Skip to content

Instantly share code, notes, and snippets.

@ychaouche
Created December 2, 2012 13:29
Show Gist options
  • Select an option

  • Save ychaouche/4188671 to your computer and use it in GitHub Desktop.

Select an option

Save ychaouche/4188671 to your computer and use it in GitHub Desktop.
geomtery.py
class Line :
def __init__(self,point = None,vector = None,A = None,B = None) :
""" Parametric equations are fine """
if not A == None and not B == None :
self.vector = Vector(point = B-A)
## self.vector.normalize()
self.point = A
elif not point == None and not vector == None :
self.vector = vector
## self.vector.normalize()
self.point = point
else :
raise "Creation of a line need either a Vector and a Point, or two Points "
def pointOnLine(self,point):
""" tests if a point is on the line"""
if not point :
return False
if point == self.point:
return True
v = Vector(vector = self.vector)
v.normalize()
vn = Vector(point = point-self.point)
vn.normalize()
d1 = [ abs(round (i,15)) for i in v.direction ]
d2 = [ abs(round(i,15)) for i in vn.direction ]
if d1 == d2 :
return True
else :
return False
def intersect(self,line):
""" returns the intersection point with line if any, or None. Line must be on the same plane as self \
only 2d Lines are accepted in fact...
"""
linePointVector = Vector(point = line.point)
selfPointVector = Vector(point = self.point)
vn = line.vector.normal()
dotProd3 = self.vector.dotProduct(vn)
if dotProd3 == 0 :
return None,None
dotProd1 = linePointVector.dotProduct(vn)
dotProd2 = selfPointVector.dotProduct(vn)
t = (dotProd1 - dotProd2) / dotProd3
print 't = ',t
coord = [ i + j * t for i,j in zip(self.point.coord,self.vector.direction)]
print 'point at ',coord
return Point(coord = coord),t
class Point :
def __init__(self,x=0,y=0,z=0,coord=None):
if not coord == None :
self.coord = coord
else :
self.coord = [x,y,z]
def getCoordinates(self):
return self.coord
def __iadd__(self,p):
self.coord = [ i + j for i,j in zip (self.coord,p.coord)]
return self
def __add__(self,p):
return Point(coord= [ i + j for i,j in zip (self.coord,p.coord)])
def __isub__(self,p):
self.coord = [ i - j for i,j in zip (self.coord,p.coord)]
return self
def __sub__(self,p):
return Point(coord= [ i - j for i,j in zip (self.coord,p.coord)])
def __mul__(self,k):
return Point(coord= [ k * i for i in self.coord])
def __imul__(self,k):
self.coord = [ k * i for i in self.coord]
return self
def __eq__(self,point):
if point == None :
return False
else :
if self.coord == point.coord :
return True
else :
return False
class Vector:
def __init__ (self,x=None,y=None,z=None,point=None,vector = None,
rxdeg = None,rydeg =None,rzdeg =None,rxrad =None,ryrad = None,rzrad = None):
self.sinrotationx = None
self.cosrotationx = None
self.cosrotationy = None
self.sinrotationy = None
self.sinrotationz = None
self.cosrotaionz = None
self.direction = None
self.rotationx = 0
self.rotationz = 0
self.rotationy = 0
self.module = 0
if not point == None :
#if passing a point as argument
self.sinrotationx = point.coord[Y]
self.sinrotationy = point.coord[X]
self.cosrotationy = point.coord[Z]
self.direction = list(point.coord)
elif not (vector == None) :
self.sinrotationx = vector.direction[Y]
self.sinrotationy = vector.direction[X]
self.cosrotationy = vector.direction[Z]
self.direction = list(vector.direction)
elif not (x == None and y == None and z == None) :
try:
#if passing a list as argument
t = x[1]
self.direction = x
##print 'list of coord'
except:
#if not passing a list as argument
## print 'single coordinates'
##print x,y,z
self.direction = [x,y,z]
else :
if not rxdeg == None:
self.rotationx= radians(rxdeg)
elif not rxrad == None:
self.rotationx= rxrad
if not rydeg == None:
self.rotationy = radians(rydeg)
elif not ryrad == None:
self.rotationy = ryrad
if not rzdeg == None:
self.rotationz = radians(rzdeg)
elif not rzrad == None :
self.rotationz = rzrad
self.setRotation(rxrad = self.rotationx,ryrad = self.rotationy, rzrad = self.rotationz)
self.__module()
def getRotations(self):
""" return the tuple (rx,ry,rz) """
return self.rotationx,self.rotationy,self.rotationz
def getDirectionVector(self):
""" returns the direction component of the direction vector"""
return self.direction
def getDirectionTrigo(self):
""" return sinrx,sinry,sinrz,cosrx,cosry,cosrz"""
return self.sinrotationx,self.sinrotationy,self.sinrotationz,\
self.cosrotationx,self.cosrotationy,self.cosrotationz
def setDirection(self,direction = None):
if direction == None :
self.direction = [self.sinrotationy,self.sinrotationx,self.cosrotationy]
else:
self.direction = direction
self.__module()
def setRotation(self,rxdeg = None,rxrad = None,rydeg = None,ryrad = None,rzdeg= None,rzrad = None):
"""set angles and their sinus/cosinus and update the direction """
rx,ry,rz = None,None,None
if (not rxdeg == None) :
rx = radians(rxdeg)
elif(not rxrad == None):
rx = rxrad
if(not rydeg == None):
ry = radians(rydeg)
elif(not ryrad == None):
ry = ryrad
if(not rzdeg == None):
rz = radians(rzdeg)
elif(not rzrad == None):
rz = rzrad
if(not rx == None):
self.rotationx = rx
self.sinrotationx = sin(rx)
self.cosrotationx = cos(rx)
if(not ry == None ):
self.rotationy = ry
self.sinrotationy = sin(ry)
self.cosrotationy = cos(ry)
if(not rz == None ):
self.rotationz = rz
self.sinrotationz = sin(rz)
self.cosrotationz = cos(rz)
self.direction = [self.sinrotationy,self.sinrotationx,self.cosrotationy]
def dotProduct(self,p) :
return sum([i*j for i,j in zip (self.direction,p.direction)])
def crossProduct(self,p) :
return Vector([(self.direction[i] * p.direction[(i+1) % 3]) - ( self.direction[(i+1)%3] * p.direction[i])
for i in (1,2,0)])
def normal(self):
""" this is only for 2D Vectors on plan y = 0"""
return Vector(x = -self.direction[Z],y = 0,z = self.direction[X])
def __module (self) :
self.module = sqrt(abs(self.dotProduct(self)))
## if not self.module :
## raise "Error, NULL Vector"
def normalize(self):
self *= (1.0/self.module)
def cos(self,p) :
return self.dotProduct(p) / (self.module * p.module)
def sin(self,p) :
return self.crossProduct(p).module / (self.module * p.module)
def projection(self):
""" axis must be an enum : X,Y or Z"""
rotationz = atan2(self.direction[Y],self.direction[Z])
rotationy = atan2(self.direction[Z],self.direction[X])
projectionOnZ0 = Vector(self.direction[X],0,self.direction[Z])
projectionModule = projectionOnZ0.module
rotationx = atan2(self.direction[Y],projectionModule)
return rotationx,rotationy,rotationz
def __eq__(self,vector):
if vector == None :
return False
for i,j in zip(self.direction,vector.direction):
if not i == j :
return False
return True
def __sub__(self,vector):
return Vector( [ i-j for i,j in zip(self.direction,vector.direction) ] )
def __isub__(self,vector):
self.setDirection( [ i-j for i,j in zip(self.direction,vector.direction) ] )
return self
def __iadd__(self,vector):
self.setDirection( [ i+j for i,j in zip(self.direction,vector.direction) ] )
return self
def __add__(self,vector):
return Vector( [i+j for i,j in zip(self.direction,vector.direction) ] )
def __imul__(self,k):
d = [i*k for i in self.direction ]
self.setDirection ([i*k for i in self.direction])
return self
def __mul__(self,k):
self = Vector([i*k for i in self.direction])
return self
def rotateRight(self,deg=0,rad=0):
if (deg) :
angle = radians(deg)
else :
angle = rad
self.setRotation(ryrad = self.rotationy - angle)
def rotateLeft(self,deg=0,rad = 0):
if (deg) :
angle = radians(deg)
else :
angle = rad
self.setRotation(ryrad =( self.rotationy + angle))
def rotateUp(self, deg=0, rad=0):
if (deg) :
angle = radians(deg)
else :
angle = rad
self.setRotation(rxrad = self.rotationx + angle)
def rotateDown(self,deg=0, rad=0):
if (deg) :
angle = radians(deg)
else:
angle = rad
self.setRotation(rxrad = self.rotationx - angle)
def leanLeft (self, deg=0, rad=0):
if(deg):
angle = radians(deg)
elif(rad):
angle = rad
self.setRotation(rzrad = self.rotationz - angle)
def leanRight (self, deg=0, rad=0):
if(deg):
angle = radians(deg)
elif(rad):
angle = rad
self.setRotation(rzrad = self.rotationz + angle)
class Arrow(Vector,Point):
def __init__(self,x=0,y=0,z=0,coord=None,
rxdeg = None,rydeg =None,rzdeg =None,rxrad =None,ryrad = None,rzrad = None):
Vector.__init__(self,rxdeg=rxdeg,rydeg=rydeg,rxrad=rxrad,ryrad=ryrad,rzdeg=rzdeg,rzrad=rzrad)
Point.__init__(self,x=x,y=y,z=z,coord=coord)
def foreward(self,step=1) :
self.coord[Y] += self.sinrotationx * step
self.coord[Z] += self.cosrotationy * step * self.cosrotationx
self.coord[X] += self.sinrotationy * step * self.cosrotationx
def backward(self,step=1) :
# could have been :
# def backward(self,step = 1) :
# self.foreward(-step)
# but this way you save a function call to foreward.
self.coord[Y] -= self.sinrotationx * step
self.coord[Z] -= self.cosrotationy * step * self.cosrotationx
self.coord[X] -= self.sinrotationy * step * self.cosrotationx
def moveTo(self,x,y,z) :
self.coord[X] = x
self.coord[Y] = y
self.coord[Z] = z
def strafeForeward(self,step=1) :
self.coord[Z] += self.cosrotationy * step
self.coord[X] += self.sinrotationy * step
def strafeBackward(self,step=1) :
# could have been :
# def backward(self,step = 1) :
# self.foreward(-step)
# but this way you save a function call to foreward.
self.coord[Z] -= self.cosrotationy * step
self.coord[X] -= self.sinrotationy * step
def strafeLeft(self,step=1):
## if self.tailedTarget :
## self.rotyToTailedTarget -= angle
##
self.coord[Z] -= self.sinrotationy * step
self.coord[X] += self.cosrotationy * step
def strafeRight(self,step=1):
## if self.tailedTarget :
## self.rotyToTailedTarget -= angle
self.coord[Z] += self.sinrotationy * step
self.coord[X] -= self.cosrotationy * step
def goUp(self,step=1):
self.coord[Y] +=step
def goDown(self,step=1):
self.coord[Y] -=step
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment