通過矩陣變化實現的 3D 模型自動佈局
在數學中,矩陣是以行和列排列的數字,符號或表示式的矩形陣列,任何矩陣都可以通過相關欄位的標量乘以元素。矩陣的主要應用是表示線性變換,即 f(x)= 4 x 等線性函式的推廣。例如,旋轉的載體在三維空間是一個線性變換,這可以通過一個表示旋轉矩陣:如果v是一個列向量描述(只有一列的矩陣)的位置在空間中的點,該產品器 Rv 是列向量描述旋轉後該點的位置。兩個變換矩陣的乘積是表示兩個變換組成的矩陣。矩陣的另一個應用是線性方程組的解。如果矩陣是方形的,可以通過計算其行列式來推斷它的一些性質。例如,當且僅當其行列式不為零時,方陣具有相反的 。從矩陣的特徵值和特徵向量中可以看到線性變換的幾何結構(以及其他資訊)。
矩陣的應用可以在大多數科學領域找到。在物理學的每一個分支,包括經典力學,光學,電磁學,量子力學和量子電動力學,都被用來研究物理現象,比如剛體的運動。在計算機圖形學中,它們被用來操作三維模型並將其投影到二維螢幕上。在概率論和統計學中,隨機矩陣被用來描述概率集; 例如,它們在 PageRank 演算法中用於對 Google 搜尋中的頁面進行排名。矩陣演算概括經典分析概念,如衍生物和指數更高的尺寸。矩陣在經濟學中被用來描述經濟關係系統。
首先,這個實現真的是非常的酷,我從來不知道分子中的引力和斥力結合矩陣能做出這麼炫酷的效果,而且還是程式碼量非常少的情況下,這個例子在醫療界還有生物界應該是應用非常廣泛的,但是如果好好利用,在工業方面也一定有不小的成就。
http://www.hightopo.com/demo/pipeline/index.html
接下來我的任務就是幫助你們也能輕鬆地實現這個效果,HT 將彈力佈局的 js 檔案放到了一個獨立的檔案中,在引用這個 js 檔案需要先引入 ht.js,因為我們還做了一個 form 表單,所以也要引入 form 表單的 js 檔案, 並不是所有的 HT 封裝的的功能都需要引入一個特別的 js 檔案,需要引入額外的 js 檔案的手冊中頂部都會有介紹,這裡 forcelayout 彈力佈局的 js 和 form 表單的 js 的排放順序沒有關係:
<script src="../../guide/lib/core/ht.js"></script>
<script src="../../guide/lib/plugin/ht-forcelayout.js"></script>
<script src="../../guide/lib/plugin/ht-form.js"></script>
首先我們定義一個顏色陣列變數,儲存各個彈力球的顏色,還定義了一個隨機函式,用來生成數隨機的陣列中的顏色:
var colorList = ['#FFAFA4', '#B887C5', '#B9EA9C', '#CFD9E7', '#4590B8', '#FF9C30'],
colorLen = colorList.length;
var randomColor = function() {
var ran = Math.random() * colorLen;
return colorList[Math.floor(ran)]; // 隨機6種顏色
};
接著建立彈力球,簡單生成一個 3D 節點,通過設定這個節點的 style 樣式屬性來控制節點的顯示方式,其中將“shape3d”設定為“sphere”即可將 ht.Node 六面體變成 3D 球體模型,再設定“shape3d”屬性為前面定義的隨機顏色,s3 也是 HT 封裝的設定 3D 節點大小的函式,最後將這個節點新增進資料模型 dataModel 中:
var createNode = function(dm) { // 建立 node 節點 圓
var node = new ht.Node();
node.s({
'shape3d': 'sphere',
'shape3d.color': randomColor()
});
node.s3(40, 40, 40);
dm.add(node);
return node;
};
現在效果圖上出現的還有各個彈力球之間的連線,這個連線我們一看就覺得很不一般,也是通過構造一個一個節點,這個節點是通過 HT for Web 建模手冊 setShape3dModel函式自定義的一個 3D 模型,將其命名為‘custom’:
ht.Default.setShape3dModel( // 建立模型 根據 xy 平面的曲線,環繞一週形成 3D 模型。
'custom', ht.Default.createRingModel( [0.5, 0.5, -0.2, 0, 0.5, -0.5], [1, 3] )
);
HT 將使用者自定義的屬性和 HT 預設的屬性呼叫方法分為 node.a 和 node.s 這樣就能將兩者有效地區分開來,我們在建立管線的時候就呼叫了這種方法:
var updatePipeline = function(edge) { // 重新設定 edge 的樣式
var pipeline = edge.a('pipeline');
pipeline.s3(1, 1, 1);
pipeline.p3(0, 0, 0);
var node1 = edge.getSourceAgent(), // 獲取圖形上連線的起始節點
node2 = edge.getTargetAgent();
pipeline.s('mat', createMatrix(node1.p3(), node2.p3(), 20)); // 3d 整體圖形矩陣變化
};
我們知道,矩陣能描述任意線性變換。線性變換保留了直線和平行線,線性變換保留直線的同時,其他的幾何性質如長度、角度、面積和體積可能被變換改變了。簡單的說,線性變換可能“拉伸”座標系,但不會“彎曲”或“卷折”座標系。這個函式主要是將我們的連線線在拖動彈力球后被拖拉的連線線的進行一個“變化矩陣”的操作,變化矩陣也是 HT 封裝的 ht.Default.createMatrix 函式,能夠非常輕鬆地建立出變化矩陣:
var createMatrix = function(p1, p2, width) { // createMatrix(array, matrix) 將一組 JSON 描述的縮放、移動和旋轉等操作轉換成對應的變化矩陣
var vec = [p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2]],
dist = ht.Default.getDistance(p1, p2); // 獲取兩點之間距離,或向量長度
return ht.Default.createMatrix({
s3: [width, dist, width],
r3: [Math.PI/2 - Math.asin(vec[1]/dist), Math.atan2(vec[0], vec[2]), 0],
rotationMode: 'xyz',
t3: [(p1[0]+p2[0])/2, (p1[1]+p2[1])/2, (p1[2]+p2[2])/2]
});
};
基礎配件全部定義完畢,接著就是將“shape3d”屬性設定為自定義的 3D 模型“custom” ,並將“layoutable”屬性設定為“false”阻止圖元參與佈局,並將點之間的連線通過edge.a(‘pipeline’, node)重新重新整理,並新增進資料模型 dataModel 中:
var createEdge = function(dm, node1, node2) { // 建立‘custom’模型的 edge
var node = new ht.Node();
node.s({
'shape3d': 'custom',
'shape3d.color': '#ECE0D4',
'layoutable': false
});
dm.add(node);
var edge = new ht.Edge(node1, node2);
edge.a('pipeline', node);
edge.s('edge.color', 'rgba(0, 0, 0, 0)');
dm.add(edge);
return edge;
};
我們還可以在工業上用 HeatMap 熱圖上做文章,效果依舊很炫,具體地址 http://hightopo.com/guide/guide/plugin/forcelayout/examples/example_heatmap3d.html
這裡我們還是專注地繼續完成這個例子。
介面上的圖形全部繪製完畢,剩下的就只有 form 表單,首先將 form 表單新增進 HTML 頁面,用的是 HT 封裝的 ht.widget.FormPane 函式:
var formPane = new ht.widget.FormPane();
formPane.setWidth(230);
formPane.setHeight(125);
formPane.addToDOM();
記住,form 表單要設定寬高,不然不顯示。
form 表單新增行是通過 addRow 函式,我們重點來說一下下面的幾行,Color、Range 和 Intensity,這三個名字主要是用來控制“頭燈”的。在 HT 中直接通過 setHeadlightColor/setHeadlightRange/setHeadlightIntensity 三個函式來控制“頭燈”的顏色、範圍以及燈的強度,onValueChanged 屬性,顧名思義屬性值改變之後觸發的事件:
['Color', 'Range', 'Intensity'].forEach(function(name) {
var obj = { id: name },
func = function(oV, nV) {
g3d['setHeadlight' + name](nV); // === g3d.setHeadlightColor(nV)/g3d.setHeadlightRange(nV)/g3d.setHeadlightIntensity(nV)
};
if (name === 'Color')
obj.colorPicker = { // ht.widget.ColorPicker為顏色選擇框
instant: true,
value: g3d['getHeadlight' + name](), // === g3d.getHeadlightColor()
onValueChanged: func
};
else
obj.slider = { // 滑動條
min: 0,
max: name === 'Range' ? 20000 : 3,
step: 0.1,
value: g3d['getHeadlight' + name](),
onValueChanged: func
};
formPane.addRow([ name, obj ], [ 70, 0.1 ]);
});
slider 和 colorPicker 都是 HT 自定義的滑動條和顏色選擇器,詳情請參考 HT for Web 表單手冊。
如果還有不懂的請諮詢我,或者直接上 HT for Web 官網查閱手冊。
相關文章
- css實現高度動態變化的佈局CSS
- flutter佈局-5-Matrix4矩陣變換Flutter矩陣
- 使用 CSS columns 佈局來實現自動分組佈局CSS
- 通過自動化和現代化實現網路優化優化
- UITableViewCell使用自動佈局的“最佳實踐”UIView
- 通過Gradle自動實現Android元件化模組構建GradleAndroid元件化
- lib-flexible 實現移動端自適應佈局Flex
- 實現一個上下固定,中間自動填滿的佈局
- 矩陣的乘法運算與css的3d變換(transform)矩陣CSS3DORM
- 佈局總結-水平居中佈局的實現
- 【OC梳理】自動佈局
- 使用第三方框架 Masonry 實現自動佈局框架
- 【android】自定義佈局控制控制元件的位置可以通過繼承FrameLayout實現Android控制元件繼承
- 基於 WebGL 實現的 HTML5 3D “彈力”佈局WebHTML3D
- 基於 HTML5 WebGL 實現的 3D “彈力”佈局HTMLWeb3D
- webgl 系列 —— 變換矩陣和動畫Web矩陣動畫
- 向量化實現矩陣運算最佳化(一)矩陣
- 如何實現兩欄佈局,右側自適應?三欄佈局中間自適應呢?
- 3D旋轉矩陣的推導3D矩陣
- css佈局系列1——盒模型佈局CSS模型
- Bert結構手動矩陣運算實現(Transform)矩陣ORM
- github或gitee等dev cloud使用actions通過yml配置實現自動化部署GithubGiteedevCloud
- CSS 佈局模型CSS模型
- css佈局-實現左中右佈局的5種方式CSS
- css佈局,左右固定中間自適應實現CSS
- Transformer模型中的權重矩陣ORM模型矩陣
- CSS佈局 --- 自適應佈局CSS
- iOS自動佈局——Masonry詳解iOS
- Grid 拖拽佈局實現
- Selenium自動化實現web自動化-1Web
- 基於DotNetty實現自動釋出 - 自動檢測程式碼變化Netty
- 聖盃佈局進階版-flex佈局實現Flex
- 基向量 變換矩陣矩陣
- 通過 PXE 自動化安裝 Ubuntu ServerUbuntuServer
- CSS佈局–聖盃佈局和雙飛翼佈局以及使用Flex實現聖盃佈局CSSFlex
- 教你如何通過自媒體變現!(建議收藏)
- HTML5頁面移動端自適應佈局的實現示例程式碼HTML
- 矩陣LU分解---使用MATLAB和DEV-C++實現的程式碼過程矩陣MatlabdevC++