Normalise and Perpendicular Function in python

2020-07-23 05:09发布

I was going through a blog on Creating Lightning effect in 2D game.I wanted to implement the same in python. However I am stuck at a place.

Lets say startpoint and endPoint are co-ordinates in 2D plane , representing extreme points of a line segment.

Lets look at following Code Snippet from the blog:

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):

That line gets a unit vector (vector of length 1) from startPoint to endPoint


Perpendicular(Normalize(endPoint-startPoint))

then gets a vector perpendicular to that (i.e. at right angles to the line)


I am not a regular python coder. Is there any in-built Normalise and Perpendicular Function in python that would help me in implementing the above code in python.

3条回答
贪生不怕死
2楼-- · 2020-07-23 05:37

I don't know of built-in or third-party methods, but they are really simple:

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))

This will print

[-0.89442719  0.4472136 ]
[ 0.83205029  0.5547002 ]

You can call these functions with

  • a two-tuple
  • a list of length two
  • an 1d-array of length 2

or similar types.

Be aware that normalize will raise an Exception if the vector a has length zero.

I decided to name my functions lower-case according to PEP 8, Python style guide.

查看更多
神经病院院长
3楼-- · 2020-07-23 05:37

As @SethMMorton and @ThoestenKranz indicated, numpy has a lot of support for vector manipulation. I don't think there is built-in support in Python to get what you want. However using simple trigonometric functions you can calculate normalize and perpendicular pretty easily using the built-in math module.

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))
查看更多
Melony?
4楼-- · 2020-07-23 05:40

I recommend taking a look at the numpy package. It has many built-in fast math operations. You can use norm and cross as starting points for Normalize and Perpendicular, respectively.

查看更多
登录 后发表回答