【问题标题】:Three.js: trying to render a custom mesh (rhombic dodecahedron)?Three.js:尝试渲染自定义网格(菱形十二面体)?
【发布时间】:2015-06-01 14:43:42
【问题描述】:

我想渲染这个:

不幸的是,当我尝试创建自定义网格时,我得到了这个:

我遇到了一些旧的 THREE.js 代码来渲染这个实体,但令人失望的是,它只有一半用处,因为它依赖于已弃用的 THREE.Face4()。因此,在 StackOverflow 周围挖掘,我发现了我认为使用 2 THREE.Face3() 的解决方法。正如您在上面看到的,它不起作用。这是我的代码。

//'2 Face3' to emulate 'Face4' function, thanks to @Kevin Miller and    
  @Jonathan at github.com

function drawSquare(x1, y1, x2, y2) { 
  var square = new THREE.Geometry(); 

  //set 4 points
  square.vertices.push( new THREE.Vector3( x1,y2,0) );
  square.vertices.push( new THREE.Vector3( x1,y1,0) );
  square.vertices.push( new THREE.Vector3( x2,y1,0) );
  square.vertices.push( new THREE.Vector3( x2,y2,0) );

//push 1 triangle
  square.faces.push( new THREE.Face3( 0,1,2) );

//push another triangle
  square.faces.push( new THREE.Face3( 0,3,2) );

//return the square object with BOTH faces
  return square;
};

//rhombic dodecahedron geometry, thanks to http://www.sacred-geometry.es
//vertices
  var vertices = [ new THREE.Vector3( 2.04772293123743050, -4.09327412386437040, -5.74908146957292670),
                   new THREE.Vector3(  7.02732984841516030, 1.40331541320251810, -1.62706516545639390),
                   new THREE.Vector3( 4.22549114271519950, -1.62031854283173550,  5.78962800381778210),
                   new THREE.Vector3( 0.75411577446253997,  7.11690807989861880, -1.66761169970125600),
                   new THREE.Vector3(-0.75411577446252998, -7.11690807989862510,  1.66761169970125020),
                   new THREE.Vector3(-4.22549114271518980,  1.62031854283173260, -5.78962800381778920),
                   new THREE.Vector3( -2.0477229312374288,  4.09327412386436950,  5.74908146957292670),
                   new THREE.Vector3(-7.02732984841515230, -1.40331541320252740,  1.62706516545639970),
                   new THREE.Vector3( 6.27321407395262300, -5.71359266669610030,  0.04054653424485652),
                   new THREE.Vector3( 2.80183870569996340,  3.02363395603425690, -7.41669316927418000),
                   new THREE.Vector3( 4.97960691717773150,  5.49658953706689160,  4.12201630411653590),
                   new THREE.Vector3(-2.80183870569996340, -3.02363395603425690,  7.41669316927418000),
                   new THREE.Vector3(-4.97960691717773150, -5.49658953706689160, -4.12201630411653590),
                   new THREE.Vector3(-6.27321407395262480,  5.71359266669610210, -0.04054653424485653) ];

//faces
  var faces = [ drawSquare(vertices[8],vertices[0],vertices[9],vertices[1]).faces[0],
                drawSquare(vertices[8],vertices[0],vertices[9],vertices[1]).faces[1],
                drawSquare(vertices[8],vertices[1],vertices[10],vertices[2]).faces[0],
                drawSquare(vertices[8],vertices[1],vertices[10],vertices[2]).faces[1],
                drawSquare(vertices[8],vertices[2],vertices[11],vertices[4]).faces[0],
                drawSquare(vertices[8],vertices[2],vertices[11],vertices[4]).faces[1],
                drawSquare(vertices[8],vertices[4],vertices[12],vertices[0]).faces[0],
                drawSquare(vertices[8],vertices[4],vertices[12],vertices[0]).faces[1],
                drawSquare(vertices[12],vertices[5],vertices[9],vertices[0]).faces[0],
                drawSquare(vertices[12],vertices[5],vertices[9],vertices[0]).faces[1],
                drawSquare(vertices[13],vertices[3],vertices[9],vertices[5]).faces[0],
                drawSquare(vertices[13],vertices[3],vertices[9],vertices[5]).faces[1],
                drawSquare(vertices[10],vertices[1],vertices[9],vertices[3]).faces[0],
                drawSquare(vertices[10],vertices[1],vertices[9],vertices[3]).faces[1],
                drawSquare(vertices[10],vertices[3],vertices[13],vertices[6]).faces[0],
                drawSquare(vertices[10],vertices[3],vertices[13],vertices[6]).faces[1],
                drawSquare(vertices[11],vertices[2],vertices[10],vertices[6]).faces[0],
                drawSquare(vertices[11],vertices[2],vertices[10],vertices[6]).faces[1],
                drawSquare(vertices[11],vertices[7],vertices[12],vertices[4]).faces[0],
                drawSquare(vertices[11],vertices[7],vertices[12],vertices[4]).faces[1],
                drawSquare(vertices[12],vertices[7],vertices[13],vertices[5]).faces[0],
                drawSquare(vertices[12],vertices[7],vertices[13],vertices[5]).faces[1],
                drawSquare(vertices[13],vertices[7],vertices[11],vertices[6]).faces[0],
                drawSquare(vertices[13],vertices[7],vertices[11],vertices[6]).faces[1] ];            

//create the mesh 
  var rhombic_dodecahedron_geo = new THREE.Geometry();
    for(c=0; c<vertices.length; c++) { rhombic_dodecahedron_geo.vertices.push( vertices[c] ) };
    for(d=0; d<faces.length; d++) { rhombic_dodecahedron_geo.faces.push( faces[d] ) };

  var rhombic_dodecahedron_mat   = new THREE.MeshBasicMaterial( {color: 0x4B32AF, wireframe: false} );
      rhombic_dodecahedron       = new THREE.Mesh(rhombic_dodecahedron_geo, rhombic_dodecahedron_mat);

      scene.add(rhombic_dodecahedron);

谁能发现任何错误?提前感谢您帮助解决这个令人沮丧的问题。

【问题讨论】:

    标签: javascript three.js mesh


    【解决方案1】:

    这是创建自定义多面体网格要遵循的模式:

    // geometry
    var geometry = new THREE.Geometry();
    
    // vertices
    geometry.vertices = [
        new THREE.Vector3( 2.04772293123743050, -4.09327412386437040, -5.74908146957292670),
        new THREE.Vector3(  7.02732984841516030, 1.40331541320251810, -1.62706516545639390),
        new THREE.Vector3( 4.22549114271519950, -1.62031854283173550,  5.78962800381778210),
        new THREE.Vector3( 0.75411577446253997,  7.11690807989861880, -1.66761169970125600),
        new THREE.Vector3(-0.75411577446252998, -7.11690807989862510,  1.66761169970125020),
        new THREE.Vector3(-4.22549114271518980,  1.62031854283173260, -5.78962800381778920),
        new THREE.Vector3( -2.0477229312374288,  4.09327412386436950,  5.74908146957292670),
        new THREE.Vector3(-7.02732984841515230, -1.40331541320252740,  1.62706516545639970),
        new THREE.Vector3( 6.27321407395262300, -5.71359266669610030,  0.04054653424485652),
        new THREE.Vector3( 2.80183870569996340,  3.02363395603425690, -7.41669316927418000),
        new THREE.Vector3( 4.97960691717773150,  5.49658953706689160,  4.12201630411653590),
        new THREE.Vector3(-2.80183870569996340, -3.02363395603425690,  7.41669316927418000),
        new THREE.Vector3(-4.97960691717773150, -5.49658953706689160, -4.12201630411653590),
        new THREE.Vector3(-6.27321407395262480,  5.71359266669610210, -0.04054653424485653)
    ];
    
    // faces - in counterclockwise winding order - important!
    geometry.faces.push(
        new THREE.Face3( 8, 0, 9 ),  new THREE.Face3( 9, 1, 8 ),
        new THREE.Face3( 8, 1, 10 ), new THREE.Face3( 10, 2, 8 ),
        new THREE.Face3( 8, 2, 11 ), new THREE.Face3( 11, 4, 8 ),
        new THREE.Face3( 8, 4, 12 ), new THREE.Face3( 12, 0, 8 ),
        new THREE.Face3( 12, 5, 9 ), new THREE.Face3( 9, 0, 12 ),
        new THREE.Face3( 13, 3, 9 ), new THREE.Face3( 9, 5, 13 ),
        new THREE.Face3( 10, 1, 9 ), new THREE.Face3( 9, 3, 10 ),
        new THREE.Face3( 10, 3, 13 ), new THREE.Face3( 13, 6, 10 ),
        new THREE.Face3( 11, 2, 10 ), new THREE.Face3( 10, 6, 11 ),
        new THREE.Face3( 11, 7, 12 ), new THREE.Face3( 12, 4, 11 ),
        new THREE.Face3( 12, 7, 13 ), new THREE.Face3( 13, 5, 12 ),
        new THREE.Face3( 13, 7, 11 ), new THREE.Face3( 11, 6, 13 )
    );
    
    // normals ( since they are not specified directly )
    geometry.computeFaceNormals();
    geometry.computeVertexNormals();
    
    // material - polyhedron requires flat shading
    var material = new THREE.MeshLambertMaterial( { color: 0x479100, shading: THREE.FlatShading } );
    
    // mesh
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
    

    请务必在场景中添加灯光,因为 Lambert 材质需要它。

    three.js r.71

    【讨论】:

    • @WestLangley 的另一个出色而彻底的回答。非常感谢!
    • 一个问题:我注意到您将面孔按 x 坐标升序排列。这是否确保逆时针缠绕顺序,还是我错过了其他东西?提前致谢。
    • 没有。当面面向您时,每个面的顶点必须具有逆时针缠绕顺序。
    【解决方案2】:

    扩展 WestLangley 的答案,这是在 threejs 中表示菱形十二面体的简化方法。

    菱形十二面体可以通过在正方形的每个面上放置一个正方形金字塔来构造,其中正方形的边长为l,而正方形金字塔的高度为l/2(来自here)。

    以下代码描述了基于正方形的菱形十二面体

    • 原点 (0, 0, 0)
    • 旋转 (0, 0, 0)
    • 顶面:(A、B、C、D)
    • 底面:(E、F、G、H)
    • 边长:2

    您会注意到我的十二面体的面数是 WestLangley 的一半。这是因为合成的十二面体的每个面实际上是上述方形金字塔的两个相邻面的联合。 [编辑:我使用 Face4 生成菱形,但我刚刚发现 Face4 已被弃用,因此我在下面创建的每个菱形都需要替换为两个三角形。如何做到这一点应该很明显。]

    (jsfiddle)

    var geometry = new THREE.Geometry();
    
    // vertices
    geometry.vertices = [
        new THREE.Vector3( -1,  1, -1 ), // A       (0)
        new THREE.Vector3(  1,  1, -1 ), // B       (1)
        new THREE.Vector3(  1,  1,  1 ), // C       (2)
        new THREE.Vector3( -1,  1,  1 ), // D       (3)
        new THREE.Vector3( -1, -1, -1 ), // E       (4)
        new THREE.Vector3(  1, -1, -1 ), // F       (5)
        new THREE.Vector3(  1, -1,  1 ), // G       (6)
        new THREE.Vector3( -1, -1,  1 ), // H       (7)
        new THREE.Vector3( -2,  0,  0 ), // left    (8)
        new THREE.Vector3(  2,  0,  0 ), // right   (9)
        new THREE.Vector3(  0,  2,  0 ), // top     (10)
        new THREE.Vector3(  0, -2,  0 ), // bottom  (11)
        new THREE.Vector3(  0,  0,  2 ), // front   (12)
        new THREE.Vector3(  0,  0, -2 )  // back    (13)
    ];
    
    
    // faces - in counterclockwise winding order
    geometry.faces.push(
      new THREE.Face4( 12, 2, 10, 3 ),  // (front, C, top, D)
      new THREE.Face4( 12, 6,  9, 2 ),  // (front, G, right, C)
      new THREE.Face4( 12, 7, 11, 6 ),  // (front, H, bottom, G)
      new THREE.Face4( 12, 3,  8, 7 ),  // (front, D, left, H)
      new THREE.Face4( 13, 5, 11, 4 ),  // (back, F, bottom, E)
      new THREE.Face4( 13, 4,  8, 0 ),  // (back, E, left, A)
      new THREE.Face4( 13, 0, 10, 1 ),  // (back, A, top, B)
      new THREE.Face4( 13, 1,  9, 5 ),  // (back, B, right, F)
      new THREE.Face4(  8, 3, 10, 0 ),  // (left, D, top, A)
      new THREE.Face4(  8, 4, 11, 7 ),  // (left, E, bottom, H)
      new THREE.Face4(  9, 1, 10, 2 ),  // (right, B, top, C)
      new THREE.Face4(  9, 6, 11, 5 )   // (right, G, bottom, F)
    
    );
    
    // normals ( since they are not specified directly )
    geometry.computeFaceNormals();
    geometry.computeVertexNormals();
    
    // material - polyhedron requires flat shading
    var material = new THREE.MeshLambertMaterial( { color: 0x479100, shading: THREE.FlatShading } );
    
    // mesh
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-20
      • 1970-01-01
      • 2014-01-14
      • 2016-12-10
      • 1970-01-01
      • 2013-07-24
      • 2017-06-09
      • 1970-01-01
      相关资源
      最近更新 更多