自从我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()中。)
感谢任何有关此事的想法。
答案 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变为无限,则获得平行投影。