【问题标题】:Three.js: converting 3d position to 2d screen positionThree.js:将 3d 位置转换为 2d 屏幕位置
【发布时间】:2012-07-17 01:16:48
【问题描述】:

我有一个位置为 (x,y,z) 的 3D 对象。如何计算该对象的屏幕位置(x,y)?

我已经搜索了它,一种解决方案是我必须找出投影矩阵,然后将 3D 位置点乘以该矩阵,以将其投影到某个 2D 观察表面(计算机屏幕)上。但我不知道如何在 Three.js 中找到这个矩阵。

我尝试了这样的转换函数,但结果不正确

function Point3DToScreen2D(point3D){
            var screenX = 0;
            var screenY = 0;
            var inputX = point3D.x - camera.position.x;
            var inputY = point3D.y - camera.position.y;
            var inputZ = point3D.z - camera.position.z;
            var aspectRatio = renderer.domElement.width / renderer.domElement.height;
            screenX = inputX / (-inputZ * Math.tan(camera.fov/2));
            screenY = (inputY * aspectRatio) / (-inputZ * Math.tan(camera.fov / 2));
            screenX = screenX * renderer.domElement.width;
            screenY = renderer.domElement.height * (1-screenY);
            return {x: screenX, y: screenY};
        }

提前致谢。

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    对我来说这个功能有效(Three.js 版本 69):

    function createVector(x, y, z, camera, width, height) {
            var p = new THREE.Vector3(x, y, z);
            var vector = p.project(camera);
    
            vector.x = (vector.x + 1) / 2 * width;
            vector.y = -(vector.y - 1) / 2 * height;
    
            return vector;
        }

    【讨论】:

    • 这太完美了!请记住 project 是一个可变方法,因此如果您在现有 Vector3 上使用它,请先调用 clone
    • z 为 0 时失败
    • 应该不会失败。请提供一些 jsbin/jsfiddle 示例。
    【解决方案2】:

    我终于用这段代码完成了:

    注意:div 参数 = canvas dom 元素。

    function toScreenXY( position, camera, div ) {
                var pos = position.clone();
                projScreenMat = new THREE.Matrix4();
                projScreenMat.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
                projScreenMat.multiplyVector3( pos );
    
                var offset = findOffset(div);
    
                return { x: ( pos.x + 1 ) * div.width / 2 + offset.left,
                     y: ( - pos.y + 1) * div.height / 2 + offset.top };
    
            }
    function findOffset(element) { 
              var pos = new Object();
              pos.left = pos.top = 0;        
              if (element.offsetParent)  
              { 
                do  
                { 
                  pos.left += element.offsetLeft; 
                  pos.top += element.offsetTop; 
                } while (element = element.offsetParent); 
              } 
              return pos;
            } 
    

    【讨论】:

    • 感谢您的尝试,因为这是一个似乎没有任何记录解决方案的问题,但我无法提供准确的坐标。
    • 您能否详细介绍一下您的案例?
    • 谢谢你,这是我写的:stackoverflow.com/questions/11586527/…
    • 我相信您的坐标不准确问题来自不正确的 div(第三个参数)输入。无论如何,似乎你找到了答案。恭喜!
    【解决方案3】:

    在演示中查看源代码: http://stemkoski.github.com/Three.js/Mouse-Over.html

    我相信你感兴趣的对象是 THREE.Projector();例如,您可以使用它来自动计算,从屏幕上的鼠标光标位置创建光线并将其投影到场景中。

    【讨论】:

    • 感谢您的回复,李。假设我有一条射线,它的原点是物体的位置,它的方向是屏幕。那么射线将与哪个对象相交以将屏幕上对象的 (x,y) 返回给我?谢谢。
    猜你喜欢
    • 2013-11-22
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 2019-07-04
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多