【问题标题】:3D three.js Create the ground surface of a 3D building3D three.js 创建 3D 建筑物的地表
【发布时间】:2021-11-30 03:03:54
【问题描述】:

继我上周的帖子three.js How to programatically produce a plane from dataset 之后,我回到社区来解决 3D 建筑物在地面上占据的表面的定义问题。 这篇文章中 cmets 中提出的解决方案适用于这座建筑,但并不通用。 为了使其具有通用性,我选择了以下方法:建造墙时,我在另一个组中创建它们的克隆(有关墙的创建,请参阅上一篇文章)

        // prepare the clones

        var clones = new THREE.Group();         
        scene.add(clones);
        var num=0;

        // drawing the real walls

        var wallGeometry = new THREE.PlaneGeometry(size,(hstair*batims[i][1]));
        val = 0xFFFFFF;
        opa = 0.5;
        if(deltaX > deltaY){val = 0x000000; opa = 0.05;} // shaded wall
        var wallMaterial = new THREE.MeshBasicMaterial({color:val,transparent:true, opacity:opa, side:THREE.DoubleSide});
        var walls = new THREE.Mesh(wallGeometry, wallMaterial);
        walls.position.set((startleft+endleft)/2,(hstair*batims[i][1])/2,(startop+endtop)/2);
        walls.rotation.y = -rads;
        scene.add(walls);

        // add the pseudo-walls to scene
                    
        var cloneGeometry=new THREE.PlaneGeometry(long,3);
        var cloneMaterial=new THREE.MeshBasicMaterial({color:0xff0000,transparent:true,opacity:0.5,side:THREE.DoubleSide});
        var clone=new THREE.Mesh(pseudomursGeometry,pseudomursMaterial);
            clone.position.set((startleft+endleft)/2,3,(startop+endtop)/2);
            clone.rotation.y=-rads;
            clones.add(clone);
            num++;

现在的想法是旋转这个伪建筑,使最长的墙是垂直的,这样我就可以确定它的boundingBox占用的确切建筑面积:

        var angle=turn=0;
        for(i=0; i<dists.length; i++) { // dists is the array of wall lengths
            if(dists[i]==longs[0]){     // longs is the reordered lengths array
             angle=angles[i][1];        // angle of the longest wall
            }
        }

        // we can now rotate the whole group to put the longest wall vertical

        if(angle>0){
            turn = angle*-1+(Math.PI/2);
        }
        else {
            turn = angle+(Math.PI/2);
        }
        clones.rotation.y=turn;

只要建筑物具有直角,无论其形状如何:三角形、矩形、斜角、直角多边形,它都能完美运行

      var boundingBox = new THREE.Box3().setFromObject(clones);
      var thisarea = boundingBox.getSize();

      // area size gives the expected result
      console.log('AREA SIZE = '+thisarea.x+' '+thisarea.y+' '+thisarea.z);

...但在没有更多直角时不会,例如梯形

原因是我们旋转了组,而不是克隆的墙。我可以通过

访问和旋转每面墙
     for(n=0;n<num;n++){
        thisangle = clones.children[n].rotation.y;
        clones.children[n].rotation.y = turn-thisangle;
     }

但其他伪墙的结果是错误的:

所以问题是:如何转动每个红色的伪墙,以使最长的一个是垂直的,而其他的则相对于它保持正确的位置?这样,任何形状的建筑物都可以通过其内部设备进行 3D 再现。关于如何实现这个结果的任何想法?

【问题讨论】:

    标签: three.js 3d


    【解决方案1】:

    一个奇怪而丑陋但运行良好的解决方案:

         // 1. determines which is the longest side
    
        for(i=0; i<dists.length; i++) {
          if(dists[i]==longs[0]){
            longest=i;
            break;  // avoid 2 values if rectangle
          }
        }
    
        // 2. the group is rotated until the longest side has an angle in degrees
        //    close to 0 or 180
        
        var letsturn = setInterval(function() {
            clones.rotation.y += 0.01;
            var group_rotation = THREE.Math.radToDeg(clones.rotation.y); // degrees
            var stop = Math.round(angles[longest][0] - group_rotation); 
    
            // 3. stop when longest wall is vertical
    
            if( (stop>=179 && stop<=181) || (stop>=-1 && stop<=1) ) { 
                clearInterval(letsturn);
                createPlane() //  we can now use boundingBox in reliability
            }
        }, 1);
    

    等等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 2019-11-13
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 2015-09-15
      • 2017-02-24
      相关资源
      最近更新 更多