繁体   English   中英

如何在JavaScript中计算旋转3D立方体的x和y坐标?

[英]How to calculate x and y coordinates of a rotated 3D cube in JavaScript?

我试图用所有单独的小div制成3D立方体。 可以说我们有一个3 * 3 * 3 div的立方体。 有关所有div的信息:

  • X,Y,Z坐标(3D立方体的坐标)
  • 绕X和Y轴旋转的角度

从技术上讲,这应该足以计算多维数据集的2D透视投影。 现在的问题是:如何计算每个div的X和Y坐标?

附言 此类链接的一个类似示例在以下链接中: http : //maettig.com/code/javascript/3d_dots.html 在此示例中,我不喜欢的两件事是:

  • 立方体旋转的方式。 例如,如果我按下鼠标,则立方体向上旋转。 同样,对于鼠标的水平移动,立方体总是绕同一轴旋转,对于鼠标的垂直移动,立方体相对于水平旋转旋转。
  • 多维数据集的角落只有一个“ +”,我想要一个填充的(大量)多维数据集。

我认为您要问的问题有两种不同的答案: 直接回答您的问题 ,以及回答您的问题


转至“如何计算每个div的X和Y坐标?”

注意-以下答案是我为Android透视投影中的将GPS点转换为屏幕点线程的帖子重新编写的内容。 您也可以查阅Wikipedia的文章“ 3D投影 ”以获得更通用的答案。

您将需要更多信息来执行透视投影,例如相机/眼睛的位置/方向,其视角以及要在其上投影多维数据集的表面。

有了这些,您应该能够在div元素上循环,然后在它们的4个角顶点上应用旋转变换并投影它们中的每一个,最终使用您获得的2D坐标来渲染元素。

应用旋转

让我们简化情况。 我们有:

  • 顶点A(x_0,y_0,z_0), div一个角
  • θδ分别定义要应用的旋转角度。 俯仰角偏航角Tayt-Brian角

...而我们想要:

  • D(x,y,z),旋转元素的位置

因此,您的线性方程为:

  • 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)

投影-简介

现在我们有:

  • 我们的点D(x,y,z)
  • w * h ,您要在其上投影的表面的尺寸(例如,对于您的情况为innerWidth * innerHeight
  • 半视角 α

...而我们想要:

  • B在曲面上的坐标(我们称它们为XY

X屏幕坐标的模式:

E是我们在此配置中“眼睛”的位置,我选择它作为原点来简化。 如果不是这种情况,并且/或者如果您还想旋转相机,则需要在下一步之前再次将相应的平移和/或旋转变换应用于D。

可以知道以下情况来估计焦距f

  • tan(α) = (w/2) / f (1)

一点几何

您可以在图片上看到,三角形ECDEBM 相似 ,因此使用Side-Splitter定理 ,我们得到:

  • MB / CD = EM / EC <=> X / x = f / z (2)

有了(1)(2) ,我们现在有了:

  • X = (x / z) * ( (w / 2) / tan(α) )

注意:与Y的推理相同。

实际使用

一些说明:

  • 通常,使用α= 45deg ,这意味着tan(α) = 1 这就是为什么该术语没有在许多实现中出现的原因。
  • 如果要保留显示元素的比例,请对XY保持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/2Y += h/2问题已解决。


对于显示由div制成的3D立方体的问题

从我看到的情况来看,上述方法存在缺陷。 当然,您可以获得定义旋转和投影div元素的2D坐标,但是如何使用它来渲染它们呢?

投影后,您的div可能看起来不再是矩形,这使得使用简单的CSS很难渲染,尤其是在div元素包含复杂内容的情况下。

因此,如果您的真正目的是显示具有旋转和透视图的3D DOM立方体,那么我建议您使用CSS3 3D变换 ,让浏览器进行计算。

例如,您将在此处找到仅使用HTML和CSS3实现此类多维数据集的教程。

优点是多方面的:

  • 您将从浏览器的GPU加速中受益,使其比使用普通JS平滑。
  • 它会影响div的内容(旋转,透视)
  • 没有数学可以实现

您可能只需要担心针对较旧版本( http://caniuse.com/transforms3d )的浏览器兼容性。

如果要动态旋转立方体(例如,当鼠标移动时),只需使用JS编辑CSS转换

我很快制作了这个JSFiddle ,只需从教程中复制实现并添加onmousemove处理程序即可更新轮换。

希望它有所帮助,再见!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM