将球体表面上的点投影到2D中

时间:2012-12-10 05:03:01

标签: javascript math 3d

我有很多用HTML / CSS / JavaScript渲染的对象。这些物体都位于半径为R的不可见球体的表面上。

此外,与用户的交互允许这个不可见的球体任意旋转。

显而易见的解决方案是分配给物体(Theta,Phi和固定半径)的球形坐标,它被转换为笛卡尔3D坐标,然后我可以直接放下深度(Z),或者应用一些花哨的观点。我稍后会担心透视......

由于我正在使用图形,X / Y分别是水平/垂直,Z是深度,其中+ ve伸出屏幕,-ve在显示器内。

我有一个名为objects[]的JavaScript对象数组,每个对象都有一个Theta和Phi。我假设Theta是围绕Y轴的旋转,并且Phi是围绕X轴的旋转,使得在Phi = 0和Theta = 0时,我们处于(X,Y,Z)=(0,0,R);

由于我在旋转不可见的球体,我不想改变每个物体的Theta和Phi,这也会增加数值的不稳定性。相反,我存储了一个与球体自身旋转相关的全局Theta和Phi。

因此,积分的“有效”Theta和Phi是积分的Theta和Phi以及全球Theta和Phi。

根据维基百科,WolframAlpha,MathWorld和许多其他资源,我们可以通过以下方式从球形坐标中找到笛卡尔坐标:

z = r * sin(phi) * cos(theta);
y = r * sin(phi) * sin(theta);
x = r * cos(phi);

(我已经将维塔百科的Theta和Phi换成了向后使用它们,而我的X / Y / Z坐标也不同。)

我不确定为什么,但是当我渲染这些物体时,它们看起来并不正确。如果您想象使用Theta = Pi / 4的球体赤道上的一个点,并且您围绕Y轴旋转球体,则只有在投影到2D并且不使用透视变换时,该点才应上下移动。然而,这根本不是什么。点从屏幕的右侧移动到左侧。整件事看起来都错了。

1 个答案:

答案 0 :(得分:1)

订单很重要。当你使用方程时

z = r * sin(phi) * cos(theta);
y = r * sin(phi) * sin(theta);
x = r * cos(phi);

然后您可以phi将{em> y 和第二解释为theta关于首先的轮换 x (适合选择角度测量方向):

(x1, y1, z1) = (r, 0, 0)
(x2, y2, z2) = (x1 * cos(phi) - z1 * sin(phi),
                y1,
                x1 * sin(phi) + z1 * cos(phi))
             = (r * cos(phi), 0, r * sin(phi))
(x3, y3, z3) = (x2,
                y2 * cos(-theta) - z2 * sin(-theta),
                y2 * sin(-theta) + z2 * cos(-theta))
             = (r * cos(phi),
                r * sin(phi) * sin(theta),
                r * sin(phi) * cos(theta))

当您只是添加这些角度时,最终会得到错误的顺序:首先按phi1然后按theta1然后按phi2然后按theta2进行约不同的轴与先phi1 + phi2theta1 + theta2之后的旋转不同。您正在更改theta1phi2之间的顺序,这会破坏您的3D位置。

更好地使用rotation matricesquaternions,为您封装此类的库(如),或确保正确合并euler angles