[英]How to calculate x and y coordinates of a rotated 3D cube in JavaScript?
我试图用所有单独的小div制成3D立方体。 可以说我们有一个3 * 3 * 3 div的立方体。 有关所有div的信息:
从技术上讲,这应该足以计算多维数据集的2D透视投影。 现在的问题是:如何计算每个div的X和Y坐标?
附言 此类链接的一个类似示例在以下链接中: http : //maettig.com/code/javascript/3d_dots.html 。 在此示例中,我不喜欢的两件事是:
我认为您要问的问题有两种不同的答案: 直接回答您的问题 ,以及回答您的问题 :
注意-以下答案是我为Android透视投影中的将GPS点转换为屏幕点线程的帖子重新编写的内容。 您也可以查阅Wikipedia的文章“ 3D投影 ”以获得更通用的答案。
您将需要更多信息来执行透视投影,例如相机/眼睛的位置/方向,其视角以及要在其上投影多维数据集的表面。
有了这些,您应该能够在div
元素上循环,然后在它们的4个角顶点上应用旋转变换并投影它们中的每一个,最终使用您获得的2D坐标来渲染元素。
让我们简化情况。 我们有:
div
一个角 ...而我们想要:
因此,您的线性方程为:
x = sin(δ) * y_0 + cos(δ) * x_0
y = sin(θ) * z_0 + cos(θ) * (cos(δ) * y_0 − sin(δ) * x_0)
z = cos(θ) * z_0 i sin(θ) * (cos(δ) * y_0 − sin(δ) * x_0)
现在我们有:
innerWidth
* innerHeight
) ...而我们想要:
X屏幕坐标的模式:
E是我们在此配置中“眼睛”的位置,我选择它作为原点来简化。 如果不是这种情况,并且/或者如果您还想旋转相机,则需要在下一步之前再次将相应的平移和/或旋转变换应用于D。
可以知道以下情况来估计焦距f :
tan(α) = (w/2) / f
(1) 您可以在图片上看到,三角形ECD和EBM 相似 ,因此使用Side-Splitter定理 ,我们得到:
MB / CD = EM / EC
<=> X / x = f / z
(2) 有了(1)和(2) ,我们现在有了:
X = (x / z) * ( (w / 2) / tan(α) )
注意:与Y的推理相同。
一些说明:
tan(α) = 1
。 这就是为什么该术语没有在许多实现中出现的原因。 如果要保留显示元素的比例,请对X和Y保持f不变,即不要计算:
X = (x / z) * ( (w / 2) / tan(α) )
和Y = (y / z) * ( (h / 2) / tan(α) )
...做:
X = (x / z) * ( size / 2) / tan(α) )
和Y = (y / z) * ( (size / 2) / tan(α) )
, size
为您定义的常数( size = min(w,h)
例如,通常使用size = min(w,h)
或size = (w+h)/2
)。 它只会影响焦点,进而影响视角。 如您在上面的图片中可能已经注意到的,屏幕坐标在此处定义为[-w / 2; w / 2]用于X和[-h / 2; h / 2]表示Y,但您可能想要[0; w]和[0; h] 。 X += w/2
和Y += h/2
问题已解决。
div
制成的3D立方体的问题 从我看到的情况来看,上述方法存在缺陷。 当然,您可以获得定义旋转和投影div
元素的2D坐标,但是如何使用它来渲染它们呢? 。
投影后,您的div
可能看起来不再是矩形,这使得使用简单的CSS很难渲染,尤其是在div
元素包含复杂内容的情况下。
因此,如果您的真正目的是显示具有旋转和透视图的3D DOM立方体,那么我建议您使用CSS3 3D变换 ,让浏览器进行计算。
例如,您将在此处找到仅使用HTML和CSS3实现此类多维数据集的教程。
优点是多方面的:
div
的内容(旋转,透视) 您可能只需要担心针对较旧版本( http://caniuse.com/transforms3d )的浏览器兼容性。
如果要动态旋转立方体(例如,当鼠标移动时),只需使用JS编辑CSS转换
我很快制作了这个JSFiddle ,只需从教程中复制实现并添加onmousemove
处理程序即可更新轮换。
希望它有所帮助,再见!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.