今天說說three.js的幾何體,常見的幾何體今天就不說了,今天說一說如何畫直線,圓弧線,以及高級幾何體。數組
畫直線咱們使用THREE.Geometry()對象。框架
//給空白幾何體添加點信息,geometry會把這些點自動組合成線。 var material = new THREE.LineBasicMaterial({color: 0x00ff00}); var geometry = new THREE.Geometry(); geometry.vertices.push(new THREE.Vector3(0,0,0)); geometry.vertices.push(new THREE.Vector3(10,10,10)); geometry.vertices.push(new THREE.Vector3(0,20,0)); var line = new THREE.Line(geometry, material);
這樣就在空間畫出了一條折線。dom
畫圓弧線咱們藉助THREE.ArcCurve()對象。這個對象有點相似於d3.js中的佈局(layout),它的本質就是根據參數生成一系列點座標,他有一些方法.getPoints()從圓弧線均勻得到圓弧上面點的座標。下面是THREE.ArcCurve()的部分源碼。oop
THREE.ArcCurve = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { THREE.EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); };
咱們能夠知道有6個參數,而且繼承自THREE.EllipseCurve()。加下來咱們來畫圓弧。佈局
var arc = new THREE.ArcCurve(0, 0, 30, 0, Math.PI * 2, true); var points = arc.getPoints(1000); var ring = new THREE.Geometry(); points.forEach(v => ring.vertices.push(new THREE.Vector3(v.x,0,v.y))); var mat = new THREE.LineBasicMaterial({color: 0x999900}); var line = new THREE.LineLoop(ring, mat);
注意points都是XY平面上面的點。最後使用THREE.LineLoop來繪製圓弧線。優化
什麼是凸包?簡單地說凸包就是,在空間中每三個不在一條直線的點均可以組成一個平面,若是空間中有一組點,那麼會組成不少平面,若是平面不透明,咱們只能看到最外層的若干個面,這個面組成的幾個體就是凸包。this
like this !(這個只是加了岩石紋理)spa
凸包使用起來很是簡單code
let asteroidMate = new THREE.MeshBasicMaterial(); let points = []; let rad = Math.pow(Math.random(), 3) * ASTERIODRADIUS; for(var j=0; j<30; j++) { points.push(new THREE.Vector3(Math.random() * 10, Math.random() * 10, Math.random() * 10)) } var asteroidGeom = new THREE.ConvexGeometry(points); var asterMesh = new THREE.Mesh(asteroidGeom, asteroidMate);
這就是30個點組成的隨機凸包。你們能夠試試用它來自定義圖形或者製做隨機圖形。orm
旋轉體就是將由一組點組成的線繞固定軸旋轉造成的幾何體,LatheGeometry有4個參數,第一個是points點數組,第二個是分段數,第三個是旋轉開始角度,第四個是旋轉角度。
ar points = []; for(var i=-12; i<=10; i = i + 0.5) { if(i < 0) { console.log(Math.sqrt(36 - Math.pow(i + 6, 2)) * 1.2, i) points.push(new THREE.Vector3(Math.sqrt(36 - Math.pow(i + 6, 2)) * 1.2, i)) } else if(i < 8 && i >= 0) { console.log(Math.sqrt(16 - Math.pow(i - 4, 2)) * 1.2, i) points.push(new THREE.Vector3(Math.sqrt(16 - Math.pow(i - 4, 2)) * 1.2, i)) } else { console.log(Math.sqrt(1 - Math.pow(i - 9, 2)) * 1.2, i) points.push(new THREE.Vector3(Math.sqrt(1 - Math.pow(i - 9, 2)) * 1.2, i)) } } var latheGeo = new THREE.LatheGeometry(points, 30, 0, Math.PI * 2); latheMesh = createMesh(latheGeo);;
拉伸幾何體就是將一個幾何體沿着Z軸拉伸造成的幾何體。它的參數比較多可是不難理解。
var material = new THREE.MeshNormalMaterial(); var shapeGeomery = new THREE.Shape(); shape.moveTo(-10, -10); shape.lineTo(10, -10); shape.lineTo(10, 10); shape.lineTo(-10,10); shape.lineTo(-10, -10); var geometry = new THREE.ExtrudeGeometry(shapeGeomery, { amount: 2, //拉伸的深度 bevelThickness: 2, //斜角的深度 bevelSize: 3, //斜角的高度 bevelSegments: 30, //斜角分段數 bevelEnabled: true, //開啓斜角 curveSegments: 12, //拉伸的段數 steps: 1 //沿深度方向的段數 }) var shape = new THREE.Mesh(geometry, material);
這裏注意幾點,
1.ExtrudeGeometry()的第一個參數是一個shape對象,
2.區分一下這三個分段數,bevelSegments是斜角的分段,它影響斜角的光滑程度,curveSegments是拉伸曲線的段數,steps是沿深度方向的段數。
這個方法很簡單,就是驗證曲線拉伸成一根管,簡單的東西直接上代碼
var points = []; for (var i = 0; i < controls.numberOfPoints; i++) { var randomX = -20 + Math.round(Math.random() * 50); var randomY = -15 + Math.round(Math.random() * 40); var randomZ = -20 + Math.round(Math.random() * 40); points.push(new THREE.Vector3(randomX, randomY, randomZ)); } var tubeGeometry = new THREE.TubeGeometry(new THREE.SplineCurve3(points), 64, 3, 16, false); var meshMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00, transparent: true, opacity: 0.2}); var tubeMesh = new THREE.Mesh(tubeGeometry, meshMaterial)
這裏只需注意TubeGeometry()的第一個參數是一個SplineCurve3對象,須要將三維點數組用SplineCurve3處理成三維曲線。
這個東西相似於高數中的參數方程,經過三階等式來建立空間曲面,使用ParametricGeometry()的時候,我特地使用了v69版本和v104兩個版本,使用方法是不一樣的。下面咱們從代碼中尋找區別。
// v69 var oldVersion = function (u, v) { var x = u * 50 - 25; var z = v * 50 - 25; var y = Math.sin(u * 50 - 25) + Math.sin(v * 50 - 25) + Math.pow((Math.pow((u - 0.5), 2) + Math.pow((v - 0.5), 2)) * 10, 2) - 10; return new THREE.Vector3(x, y, z); }; var geometry = new THREE.ParametricGeometry(oldVersion, 120, 120)
var newVersion = function (u, v, target) { var x = u * 50 - 25; var z = v * 50 - 25; var y = Math.sin(u * 50 - 25) + Math.sin(v * 50 - 25) + Math.pow((Math.pow((u - 0.5), 2) + Math.pow((v - 0.5), 2)) * 10, 2) - 10; target.set(x,y,z); }; var geometry = new THREE.ParametricGeometry(newVersion, 120, 120)
能夠看出方法中傳遞了第三個參數,這裏使用set方法作了優化,(因此說每當出現新的js標準後,都出新生一些框架或者出現新版本)。相信喜歡數學的小夥伴都會很是喜歡這個幾何體。下面隨便展現一個demo
### 8. 組合網格
未完待續。。。(這將是一個很是有意思的幾何體)
### 9. Geometry()實現自定義面
未完待續。。。(一樣能夠很發散)
更多demo請移步至原文
轉載請註明原文地址 http://www.bettersmile.cn 郭志強的博客