我无法将3D坐标投影到2D屏幕坐标

时间:2015-03-19 21:19:47

标签: python 3d

注意:因为我是新成员,我显然需要10个声望来发布图片或超过2个链接,我将提到this imgur album的视觉效果。抱歉给您带来不便。

我试图制作一个程序来在python中可视化3D对象,但是我对将3D坐标投影到2D屏幕坐标上的函数有疑问。它在某些情况下有效,但不是全部。当相机相对远离该点并且在相同水平上时,投影看起来非常好,例如在该图像中描绘了十边形和矩形,其顶点由3D点定义(图2)。然而,当相机向下看时,它们描绘的物体不成比例地变平(图3),当相机接近它必须投射的点时,形状会变形(图4)。

有问题的函数是Camera.projectPoint,我已经包含了它在下面使用的所有函数和类:

class Vector3:

    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
        self.mag = math.sqrt(x**2+y**2+z**2)
        self.yaw = math.atan2(self.y, self.x)
        self.pitch = math.atan2(self.z, math.sqrt(self.x**2+self.y**2))

class Point:

    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def vectorTo(self, p):
        return(Vector3(p.x-self.x, p.y-self.y, p.z-self.z))

class Camera:

    def __init__(self, pos, yaw, pitch, FOV=math.pi/2):
        self.pos = pos
        self.yaw = yaw
        self.pitch = pitch
        self.FOV = FOV

    def projectPoint(self, point):
        ## finding the vector from the camera position to the point
        v = self.pos.vectorTo(point)
        ## setting alpha to the difference in yaw between the camera and the vector to the point
        ## and beta to the difference in pitch
        alpha = v.yaw - self.yaw
        beta = v.pitch - self.pitch
        ## making sure that the smallest angle between the two is chosen
        ## (difference between 300 degrees and 10 degrees is 70, not 290)
        alpha = (alpha+math.pi)%(2*math.pi)-math.pi
        beta = (beta+math.pi)%(2*math.pi)-math.pi
        ## Doing the operation pictured in the diagram
        h = math.sin(self.FOV/2)/math.cos(self.FOV/2)
        x1 = math.sin(alpha)/math.cos(alpha)
        y1 = math.sin(beta)/math.cos(beta)
        ## adjusting for screen resolution
        return(x1*1000/h+500, y1*1000/h+325)

我已经四处寻找将3D坐标投影到屏幕上的算法,并找到了许多内容,例如Figure 1中描述的内容(这是我的函数所基于的),但它似乎并没有很好地运作。这是算法的问题吗?我赞美它的方式?它使用的功能之一? (我99%肯定所有其他功能和类都非常好)。关于什么是错的以及如何解决它的任何想法?谢谢。

0 个答案:

没有答案