我目前正在用pygame创建一条透视3D道路,并试图将相机在y轴上从0度旋转到360度。但当相机与y轴的夹角大于90度时,我在屏幕上看到的图像会翻转,向前移动实际上会导致相机向后移动。。。
我对180度角的期望是什么;在"后面";相机,但这不是我得到的。
这是我用来投影和旋转世界的代码,我猜我的数学在某个地方是错误的,因为sin/cos的属性,但我找不到问题的原因。。。
def rotate2DPoint(x,y, angle):
"""rotate 2d point in an angle"""
return cos(angle)*x-sin(angle)*y, sin(angle)*x+cos(angle)*y
def rotate3Dpoint(x,y,z,angleX=0,angleY=0, angleZ = 0):
"""rotate a 3D point in an angle """
x,z = rotate2DPoint(x,z,angleY)
y,z = rotate2DPoint(y,z,angleX)
x,y = rotate2DPoint(x,y,angleZ)
return x,y,z
def project(x,y,z, camera):
"""project a 3D point to 2D screen
returns screen x,y and the scale factor"""
# Translate the points to be reletive to the camera
x_distance = x - camera.location["x"] #distance from the camera on x
y_distance = y - camera.location["y"] #distance from the camera on y
z_distance = z - camera.location["z"] #distance from the camera on z
# get the projection factor
factor = camera.depth / (z_distance or 0.1) # don't divide in 0...
# rotate :
x_distance,y_distance, z_distance = rotate3Dpoint(x_distance,y_distance, z_distance, angleY = camera.angleY, angleX= camera.angleX, angleZ = camera.angleZ)
# project:
x = int(SCREEN_WIDTH/2 + factor * x_distance )
y = int(SCREEN_HEIGHT/2 - factor * y_distance )
return x,y, factor
只有相机的Y角度不同于0。对于道路,我只存储一个点,所以对于道路的每一部分,我都投影一个点。
在几乎放弃之后,我发现了问题。。我在计算因子后旋转,而不是在。。。这防止了新的CCD_ 1影响投影。
因此正确的功能是:
def project(x,y,z, camera):
"""project a 3D point to 2D screen
returns screen x,y and the scale factor"""
x_distance = x - camera.location["x"]
y_distance = y - camera.location["y"]
z_distance = z - camera.location["z"]
x_distance,y_distance, z_distance = rotate3Dpoint(x_distance,y_distance, z_distance, angleY = camera.angleY, angleX= camera.angleX, angleZ = camera.angleZ)
factor = camera.depth / (z_distance or 0.1)
x = int(SCREEN_WIDTH/2 + factor * x_distance )
y = int(SCREEN_HEIGHT/2 - factor * y_distance )
return x,y, factor