如何用固定大小的立方体填充相机的视锥?

时间:2019-12-16 16:02:21

标签: math three.js 3d geometry frustum

我相信这将是梯形(相机的视锥)的packing problem。我想用固定大小的立方体或长方体填充整个相机的视锥。每次移动相机时,我都需要一组适合于相机视锥中的立方体。 重要,这些多维数据集在世界空间中是轴向对齐的,因为否则将会有很多重叠,因此在我的用例中必须避免这种情况。

我最初的想法是创建一个从起始点p=(0,0,0)开始循环的大量(大于世界大小)立方体,将p设为立方体的中心,如果尺寸为2,则放置{ {1}}作为下一个多维数据集的中心点,p2=(2,0,0)作为第三个多维数据集的中心点,依此类推... 问题在于,我会在场景中添加比实际所需数量更多的多维数据集,并且每次移动相机时,我都必须遍历所有多维数据集以检查它们是否相交或包含在相机的视锥中。 ,我相信这种方法可能会非常昂贵。

我该怎么做,有没有更聪明的方法?

另一方面,如果可以使用尺寸可变的3D四边形完成包装问题,是否会更容易解决问题?以及如何做到?

编辑:在某些情况下,我很难理解相机空间与相机世界。我尝试了您的方法,但没有考虑层,而是“人为地”创建了自己的层,而不是使用逆视图矩阵变换了长方体,而是获得了长方体的最大/最小点,以获得世界空间中的边界框(我相信这是真的)。

p3=(0,2,0)

我想知道我的代码是否等同于您的代码。事实是,当从摄像机创建图层,然后将其转换为世界空间时,当摄像机未与世界坐标轴对齐时,它们中的大多数是重叠的,这不好,因为我会非常查询数据库效率低下。下图显示了两个长方体重叠的黄色部分。

enter image description here

因此,我正在尝试一种不同的方法,即在世界空间中获得我的视锥的初始边界框,然后开始将较大的长方体分成8个较小的长方体,直到达到一定数量的“迷你立方体”为止。达到深度。如果长方体内部有一个长方体,我们将其视为一个良好的长方体并停止分裂。同样,如果长方体位于平截头体之外,我们将其丢弃。下一张图片试图显示出来。

enter image description here

这就是这种方法的代码。

this.createCuboids = (farCamera, xDist, yDist, nearPoints) => {
  //xDist is the difference of max.x and min.x
  //yDist is the difference of max.y and min.y
  //nearPoints are 4 points that represent the near plane
  const cuboidsCount = 5; //number of layers
  const cuboidThickness = farCamera/cuboidsCount; //depth for each layer

  let cuboidList = [];

  for (let i=1; i < cuboidsCount+1; i++) {
      const cuboid = [
          new THREE.Vector3(nearPoints[0].x, nearPoints[0].y, nearPoints[0].z),  // nearTopLeft
          new THREE.Vector3(nearPoints[1].x, nearPoints[1].y, nearPoints[1].z),  // nearBottomRight
          new THREE.Vector3(nearPoints[2].x, nearPoints[2].y, nearPoints[2].z),  // nearTopRight
          new THREE.Vector3(nearPoints[3].x, nearPoints[3].y, nearPoints[3].z),  // nearBottomLeft
          new THREE.Vector3(nearPoints[0].x+xDist*i, nearPoints[0].y+yDist*i, nearPoints[0].z+cuboidThickness*i), // farTopLeft
          new THREE.Vector3(nearPoints[1].x+xDist*i, nearPoints[1].y+yDist*i, nearPoints[1].z+cuboidThickness*i), // farBottomRight
          new THREE.Vector3(nearPoints[2].x+xDist*i, nearPoints[2].y+yDist*i, nearPoints[2].z+cuboidThickness*i), // farTopRight
          new THREE.Vector3(nearPoints[3].x+xDist*i, nearPoints[3].y+yDist*i, nearPoints[3].z+cuboidThickness*i), // farBottomLeft
      ];
      cuboidList.push(cuboid);
  }
  //Finally get the X/Y/Z max and min as bounding box for each cuboid

最后一段代码尚无法使用,我的主要担心是我无法正确理解什么是相机空间以及什么是世界空间。在执行此功能之前,我使用camera.updateMatrixWorld()更新相机并相应地更新了平截头体。

0 个答案:

没有答案