Created
December 2, 2012 13:29
-
-
Save ychaouche/4188671 to your computer and use it in GitHub Desktop.
geomtery.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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