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