1. 程式人生 > 實用技巧 >Three.js模型幾何體面積、體積計算

Three.js模型幾何體面積、體積計算

在工作中通過Three.js開發專案的時候,一些特定的情況下你可能需要計算一個三維模型的表面積或者體積,比如在3D列印的Web專案中,你需要計算一個三維模型的體積,然後通過體積計算列印一個三維模型所需要的3D列印材料費;比如開發的一個程式中,需要自動計算一個地面、牆面或某個零件的表面需要多少塗料,肯定需要先計算它的外表面面積是多少。

思路——模型幾何體表面積計算

如果是一個立方體、球體等規則幾何體,計算它們的面積,可以直接代入公式,實際應用中,不一定就是規則幾何體,下面的任務是探討一個通用的演算法,可以計算任意形狀的幾何體,任意自由形狀的曲面表面積。

一個三維模型,可能包含多個網格模型Mesh,如果一個三維模型有多個網格模型,你可以分別計算每一個網格模型的表面積,然後求和即可。這裡先考慮如何計算一個網格模型Mesh的表面積,每個網格模型的幾何體本質上都是多個三角形組成,計算一個網格模型的外表面積,只需要計算該網格模型幾何體所有三角形面積就可以,如果想計算所有三角形的面積,肯定要先計算一個三角形的面積。

一個三角形面積

已知三角形的三個頂點p1, p2, p3的座標值,利用三個頂點的座標計算三角形的面積,每個頂點的座標通過一個三維向量物件Vector3表示,具體程式碼見下方。

下面的計算主要是向量的計算,如果你對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屬性獲得三角形頂點的位置座標。

這裡不載入外部模型,先以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)

計算幾何體體積

幾何體的每一個三角形可以和頂點座標構成一個四面體,計算一個幾何體的體積,可以計算所有所有三角形和座標原點構成的四面體體積,然後求和。

四面體體積

三角形三個頂點和座標系原點構成一個四面體,已知三角形的三個頂點座標p1、 p2和p3,計算該四面體的體積。

計算的結果可能是正可能是負,幾何體所有的四面體累積後可以計算出正確的結果。

// 四面體體積計算公式
function vFun(p1, p2, p3) {
  //藉助threejs的Vector3的叉乘、點乘方法進行計算
  return p1.clone().cross(p2).dot(p3) / 6; //p1叉乘p2點乘p3除以6
}

廣州品牌設計公司https://www.houdianzi.com PPT模板下載大全https://redbox.wode007.com

幾何體體積計算

下面一個立方體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);