python中的透视投影和旋转

python中的透视投影和旋转,python,rotation,projection,perspective,Python,Rotation,Projection,Perspective,我试过搜索,但没有一个问题和我的一样。我或多或少地在python中尝试透视投影和旋转,但遇到了一个障碍。我确信我的投影方程和旋转方程都是精确的;但是,当我运行它时,旋转开始正常,但开始向内旋转,直到向量与Z轴(我正在旋转的轴)处于相同的位置 感谢您的任何意见:) 编辑:对不起,我刚意识到我忘了提问题。我只是想知道为什么它会向内引力,而不仅仅是“正常”旋转?这部分是错误的: self.ang += 1 if self.ang >= 361: self.ang = 0 self.vP

我试过搜索,但没有一个问题和我的一样。我或多或少地在python中尝试透视投影和旋转,但遇到了一个障碍。我确信我的投影方程和旋转方程都是精确的;但是,当我运行它时,旋转开始正常,但开始向内旋转,直到向量与Z轴(我正在旋转的轴)处于相同的位置

感谢您的任何意见:)

编辑:对不起,我刚意识到我忘了提问题。我只是想知道为什么它会向内引力,而不仅仅是“正常”旋转?

这部分是错误的:

self.ang += 1
if self.ang >= 361:
    self.ang = 0

self.vPoint.X = (self.vPoint.X * cos(radians(self.ang))
               - self.vPoint.Y * sin(radians(self.ang))) 
self.vPoint.Y = (self.vPoint.X * sin(radians(self.ang))
               + self.vPoint.Y * cos(radians(self.ang)))
self.vPoint.pProject()
原因有二:

  • self.ang
    将取开放范围[0-360]中的整数,这意味着重复角度360(=0)
  • 在每次迭代中,将点从上一次迭代旋转角度。因此,第一帧为1度,第二帧为1+2=3,第三帧为1+2+3。。。你应该:
    • 每次将上一次迭代的点旋转一个恒定角度(1°)。这与我在评论中提到的问题有关
    • 每次按当前旋转角度旋转初始点

  • 实际上与您的问题无关,但我强烈建议您使用Numpy执行几何变换,特别是在涉及3D点的情况下

    下面,我发布了一个示例片段,希望它能有所帮助:

    import numpy
    from math import radians, cos, sin
    
    ## suppose you have a Nx3 cloudpoint (it might even be a single row of x,y,z coordinates)
    cloudpoint = give_me_a_cloudpoint()
    
    ## this will be a rotation around Y azis:
    yrot = radians(some_angle_in_degrees)
    
    ## let's create a rotation matrix using a numpy array
    yrotmatrix = numpy.array([[cos(yrot), 0, -sin(yrot)],
                              [0,         1,          0],
                              [sin(yrot), 0,  cos(yrot)]], dtype=float)
    
    
    ## apply the rotation via dot multiplication
    rotatedcloud = numpy.dot(yrotmatrix, pointcloud.T).T   # .T means transposition
    

    您可以看到浮点错误累积的效果,因为
    self.vPoint
    是从其旧值派生的,但使用的是不精确的浮点数。你需要经常正交化矩阵,以防止这些错误失控。啊,好的。所以我应该说,每次θ回到0度,把X和Y重置回它们原来的大小?或者,根本不根据它们原来的向量计算向量。只有一个或两个角度是从它们的旧值计算出来的,而浮点错误的累积并不重要。然后从这些角度重新计算所有矢量。选项2.1(旋转初始点)正确。如果对象不变,但角度不变,则始终在“基线位置”对象上执行旋转,而不是增量旋转它(它会累积积分错误)。计算成本是相同的。如何有效地将其扩展到更大的点云?我想简单地增加<代码> yOrthMatx的维数,但是我不知道如何将角值缩放到中间的零点。@德克特摩根,我不确定我理解你的怀疑。通常,“放大”只意味着你有一个更大的点云(一个带有narger N的Nx3矩阵),人们会期望操作需要更长的时间,但我不相信它会需要更长的时间,除了非常大的点云(比如,数百万个点)。我也不明白你所说的“将角点值缩放到中间的零”是什么意思。无论如何,你永远不需要一个更大的
    yrotmatrix
    ,因为它必须是一个3x3矩阵。我不是指性能,而是说:如果点云是10x10,旋转矩阵会是什么样子?这是一个有趣的问题。我的答案假设3D空间中的点云是Nx3矩阵,其中N是点计数,3是维度(x、y、z)。当编写一个10x10点云时,这可能意味着两件事:要么是一组10个点,每个点都有10个维度(坐标),我觉得这不太可能,要么是一个10x10的3D点阵列。在后一种情况下,您可以使用
    numpy.reformate
    将其转换为100x3数组。在前一种情况下,需要一个10x10的旋转矩阵。但是我想知道10维点空间的实际意义是什么。我对通过这种方法旋转一些图像感兴趣,所以我有(100,100,3)RGB阵列。整形、旋转和整形背部是否有意义。。。关于你的最后一点:也许涉及弦论的东西可以在这么多维度上找到用途:)
    import numpy
    from math import radians, cos, sin
    
    ## suppose you have a Nx3 cloudpoint (it might even be a single row of x,y,z coordinates)
    cloudpoint = give_me_a_cloudpoint()
    
    ## this will be a rotation around Y azis:
    yrot = radians(some_angle_in_degrees)
    
    ## let's create a rotation matrix using a numpy array
    yrotmatrix = numpy.array([[cos(yrot), 0, -sin(yrot)],
                              [0,         1,          0],
                              [sin(yrot), 0,  cos(yrot)]], dtype=float)
    
    
    ## apply the rotation via dot multiplication
    rotatedcloud = numpy.dot(yrotmatrix, pointcloud.T).T   # .T means transposition