3

我正在浏览有关在 2D 游戏中创建闪电效果的博客。我想在 python 中实现相同的效果。但是我被困在一个地方。

假设startpointendPoint是 2D plane 中的坐标,表示线段的极值点。

让我们看一下博客中的以下代码片段:

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 中是否有任何内置的NormalizePerpendicular函数可以帮助我在 python 中实现上述代码。

4

3 回答 3

10

我不知道内置或第三方方法,但它们真的很简单:

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 的列表
  • 长度为 2 的一维数组

或类似的类型。

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

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

于 2013-06-03T06:01:36.553 回答
6

正如@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))
于 2013-06-03T06:55:43.713 回答
4

我建议看一下numpy包。它有许多内置的快速数学运算。您可以分别使用normcrossNormalize作为和的起点Perpendicular

于 2013-06-03T06:01:53.380 回答