/[escript]/trunk/pycad/py_src/transformations.py
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 916 - (show annotations)
Fri Dec 15 08:25:57 2006 UTC (12 years, 10 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 http://www.access.edu.au
18 Primary Business: Queensland, Australia"""
19 __license__="""Licensed under the Open Software License version 3.0
20 http://www.opensource.org/licenses/osl-3.0.php"""
21 __url__="http://www.iservo.edu.au/esys/escript"
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

  ViewVC Help
Powered by ViewVC 1.1.26