在工做中經過Three.js開發項目的時候,一些特定的狀況下你可能須要計算一個三維模型的表面積或者體積,好比在3D打印的Web項目中,你須要計算一個三維模型的體積,而後經過體積計算打印一個三維模型所須要的3D打印材料費;好比開發的一個程序中,須要自動計算一個地面、牆面或某個零件的表面須要多少塗料,確定須要先計算它的外表面面積是多少。html
我的技術博客算法
若是是一個立方體、球體等規則幾何體,計算它們的面積,能夠直接代入公式,實際應用中,不必定就是規則幾何體,下面的任務是探討一個通用的算法,能夠計算任意形狀的幾何體,任意自由形狀的曲面表面積。函數
一個三維模型,可能包含多個網格模型Mesh
,若是一個三維模型有多個網格模型,你能夠分別計算每個網格模型的表面積,而後求和便可。這裏先考慮如何計算一個網格模型Mesh
的表面積,每一個網格模型的幾何體本質上都是多個三角形組成,計算一個網格模型的外表面積,只須要計算該網格模型幾何體全部三角形面積就能夠,若是想計算全部三角形的面積,確定要先計算一個三角形的面積。學習
已知三角形的三個頂點p1, p2, p3的座標值,利用三個頂點的座標計算三角形的面積,每一個頂點的座標經過一個三維向量對象Vector3
表示,具體代碼見下方。code
下面的計算主要是向量的計算,若是你對Three.js向量相關內容不瞭解,能夠查看官方文檔Vector3
接口的介紹,更多向量Vector3
相關的內容能夠參考Three.js進階視頻教程數學部分。視頻
//三角形面積計算 function AreaOfTriangle(p1, p2, p3){ var v1 = new THREE.Vector3(); var v2 = new THREE.Vector3(); // 經過兩個頂點座標計算其中兩條邊構成的向量 v1 = p1.clone().sub(p2); v2 = p1.clone().sub(p3); var v3 = new THREE.Vector3(); // 三角形面積計算 v3.crossVectors(v1,v2); var s = v3.length()/2; return s }
上面代碼封裝了一個三角形面積計算函數AreaOfTriangle()
,只要以三維向量Vector3
形式輸入三角形三個頂點座標就能夠返回一個三角形面積值。通常來講加載外部ply、stl、obj、fbx等格式三維模型,模型的幾何體都是BufferGeometry
,能夠經過BufferGeometry
的頂點索引.index
屬性和attributes.position
屬性得到三角形頂點的位置座標。htm
這裏不加載外部模型,先以Three.js自帶的Geometry
類型API爲例建立一個幾何體,而後計算它的表面,也就是計算一個球體或立方體的表面積來驗證上面函數AreaOfTriangle()
是否正確,你能夠經過公式先計算一個立方體或球體的表面積,而後再和經過調用AreaOfTriangle()
函數計算的結果相比較,來驗證AreaOfTriangle()
函數的算法是否可行。對象
// var geometry = new THREE.SphereGeometry(10, 50, 50); var geometry = new THREE.BoxGeometry(10, 10, 10); // 聲明一個變量表示幾何體的表面積 var area = 0.0; // 遍歷一個幾何體的所有三角形geometry.faces,全部三角形面積累積就是幾何體的表面積 // 對於不規則曲面,細分程度越高,面積計算精度越高 for (var i = 0; i < geometry.faces.length; i++) { //三角形的對應頂點索引 var a = geometry.faces[i].a; var b = geometry.faces[i].b; var c = geometry.faces[i].c; // 得到三角形對三個頂點的座標 var p1 = geometry.vertices[a]; var p2 = geometry.vertices[b]; var p3 = geometry.vertices[c]; // 調用三角形面積計算函數AreaOfTriangle area += AreaOfTriangle(p1, p2, p3); //三角形Face3面積累計計算 } // 查看面積計算結果 document.write("面積:" + area)
幾何體的每個三角形能夠和頂點座標構成一個四面體,計算一個幾何體的體積,能夠計算全部全部三角形和座標原點構成的四面體體積,而後求和。教程
三角形三個頂點和座標系原點構成一個四面體,已知三角形的三個頂點座標p一、 p2和p3,計算該四面體的體積。索引
計算的結果多是正多是負,幾何體全部的四面體累積後能夠計算出正確的結果。
// 四面體體積計算公式 function vFun(p1, p2, p3) { //藉助threejs的Vector3的叉乘、點乘方法進行計算 return p1.clone().cross(p2).dot(p3) / 6; //p1叉乘p2點乘p3除以6 }
下面一個立方體BoxGeometry
爲例驗證vFun
函數封裝的算法是否正確,實際應用的時候,若是是BufferGeometry
類型幾何體,只須要改變頂點的座標獲取方式就能夠,具體查看Three.js官方文檔,或者學習Three.js視頻教程的第二章。
var box = new THREE.BoxGeometry(10, 10, 10); box.translate(200, 200, 1000); //平移以後並不影響結果 // 聲明一個變量表示幾何體的體積 var V = 0.0; // 幾何體三角形索引 for (var i = 0; i < box.faces.length; i++) { // 幾何體三角形索引 var index0 = box.faces[i].a; var index1 = box.faces[i].b; var index2 = box.faces[i].c; // 經過索引訪問三角形頂點座標值 var p0 = box.vertices[index0]; var p1 = box.vertices[index1]; var p2 = box.vertices[index2]; //使用下面的函數,並不會改變p0, p1, p2引用指向的geo頂點座標值 //三角形與座標原點構成的四面體體積累計計算 V += vFun(p0, p1, p2); } //查看體積計算結果 document.write("體積:" + V); console.log("體積", V);