python中的Normalize和Perpendicular函数

时间:2013-06-03 05:54:07

标签: python python-2.7

我正在浏览2D游戏中创建Lightning效果的 blog 。我想在python中实现相同的功能。但是我被困在一个地方。

假设起点终点是2D平面中的坐标,表示线段的极值点。

让我们从博客中查看以下代码片段:

midPoint = Average(startpoint, endPoint);
// Offset the midpoint by a random amount along the normal.
midPoint += Perpendicular(Normalize(endPoint-startPoint))*RandomFloat(-offsetAmount,offsetAmount); 


Normalize(endPoint-startPoint):

该行从startPoint到endPoint获得单位向量(长度为1的向量)


Perpendicular(Normalize(endPoint-startPoint))
然后

获得垂直于该矢量的矢量(即与线成直角)


我不是常规的python编码器。在python中是否有任何内置的 Normalize Perpendicular 函数可以帮助我在python中实现上述代码。

3 个答案:

答案 0 :(得分:7)

我不知道内置或第三方方法,但它们非常简单:

import numpy as np

def perpendicular( a ) :
    b = np.empty_like(a)
    b[0] = -a[1]
    b[1] = a[0]
    return b

def normalize(a):
    a = np.array(a)
    return a/np.linalg.norm(a)

if __name__ == "__main__":    
    a = [1,2]
    print perpendicular(normalize(a))
    b = (4,-6)
    print perpendicular(normalize(b))

这将打印

[-0.89442719  0.4472136 ]
[ 0.83205029  0.5547002 ]

您可以使用

调用这些函数
  • 两元组
  • 长度为二的列表
  • 长度为2的1d阵列

或类似的类型。

请注意,如果向量a的长度为零,normalize将引发异常。

我决定根据PEP 8,Python风格指南命名我的函数小写。

答案 1 :(得分:5)

正如@SethMMorton和@ThoestenKranz所说,numpy对矢量操作有很多支持。我认为Python中没有内置的支持来获得你想要的东西。但是,使用简单的三角函数,您可以使用内置的数学模块轻松地计算归一化和垂直。

import math
class Coord(object):
    def __init__(self,x,y):
        self.x = x
        self.y = y

    def __sub__(self,other):
        # This allows you to substract vectors
        return Coord(self.x-other.x,self.y-other.y)

    def __repr__(self):
        # Used to get human readable coordinates when printing
        return "Coord(%f,%f)"%(self.x,self.y)

    def length(self):
        # Returns the length of the vector
        return math.sqrt(self.x**2 + self.y**2)

    def angle(self):
        # Returns the vector's angle
        return math.atan2(self.y,self.x)

def normalize(coord):
    return Coord(
        coord.x/coord.length(),
        coord.y/coord.length()
        )

def perpendicular(coord):
    # Shifts the angle by pi/2 and calculate the coordinates
    # using the original vector length
    return Coord(
        coord.length()*math.cos(coord.angle()+math.pi/2),
        coord.length()*math.sin(coord.angle()+math.pi/2)
        )

a = Coord(2,12)
b = Coord(7,5)
print perpendicular(normalize(a-b))

答案 2 :(得分:4)

我建议您查看numpy包。它具有许多内置的快速数学运算。您可以分别使用normcross作为NormalizePerpendicular的起点。