I'm currently working on creating a persudo 3D road with pygame, and I'm trying to rotate the camera on the y axis from 0 to 360 degrees. But when the camera angle with the y axis is grater then 90 degrees, the image i get on the screen is flipped, and going foward actually causes the camera to move backwards...
What I'm expecting for 180 angle is what is "behind" the camera, and it's not what I'm getting.
This is the code I use to project and rotate the world, my guess is my math is wrong somewhere because properties of sin/cos, but I could not find what is causing the issue...
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
only the Y angle for the camera is diffrent than 0. for the road I only store a point - so for each part of the road I'm projecting a point.
After almost giving up, I figured out the issue.. I'm rotating after I calculate the factor and not before... this prevents from the new
z_distanceto affect the projection.so the correct function is :