旋转3D立方体透视问题

时间:2009-07-12 14:49:19

标签: graphics 3d svg cube

自从我13岁开始玩AMOS 3D以来,我一直想学习如何编写3D图形。现在,10年后,我终于认为我已经积累了足够的数学来试一试。

我遵循了各种教程,并将screenX(和screenY,等效)定义为

screenX = (pointX * cameraX) / distance

(加偏移和缩放。)

我的问题是距离变量实际上指的是什么。我已经看到距离被定义为相机和点之间z的差异。然而,这不可能是完全正确的,因为x和y与从相机到该点的实际距离上的z具有相同的效果。我将距离作为实际距离来实现,但结果给出了一个有点偏斜的视角,好像它有“太多”的视角。

我的“实际距离”实施方式如下:

distance = new Vector(pointX, pointY, cameraZ - pointZ).magnitude()

使用代码,我在我的等式中添加了一个额外的变量,一个perspectiveCoefficient如下:

distance = new Vector(pointX * perspectiveCoefficient, 
  pointY * perspectiveCoefficient, cameraZ - pointZ).magnitude()

出于某种原因,这超出了我的范围,我倾向于获得将perspectiveCoefficient设置为1 / sqrt(2)的最佳结果。

我的3D测试多维数据集位于http://vega.soi.city.ac.uk/~abdv866/3dcubetest/3dtest.svg。 (在Safari和FF中测试过。)它会提示你一个perspectiveCoefficient,其中0给出了一个不考虑x / y距离的透视图,1给出了一个透视图,其中x,y和z距离被同等考虑。默认为1 / sqrt(2)。可以使用箭头键将立方体旋转大约x和y。 (对于任何感兴趣的人,相关代码都在View.js文件的update()中。)

感谢任何有关此事的想法。

1 个答案:

答案 0 :(得分:5)

通常,从该平面后面的眼睛位置在Z = 0平面上进行投影。投影点是线(Pt,Eye)与Z = 0平面的交点。最后你会得到类似的东西:

screenX = scaling * pointX / (1 + pointZ/eyeDist)
screenY = scaling * pointY / (1 + pointZ/eyeDist)

我假设相机处于(0,0,0)并注视(0,0,-eyeDist)。如果eyeDist变为无限,则获得平行投影。