当前位置: 首页 > 知识库问答 >
问题:

调整相机以匹配光线和屏幕点

有凯泽
2023-03-14

我正在为360度全景的自由视图工具工作,用三个。js。我希望相机旋转时,用户从屏幕拖动点离开点正好在鼠标指针下。

this.mesh = new THREE.Mesh(new THREE.BoxGeometry(2, 2, 2, 0, 0, 0),
    new THREE.MeshFaceMaterial(_array_of_THREE.MeshBasicMaterial_));
this.camera = new THREE.PerspectiveCamera(90, width / height, 0.1, 2);
    null
adjustCamera: function(cameraDirection, worldRay, screenPoint){
        var angle;
        this.camera.lookAt(cameraDirection);
        this.raycaster.setFromCamera(screenPoint, this.camera);
        this.axis.copy(this.raycaster.ray.direction);
        angle = this.axis.angleTo(worldRay);
        this.axis.cross(worldRay).normalize();
        this.ray.copy(cameraDirection);
        this.ray.applyAxisAngle(this.axis, angle).normalize();
        this.camera.lookAt(this.ray);
    }

我意识到为什么这个模式不起作用。以这种方式改变相机方向会得到一些滚转(当旋转轴具有非零z坐标时),这被lookkat消除--它会消除滚转,只留下俯仰和偏航。这导致了一些不准确,当初始和最终射线更远,当初始相机位置有更高的俯仰时,它就会增长。我现在被困在这里,不知道如何在没有滚动的情况下计算摄像机的位置。

所以,问题是:我怎样才能准确地旋转相机,把特定的光线带到特定的屏幕点?(最好适合我使用的模式)

编辑:实际上可能有不止一个(似乎不超过两个,前提是光线不指向最低点或天顶)正确的相机位置(没有滚动),将世界光线投射到屏幕上的特定点。

在这种模棱两可的情况下,应选择最接近初始相机方向的选项。

共有1个答案

袁旻
2023-03-14

为类似的全景目的解决这个问题需要相当长的时间。

这里的复杂之处在于如何从摄像机注视方向向上向量来构造旋转矩阵,该向量固定了滚动方向。矩阵最终投射出规则的X、Y和Z轴,这样:

  • Z匹配查找方向
  • x与Z和向上向量垂直。
  • y与X和Z垂直,以使两轴正交。
axisZ = direction;
axisX = normalize(cross(up, direction));
axisY = cross(direction, axisX);

您只需展开everything的所有项就可以得到视图的X、Y和Z分量的方程,并尝试提取Direction的分量。多亏了平方根,你得到了一个高次多项式系统,有3个方程和变量,几乎都是相互参照的。因为所有的轴都是正交的,所以可以使用z2=1-x2*y2来消除一个变量和方程,但是得到的两个多项式是四次的,都共享两个变量。我一开始是无法解决的,也是无意中尝试了一下:

w=M-1旋转v=MT旋转v

反转相机方向交换输入和输出,转置旋转矩阵使方程看起来完全不同。

(vx*sqrt(1-dy2-dx2)-vy*dx-wx-dz*dx)2*(1-dy2)=0

现在,第一个是一个双二次方程,可以手工符号化地求解dY,相机的Y分量看方向。用Wolframα求解DX的第二个问题,得到4个多项式,每个多项式约300项。定义一些辅助变量,然后产生一个合理的算法。它既不短也不快(不要把它放在顶点着色器中),但绝对能实现对鼠标移动做出直观反应的目的。我想出的启发式没有一个同样有效。

这是打字稿。

请注意,方向旋转天顶或天底点偏离YZ平面或位于XZ平面的错误一侧,根本不存在。这意味着用户不能完全任意地在屏幕上拖动点,除非你允许改变向上向量。

 类似资料:
  • 问题内容: 我正在地图上绘制一个圆(在用户当前位置上),并且我希望屏幕进行缩放以使圆在全屏中具有一定的边距。我现在正在做什么: 好吧,我尝试了一些愚蠢的演算,因为我找不到合适的解决方案… 有人有主意吗? 问题答案: 如果我理解正确,您是否希望地图适合圆形边界?如果是这样的话 像这样加一个圆 那么您需要您的圆的边界框,请阅读此 并尝试 终于打电话

  • 在持续按住PS键后显示的画面,可调整屏幕的亮度。 拖拽滑杆的旋钮,移动至想设定的亮度后再放开手指。

  • null null 当然,任何其他建议都将不胜感激。 注意:也有类似的问题,我花了几个小时来研究,但没有一个正确地解决了我的问题,也没有给出足够的细节。

  • 我想调整一个视图的大小,开始像200px宽100px高,然后“扩展”到填充半个屏幕时,它被点击。它背后的所有视图都应该保持在同一个位置。我只想扩展该视图,填满半个屏幕,重叠当前屏幕上的任何内容。 null

  • 问题内容: 我在网页上使用径向渐变作为背景,如下所示: 它可以工作,但是当内容不能填满整个页面时,渐变会被切断。如何使元素始终填充整个页面? 问题答案:

  • 问题内容: 我编写了一个应用程序,该应用程序基于固定像素位置自定义绘制paint()中的所有内容。然后我禁用了调整框架的大小,使其始终可见。 但是,现在我希望能够调整它的大小,但是我不想更改我的绘图代码。我希望我可以在所有绘制代码​​之后抓取Graphics g对象的300x300正方形并将其大小调整为JFrame当前大小,但是我不知道自己在做什么。 这里是示例代码。在此,我希望将100x100正

  • 我有一个带高度的:match_parent,它在adapter中以固定高度垂直显示16个项目。除了屏幕大小不同之外,一切都很好。在大屏幕上,16个项目显示后,底部仍留有一个空间,而在小屏幕手机上,它完全适合底部。我正在寻找一种方法,可以将列表项的高度调整为高度,直到结束时不可滚动。 查看下面的屏幕截图以了解更多说明 问题: 期望: 我的方法是将项目权重设置为1,因此当渲染到16次时,它们将在中共享