我试图用Java自己实现一个查看管道,所以我只使用Java AWT在画布上绘制2D多边形,而根本没有OpenGL的帮助。
我想和你一起测试我的成绩,因为这是一个难题,我可能误解了一些观点。
我制作了一些用于测试的原始数据文件。这是一个代表3D立方体的文件:
8 // number of vertices
0 0 0 // list of vertices indices...
1 0 0
1 1 0
0 1 0
0 0 1
1 0 1
1 1 1
0 1 1
12 // number of polygons
0 1 // first polygon coordinates indices (so the first polygon is 0 0 0 to 1 0 0)
1 2 // second polygon is 1 0 0
2 3 // and so on
3 0
4 5
5 6
6 7
7 0
0 4
1 5
2 6
3 7
以上实际上是12条折线,它们应该在屏幕上形成3D立方体。
这是相机配置:
Position 0.5 0.5 1 // position of camera
LookAt 0.5 0.5 0.5 // look at point
Up 0 1 0 // up vector
Window -1 1 -1 1 // window size, (-1,-1) to (1,1) includes all the above polygons in window
Viewport 800 600 // viewport size, not so relevant
当我绘制上面的多边形时,由于我的相机看着立方体的中心,并且正好位于它的前面(距离1,所以我能够看到一些东西), 我希望在屏幕上看到一个正常的正方形(因为所有3D边缘都正好在正方形面后面)。
我潜入了我的代码,以便找出对角线的来源,并意识到虽然我希望坐标(0,0,0)和(0,0,1)落在2D中的相同点(特别是当我们与立方体完全垂直时),它们彼此对角。
更详细:
将(0,0,0)坐标转换为视图坐标导致(-0.5,-0.5,-1),而(0,0,1)转换为(-0.5,-0.5,0)。
现在,当将每个投影到2D时,(0,0,0)变为(0.5,0.5)并且(0,0,1)变为(-0.5,-0.5)。这就是他们出现对角线的原因,并绘制多边形0 4(基本上是它们之间的一条线)是一条对角线。
为什么会这样?
我错误地认为我应该看到一个正方形,或者我都很好,这可能是计算中的一个错误?你得到与我相同的结果吗?
如果有人想知道,以下是我用来转换为查看坐标的计算:
投影2D空间:
我计算的d好像是从相机到外观点的距离,但是在我看来我可能错了。这是我的来源(我认为我误解了,但无法弄清楚是什么):
根据Nico的回答,现在我设置d = 1(然后将方程式保留为/ z + d)。我还将第8个多边形从7 0更改为7 4,这更有意义。这就是我得到的,数字是相机位置的变化:
为什么z = 1上的对角线看起来像那样?
答案 0 :(得分:1)
首先,您的投影中心位于立方体的背面。因此,这张脸上的点被投射到无限远处。将投影中心进一步移动(例如,将z坐标设置为2)。
其次,您的视图变换和投影变换似乎不匹配。使用以下转换来获得合理的值:
xp = d * x / z
yp = d * y / z
zp = d
通常,d
设置为1,但如果设置合理的窗口大小则无关紧要。
请记住,这是一个透视变换。因此,点(0, 0, 0)
和(0, 0, 1)
不会投射到同一点。