0

我目前正在使用 pygame 创建一个 persudo 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 不同。对于道路,我只存储一个点 - 所以对于道路的每一部分,我都在投影一个点。

4

1 回答 1

0

在几乎放弃之后,我发现了问题......我在计算因子之后而不是之前旋转......这可以防止新z_distance的影响投影。

所以正确的功能是:

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 
于 2021-11-09T22:45:58.043 回答