【问题标题】:ThreeJS - THREE.BufferGeometry.computeBoundingSphere() Gives Error: NaN Position ValuesThreeJS - THREE.BufferGeometry.computeBoundingSphere() 给出错误:NaN 位置值
【发布时间】:2021-08-29 12:06:02
【问题描述】:

我正在使用 Threejs 创建一个简单的 THREE.PlaneBufferGeometry。该表面是地球的一个地质表面。

这个表面有由 NaN 表示的局部间隙或“洞”。我读过另一篇类似但较旧的帖子,其中建议用“未定义”而不是 NaN 填充位置 Z 组件。我试过了,但得到了这个错误:

THREE.BufferGeometry.computeBoundingSphere():计算半径为 NaN。 “位置”属性可能具有 NaN 值。 PlaneBufferGeometry {uuid: "8D8EFFBF-7F10-4ED5-956D-5AE1EAD4DD41", name: "", type: "PlaneBufferGeometry", index: Uint16BufferAttribute, attributes: Object, ...}

这是构建表面的 TypeScript 函数:

AddSurfaces(result) {
    let surfaces: Surface[] = result;

    if (this.surfaceGroup == null) {
      this.surfaceGroup = new THREE.Group();
      this.globalGroup.add(this.surfaceGroup);
    }
   

    surfaces.forEach(surface => {
      var material = new THREE.MeshPhongMaterial({ color: 'blue', side: THREE.DoubleSide });
      let mesh: Mesh2D = surface.arealMesh;
      let values: number[][] = surface.values;

      let geometry: PlaneBufferGeometry = new THREE.PlaneBufferGeometry(mesh.width, mesh.height, mesh.nx - 1, mesh.ny - 1);
      var positions = geometry.getAttribute('position');


      let node: number = 0;

      // Surfaces in Three JS are ordered from top left corner x going fastest left to right
      // and then Y ('j') going from top to bottom.  This is backwards in Y from how we do the 
      // modelling in the backend.
      for (let j = mesh.ny - 1; j >= 0; j--) {
        for (let i = 0; i < mesh.nx; i++) {
          let value: number =  values[i][j];

          if(!isNaN(values[i][j])) {
            positions.setZ(node, -values[i][j]);
          }
          else {
            positions.setZ(node, undefined);   /// This does not work?  Any ideas?
          }
          node++;
        }
      }
      geometry.computeVertexNormals();

      var plane = new THREE.Mesh(geometry, material);
      plane.receiveShadow = true;
      plane.castShadow = true;


      let xOrigin: number = mesh.xOrigin;
      let yOrigin: number = mesh.yOrigin;

      let cx: number = xOrigin + (mesh.width / 2.0);
      let cy: number = yOrigin + (mesh.height / 2.0);

      // translate point to origin
      let tempX: number = xOrigin - cx;
      let tempY: number = yOrigin - cy;

      let azi: number = mesh.azimuth;
      let aziRad = azi * Math.PI / 180.0;

      // now apply rotation
      let rotatedX: number = tempX * Math.cos(aziRad) - tempY * Math.sin(aziRad);
      let rotatedY: number = tempX * Math.sin(aziRad) + tempY * Math.cos(aziRad);

      cx += (tempX - rotatedX);
      cy += (tempY - rotatedY);


      plane.position.set(cx, cy, 0.0);
      plane.rotateZ(aziRad);
      this.surfaceGroup.add(plane);
    });
    this.UpdateCamera();
    this.animate();
  }

谢谢!

【问题讨论】:

    标签: three.js


    【解决方案1】:

    我读过另一篇类似但较旧的帖子,其中建议用“未定义”而不是 NaN 填充位置 Z 组件。

    使用undefined 会像使用NaN 一样失败。 BufferGeometry.computeBoundingSphere() 根据Vector3.distanceToSquared() 计算半径。如果使用不包含有效数值数据的向量调用此方法,将返回NaN

    因此,您无法使用NaNundefined 位置数据来表示几何中的间隙。更好的方法是生成一个实际代表地质表面几何形状的几何形状。使用 ShapeBufferGeometry 可能是更好的选择,因为形状确实支持孔的概念。

    three.js r117

    【讨论】:

    • 如果某些几何图形具有重复值,在计算边界球时会出现这个问题吗?我生成了非常大的 BufferGeometries(uint8array 位置属性),它们导致了这个问题,但没有一个值是 NaN(实际上无符号类型不能保存 NaN 值)
    【解决方案2】:
    THREE.PlaneBufferGeometry:: parameters: {
            width: number;
            height: number;
            widthSegments: number;
            heightSegments: number;
        };  
    

    widthSegments 或 heightSegments 应大于 1 ,如果 widthSegments

    【讨论】:

    猜你喜欢
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多