找到一条直线消失后的点 - three.js

Find the point of a line after which it dissapears - three.js

我想在场景中的轴上放置 x、y、z 标签(精灵)。问题是用相机缩放,应该会导致粒子也类似地移动,因此它们会停留在 "screen".

的一侧

所以我只想找到一种方法来始终知道 x、y、z 的线在相机之外的位置以更新标签的位置: fiddle(这里它们只是静态的)。

我可能需要实现的伪代码:

    function update() { 
      var pointInLinePosition = calculateLastVisiblePointOfXline();
      xSprite.position.set(pointInLinePosition.x, pointInLinePosition.y, pointInLinePosition.z);
    }

    function calculateLastVisiblePointOfXline(){
    } 

我找到了一个足够令人满意(至少对我而言)但并不完美的解决方案。

首先,我使用场景的相机创建了一个平截头体:

var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse ) );

然后,我检查平截头体的任何平面是否与场景中的任何直线相交:

for (var i = frustum.planes.length - 1; i >= 0; i--) { 

      var py = frustum.planes[i].intersectLine( new THREE.Line3( new THREE.Vector3(0,0,0), new THREE.Vector3(1000,0,0) ) ) ; 
      if(py !== undefined) {
        ySprite.position.x = py.x-1 ;  
      }

      var px = frustum.planes[i].intersectLine( new THREE.Line3( new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,1000) ) ) ; 
      if(px !== undefined) {
        xSprite.position.z = px.z-1 ; 
      }

    };

如果有交点,我使用交点 intersectLine() 的 return 值更新标签的位置。

这是更新后的 fiddle : fiddle

希望对您有所帮助。就我而言,它适合。

正确的交点测试还必须确保交点实际上在平截头体内,因为平截头体平面无限延伸,可能导致误报交点。

验证交点的一种简单方法是检查交点到所有平面的距离。如果距离大于或等于零,则该点在平截头体内。

从 ThanosSar 的回答中截取的调整后代码:

const intersect = point => frustum.planes
    .map(plane =>
        plane.intersectLine(new THREE.Line3(new THREE.Vector3(0, 0, 0), point))
    )
    .filter(sect => sect != null)
    .filter(sect => frustum.planes.every(plane => plane.distanceToPoint(sect) >= -0.000001))[0];

const iy = intersect(new THREE.Vector3(1000, 0, 0));
if (iy != null)
    ySprite.position.x = iy.x - 1;

const ix = intersect(new THREE.Vector3(0, 0, 1000));
if (ix != null)
    xSprite.position.z = ix.z - 1;

(与 >= -0.000001 进行比较以解决浮点舍入误差)

Fiddle