three.js提供的幾何體


1.簡單幾何體

    three.js提供的稍微簡單點的幾何體包括有:PlaneGeometry(平面)、CircleGeometry(圓形)、ShapeGeometry(塑性)、CubeGeometry(立方體)、CylinderGeometry(圓柱)、TorusGeometry(圓環)、TorusKnotGeometry(畫面扭結)、PolyhedronGeometry(多面體)、IcosahedronGeometry(二十面體)、OctahedronGeometry(八面體)、TetraHedronGeometry(四面體)。

    稍微復雜點的幾何體包括有:ConvexGeometry(凸面體)、LatheGeometry(掃描體)、ExtrudeGeometry(拉伸幾何體)、TubeGeometry(管狀體)ParameterGeometry(參數幾何體)、TextGeometry(文本幾何體)。

2.二維幾何體PlaneGoemetry

    PlaneGeoemtry是矩形態的平面幾何體,初始化也很簡單,需要4個參數:

new THREE.PlaneGeometry(10, 14, 4, 4)

    4個參數分別是width、height、widthSegment、heightSegment。其中widthSegment指定矩形的寬度應該划成幾段,這里是在width和height方向都划分成4段。如下所示:

image

3.同時顯示幾何體的面和網狀結構

    可通過THREE.SceneUtils.createMultiMaterialObject來為幾何體添加多個材質,從而由顯示面的顏色也顯示網狀結構。實現代碼可參考下面:

var meshMaterial = new THREE.MeshNormalMaterial();
                meshMaterial.side = THREE.DoubleSide;
                var wireFrameMat = new THREE.MeshBasicMaterial();
                wireFrameMat.wireframe = true;

                var plane = THREE.SceneUtils.createMultiMaterialObject(new THREE.PlaneGeometry(10, 14, 4, 4), [meshMaterial, wireFrameMat]);

    createMultiMaterialObject函數第一個參數是一個幾何體對象,第二個參數是材質的數組,可傳遞多個。其實最終生成的是多個物體,只不過都重疊在一起。

4.CircleGeometry

    很容易理解CircleGeoemtry用來畫平面元的。屬性包括:

    屬性/是否必填/描述
    radius/是/定義啊圓的半徑
    segments(分段)/否/定義創建圓所有面的數量,最少三個。如果沒有指定默認為8
    thetaStart(起始角)/否/定義從哪兒開始畫圓。取值從0到2*PI
    thetaLength(角度)/否/定義圓要花多大。如果沒有指定,默認為2*PI整圓。如果指定為0.5PI則為四分之一個圓

5.ShapeGeometry

    PlaneGeometry和CircleGeometry只有有限的方法來定制他們的外觀。如果想創建一個自定義的二維圖形,可以使用ShapeGeometry。ShapeGeometry沒有比的選項可以定制圖形。一般都是先創建一個Shape圖形。用Shape圖形繪圖。Shape對象提供的函數繪制函數包括:
    moveTo(x, y)/將繪圖點移動到x、y坐標處
    lineTo(x, y)/從當前位置繪制一條線到指定的x、y坐標處
    quadriCurveTo(aCPx, aCPy, x, z)(二次曲面)/定義曲面,可以使用quadraticCurveTo函數或者bezierCurveTo函數繪制曲面。
    bezierCurveTO(aCPx1, aCPy1, aCPx2, aCPy2, x, y)/畫一條曲線。該曲線的繪制是基於兩個定義曲線的坐標以及重點坐標(x,y)。起始點是當前位置。
    splineThru(pts)/該函數沿着提供的坐標集合繪制一條光華曲線。這個參數應該是THREE.Vector2的對象數組
    arc(ay, ay, aRadius, aSTartAngle, aEndAngle, aClockwise)/畫圓或者一段圓弧。圓弧起始於當前位置。ax和ay用來指定圓心與當前位置之間的偏移量。aRadius設置圓大小,而aSTartAgnle和aEndAngle定義圓弧要畫多長。布爾aCockwise決定這段圓弧是順時針還是逆時針
    absArc(ay, ay, aRadius, aSTartAngle, aEndAngle, aClockwise)/參考arc,其位置是絕對的,而不是相對於當前位置
    ellipse(aX, aY, xRadius, aStartAngle, aEndAngle, aClockwise))/參考arc。作為補充,通過ellipse函數可以分別制定x軸半徑和y軸半徑
    absEllipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise)/參考ellipse描述。起位置時絕對,而不是相對於當前位置的相對值

    Shape對象屬性holes,通過往這個屬性中國添加THEE.Shape對象,你可以在圖形中打幾個洞。Shape對象本身也有幾個輔助函數,可永安里創建幾何體。如下所示:

    makeGeometry/該函數從shape對象返回一個ShapeGeometry對象
    createPointsGeometry(divisions)/改函數將圖形轉換成一個點集。屬性divisions分段數定義返回點的數目
    createSpacedPointsGeoemtry(divisions)/該函數將圖形轉換為一個點集,但是這一次,分段數是一次性地應用到整個路徑上
如果用createPointsGeometry或者createSpacedPointsGeometry函數創建一個點集,你可用這些點創建線段
   new THREE.Line(shape.createPointsGeometry(10), new THREE.LineBasicMateial({color: 0xff3333, linewidth: 2})

6.SphereGeometry

    這個幾何體非常靈活,可以用來創建所有跟球體相關的幾何體。下表中的屬性可用來調整結果網格的外觀:

    屬性/是否必填/描述   

    radius/否/該屬性設置球體的半徑

    widthSegments/否/指定豎直方向上的分段數。默認為8,最小為2

    hieghtSegments/否/指定水平方向的分段數。默認為6,最小為2

    phiStart/否/指定從x軸的什么地方開始繪制。取值范圍從0到2*PI。默認為0

    phiLength/否/指定從phiStart開始畫多少。2*PI是整球,0.5*PI是四分之一球

    thetaStart/否/指定從y軸的什么地方開始繪制。取值范圍從0到PI。默認為0

    thetaLength/指定從theata開始畫多少。PI是征求,0.5PI只會繪制上半球

7.CylinderGeometry

    創建CylinderGeometry時,沒有必須提供的參數。直接調用new THREE.CylinderGeometry()即可創建一個圓柱。屬性列表如下:

    radiusTop/圓柱頂部尺寸,默認是20

    radiusBottom/設置圓柱底部的尺寸,默認是20

    height/屬性設置圓柱的高度,默認是100

    segmentsX/該屬性設置沿x軸分成多少段,默認是8.這個數字越大,圓柱越光滑

    segmentsY/該屬性設置沿y軸分成多少段

    openEnded/指定網格的頂部和底部是否封閉。默認為false

8.TorusGeometry

    Torus圓環是一種簡單的圖形,看上去像甜甜圈。創建TorusGeometry沒有必須提供的參數。參數列表為:

    radius/設置完整環的尺寸,默認為100

    tube/設置是管子的半徑。默認為40

    radialSegments/這個參數設置的是沿圓環長度方向分成的段數。默認是8

    tabularSegments/這個參數設置沿圓環寬度方向分成的段數。默認是6

    arc/通過該屬性值,可以孔子是否繪制一個完整的圓環。默認是 2*PI

9.ConvexGeometry

    通過ConvexGeometry可以在一組點的外面建立一個凸面。所謂凸面就是包圍這組點的最小圖形。如下面的代碼,創建了一組隨機的點,使用new THREE.ConvexGeometry(points)初始化這個包面圖形。

function generatePoints(){
                var points = [];
                for(var i = 0; i < 20; i++){
                    var randomX = -15 + 30 * Math.random();
                    var randomY = -15 + 30 * Math.random();
                    var randomZ = -15 + 30 * Math.random();

                    points.push(new THREE.Vector3(randomX, randomY, randomZ));
                }

                spGroup = new THREE.Object3D();
                var material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true});
                points.forEach(function(point){
                    var sphereGeometry = new THREE.SphereGeometry(0.2);
                    var mesh = new THREE.Mesh(sphereGeometry, material);
                    mesh.position.copy(point);
                    spGroup.add(mesh);
                });
                scene.add(spGroup);

                var hullGeometry = new THREE.ConvexGeometry(points);
                hullMesh = createMesh(hullGeometry);
                scene.add(hullMesh);
            }

10.TubeGeometry

    TubeGeometry沿着一條三維樣條曲線拉伸出一根管道。你可以通過指定頂點來定義路徑,然后TubeGeometry就可以創建這根管子。如下面的代碼:

function generatePoints(points, segments, radius, radiusSegments, closed){
                spGroup = new THREE.Object3D();
                var material = new THREE.MeshBasicMaterial({color: 0xff0000, transparent: false});
                points.forEach(function(point){
                    var spGeom = new THREE.SphereGeometry(0.2);
                    var spMesh = new THREE.Mesh(spGeom, material);
                    spMesh.position.copy(point);
                    spGroup.add(spMesh);
                });
                scene.add(spGroup);

                var tubeGeometry = new THREE.TubeGeometry(new THREE.SplineCurve3(points), segments, radius, radiusSegments, closed);
                tubeMesh = createMesh(tubeGeometry);
                scene.add(tubeMesh);
            }

    points是一組Vector3集合,但TubeGeometry不能直接使用,必須要轉換成THREE.SplineCurve3創建樣條。而且這個參數是比傳的。其他屬性如下列表:

    屬性/是否必須/描述

    path/是/該屬性用一個THREE.SplineCurve3對象指定管道應當遵循的路徑

    segments/否/管道所有的分段數。默認64.路徑越長,指定的分段數應該越多

    radius/否/管道半徑,默認為1

    radiusSegments/否/管道圓周的分段數。默認是8.分段數越多,管道看上去越圓滑

    closed/否/如果為true,管道的頭和尾會連起來。默認為false

11.textGeometry

    text幾何體的創建代碼可參考如下:

this.asGeom = function(){
                scene.remove(text1);
                scene.remove(text2);

                var option = {
                    size: controls.size,
                    height: controls.height,
                    weight: controls.weight,
                    font: controls.font,
                    bevelThickness: controls.bevelThickness,
                    bevelSize: controls.bevelSize,
                    bevelSegments: controls.bevelSegments,
                    bevelEnabled: controls.bevelEnabled,
                    curveSegments: controls.curveSegments,
                    steps: controls.steps
                }

                text1 = createMesh(new THREE.TextGeometry("Learning", option));
                text1.position.z = -100;
                text1.position.y = 100;
                scene.add(text1);

                text2 = createMesh(new THREE.TextGeometry("Three.js", option));
                scene.add(text2);
            }

    和其他幾何體創建方式一樣,只是初始化時調用new THREE.TextGeometry對象,第一個參數是傳遞的文字。第二個參數是幾何體的屬性。屬性列表如下:

    屬性/是否必須/描述

    size/否/指定文字的大小。默認100

    height/否/指定拉伸的程度。默認是50

    weight/否/指定字體的權重。可選的值是normal、bold。默認normal

    font/否/指定要使用的字體名。默認是helvetiker

    style/否/字體樣式。可選值包括normal、italic。默認是normal

    bevelThickness(斜角厚度)/否/指定斜角的深度。斜角是前后面和拉伸面之間的倒角。默認是10

    bevelSegments(斜角分段數)/斜角的分段數。默認是3

    bevelSize/否/指定斜角的高度。默認為8

    bevelEnabled/否/如果設置為true,就會有斜角。默認為false

    curveSegments(曲線分段數)/否/定義拉伸體被分成幾段。默認為1.

    steps(拉伸體段數)/否/拉伸體被分成多少段。默認為1

    extrudePath/否/指定圖形沿着什么路徑拉伸。如果沒有指定,圖形沿着z軸拉伸

    material/否/定義前后面所用材質的索引。用函數THREE.SceneUtils.createMultiMaterialObject創建網格

    extrudeMateria(拉伸材質)/否/指定斜角和拉伸體所用材質的索引。用函數THREE.SceneUtils.createMultiMaterialObject創建網格

12添加自定義字體

    Three.js提供了幾種可以在場景中使用的字體。這些字體技術是由typeface.js(http://typeface.neocracy.org)提供的字體。typeface.js是一個可以將TrueType和OpenType字體轉換為Javascript庫。轉換出來的Javascript文件可以包含在你的頁面,然后即可在Three.js中使用。

    要轉換已有的OpenType或TrueType字體,可以使用網頁http://typeface.neocracy.org/fonts.html。你可以在這個網站上上傳一個字體,然后它就會把該字體轉化成javascript。要包含這個字體。只要在html頁面頂部引用這個javascript文件即可。

13.使用二元操作組合網格

    我們可以把標准的幾何體組合在一起創建出一個新的幾何體。實現這個功能,我們可以使用Three.js擴展庫ThreeBSP。下載地址為:https://github.com/skalnik/ThreeBSP。這個擴展庫提供了三個函數:

    intersect(相交)/可以在兩個幾何體的交集上創建出新的幾何體。兩個幾何體相互交疊的地方就是新的幾何體

    union(聯合)/將兩個幾何體聯合在一起創建出新的幾何體。可以將這個函數與mergeGeometry函數想比較

    subtract(相減)/可以在第一個幾何體中減去兩個幾何體交疊的部分,從而創建出新的幾何體

    下面代碼是使用ThreeBSP的代碼,使用也比較簡單:

function redrawResult(){
            showSpinner();

            //異步執行,避免鎖定線程
            setTimeout(function(){
                scene.remove(result);
                var sphere1BSP = new ThreeBSP(sphere1);
                var sphere2BSP = new ThreeBSP(sphere2);
                var cubeBSP = new ThreeBSP(cube);

                var resultBSP;

                switch(controls.actionSphere){
                    case "subtract":
                        resultBSP = sphere1BSP.subtract(sphere2BSP);
                        break;
                    case "intersect":
                        resultBSP = sphere1BSP.intersect(sphere2BSP);
                        break;
                    case "union":
                        resultBSP = sphere1BSP.union(sphere2BSP);
                        break;
                    case "none":
                        break;
                }

                if(!resultBSP) resultBSP = sphere1BSP;
                switch(controls.actionCube){
                    case "subtract":
                            resultBSP = cubeBSP.subtract(resultBSP);
                        break;
                    case "intersect":
                            resultBSP = cubeBSP.intersect(resultBSP);
                        break;
                    case "union":
                            resultBSP = cubeBSP.union(resultBSP);
                        break;
                    case "none":
                        break;
                }

                if(controls.actionCube === "none" && controls.actionSphere === "none"){

                }else{
                    result = resultBSP.toMesh();
                    result.geometry.computeFaceNormals();
                    result.geometry.computeVertexNormals();
                    scene.add(result);
                }

                hideSpinner(spinner);
            }, 200);
        }

    要使用運算函數,需要把geometry轉換成ThreeBSP對象。代碼resultBSP = sphere1BSP.subtract(sphere2BSP)最終的結果是sphere1BSP幾何體減去和sphere2BSP重疊的部分后剩下的幾何體。

    運算完成后直接調用result.BSP.toMesh()函數即可得到網格。但還需要調用computeFaceNormals和computeVertexNromals函數,這是因為執行二元操作之后,幾何體中心店和面的法向量可能會變化。Three.js在着色器中會用到面法向量和頂點法向量。明確地重新計算面和頂點法向量,可保證新生成的對象着色光滑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM