# Contents of /trunk/pycad/py_src/transformations.py

Revision 916 - (show annotations)
Fri Dec 15 08:25:57 2006 UTC (14 years, 9 months ago) by gross
File MIME type: text/x-python
File size: 4466 byte(s)
```curves implemenred and tested.
```
 1 # \$Id:\$ 2 """ 3 transformations 4 5 @var __author__: name of author 6 @var __copyright__: copyrights 7 @var __license__: licence agreement 8 @var __url__: url entry point on documentation 9 @var __version__: version 10 @var __date__: date of the version 11 @var DEG: unit of degree 12 @var RAD: unit of radiant 13 """ 14 15 __author__="Lutz Gross, l.gross@uq.edu.au" 16 __copyright__=""" Copyright (c) 2006 by ACcESS MNRF 17 18 Primary Business: Queensland, Australia""" 19 __license__="""Licensed under the Open Software License version 3.0 20 21 __url__= 22 __version__="\$Revision:\$" 23 __date__="\$Date:\$" 24 25 import numarray 26 import math 27 28 _TYPE=numarray.Float64 29 DEG=math.pi/180. 30 RAD=1. 31 class Transformation(object): 32 """ 33 general class to define an affine transformation x->Ax+b 34 """ 35 def __init__(self): 36 """ 37 create a linear transformation 38 """ 39 pass 40 def __call__(self,x=numarray.zeros((3,))): 41 """ 42 applies transformation to x 43 """ 44 raise NotImplementeError() 45 class Translation(Transformation): 46 """ 47 defines a translation x->x+b 48 """ 49 def __init__(self,b=numarray.zeros((3,),type=_TYPE)): 50 """ 51 create linear transformation x->x+b 52 """ 53 super(Translation, self).__init__() 54 self.__b=numarray.array(b,_TYPE) 55 def __call__(self,x=numarray.zeros((3,))): 56 """ 57 applies translation to x 58 """ 59 return numarray.array(x,_TYPE)+self.__b 60 class Rotatation(Transformation): 61 """ 62 defines a rotation 63 """ 64 def __init__(self,axis=numarray.zeros((3,),type=_TYPE),point=numarray.ones((3,),type=_TYPE),angle=0.*RAD): 65 """ 66 creates a rotation using an axis and a point on the axis 67 """ 68 self.__axis=numarray.array(axis,type=_TYPE) 69 self.__point=numarray.array(point,type=_TYPE) 70 lax=numarray.dot(self.__axis,self.__axis) 71 if not lax>0: 72 raise ValueError("points must be distinct.") 73 self.__axis/=math.sqrt(lax) 74 self.__angle=float(angle) 75 def __call__(self,x=numarray.zeros((3,))): 76 """ 77 applies rotatation to x 78 """ 79 x=numarray.array(x,_TYPE) 80 z=x-self.__point 81 z0=numarray.dot(z,self.__axis) 82 z_per=z-z0*self.__axis 83 lz_per=numarray.dot(z_per,z_per) 84 if lz_per>0: 85 axis1=z_per/math.sqrt(lz_per) 86 axis2=_cross(axis1,self.__axis) 87 lax2=numarray.dot(axis2,axis2) 88 if lax2>0: 89 axis2/=math.sqrt(lax2) 90 return z0*self.__axis+math.sqrt(lz_per)*(math.cos(self.__angle)*axis1-math.sin(self.__angle)*axis2)+self.__point 91 else: 92 return x 93 else: 94 return x 95 def _cross(x, y): 96 """ 97 Returns the cross product of x and y 98 """ 99 return numarray.array([x[1] * y[2] - x[2] * y[1], x[2] * y[0] - x[0] * y[2], x[0] * y[1] - x[1] * y[0]], _TYPE) 100 101 class Dilation(Transformation): 102 """ 103 defines a dilation 104 """ 105 def __init__(self,factor=1.,center=numarray.zeros((3,),type=_TYPE)): 106 """ 107 creates a dilation with a center an a given expansion/contraction factor 108 """ 109 if not abs(factor)>0: 110 raise ValueError("factor must be non-zero.") 111 self.__factor=factor 112 self.__center=numarray.array(center,type=_TYPE) 113 def __call__(self,x=numarray.zeros((3,))): 114 """ 115 applies dilation to x 116 """ 117 x=numarray.array(x,_TYPE) 118 return self.__factor*(x-self.__center)+self.__center 119 120 class Reflection(Transformation): 121 """ 122 defines a reflection on a plain 123 """ 124 def __init__(self,normal=numarray.ones((3,),type=_TYPE),offset=0.): 125 """ 126 defines a reflection on a plain defined in normal form 127 """ 128 self.__normal=numarray.array(normal,type=_TYPE) 129 ln=math.sqrt(numarray.dot(self.__normal,self.__normal)) 130 if not ln>0.: 131 raise ValueError("normal must have positive length.") 132 self.__normal/=ln 133 if isinstance(offset,float) or isinstance(offset,int): 134 self.__offset=offset/ln 135 else: 136 self.__offset=numarray.dot(numarray.array(offset,type=_TYPE),self.__normal) 137 def __call__(self,x=numarray.zeros((3,))): 138 """ 139 applies reflection to x 140 """ 141 x=numarray.array(x,_TYPE) 142 return x - 2*(numarray.dot(x,self.__normal)-self.__offset)*self.__normal