【问题标题】:Find the point of a line after which it dissapears - three.js找到一条线后消失的点-three.js
【发布时间】:2015-09-23 13:20:38
【问题描述】:

我想将 x、y、z 标签(精灵)放置在场景中的轴上。问题是用相机进行缩放,应该会导致类似地移动粒子,使它们停留在“屏幕”的一侧。

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

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

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

    function calculateLastVisiblePointOfXline(){
    } 

【问题讨论】:

  • 我已经问过自己好几次了,我很高兴知道答案
  • 那么您是否希望能够从屏幕坐标中找到 3d 空间中的点?这会有帮助吗?
  • @tomatosource 也许是的,告诉我你在想什么。
  • @Atrahasis 我正在尝试使用 cameraHelper,如果我发现任何有用的信息,我会告诉你。

标签: camera three.js position line particles


【解决方案1】:

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

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

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() 的返回值更新标签的位置,即交叉点。

这是更新后的小提琴:fiddle

我希望这会有所帮助。在我的情况下,它适合。

【讨论】:

  • 我做了类似的事情,它有一个与您的解决方案共同的问题:截锥体的平面无限延伸,并且截锥体之外的交叉点可能会发生。所以需要找到正确的交叉点。
【解决方案2】:

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

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

从 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

【讨论】:

    猜你喜欢
    • 2015-11-10
    • 2022-01-04
    • 2021-05-21
    • 2016-12-08
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多