| 1 |
#!/usr/bin/env python |
|---|
| 2 |
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 3 |
##~ License |
|---|
| 4 |
##~ |
|---|
| 5 |
##- The RuneBlade Foundation library is intended to ease some |
|---|
| 6 |
##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.) |
|---|
| 7 |
##- applications, while providing the flexibility to modularly change the |
|---|
| 8 |
##- architecture. Enjoy. |
|---|
| 9 |
##~ |
|---|
| 10 |
##~ Copyright (C) 2002 TechGame Networks, LLC. |
|---|
| 11 |
##~ |
|---|
| 12 |
##~ This library is free software; you can redistribute it and/or |
|---|
| 13 |
##~ modify it under the terms of the BSD style License as found in the |
|---|
| 14 |
##~ LICENSE file included with this distribution. |
|---|
| 15 |
##~ |
|---|
| 16 |
##~ TechGame Networks, LLC can be reached at: |
|---|
| 17 |
##~ 3578 E. Hartsel Drive #211 |
|---|
| 18 |
##~ Colorado Springs, Colorado, USA, 80920 |
|---|
| 19 |
##~ |
|---|
| 20 |
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 21 |
|
|---|
| 22 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 23 |
#~ Imports |
|---|
| 24 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 25 |
|
|---|
| 26 |
import math |
|---|
| 27 |
import Numeric |
|---|
| 28 |
import LinearAlgebra |
|---|
| 29 |
from Vector import * |
|---|
| 30 |
|
|---|
| 31 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 32 |
#~ Definitions |
|---|
| 33 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 34 |
|
|---|
| 35 |
class TransformPrimitive3dh(object): |
|---|
| 36 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 37 |
#~ Constants / Variables / Etc. |
|---|
| 38 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 39 |
|
|---|
| 40 |
NumericType = Numeric.Float |
|---|
| 41 |
|
|---|
| 42 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 43 |
#~ Public Methods |
|---|
| 44 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 45 |
|
|---|
| 46 |
def asArray4x4(self): |
|---|
| 47 |
"""Returns the transformation in 4x4 Numeric array form. |
|---|
| 48 |
""" |
|---|
| 49 |
return Numeric.identity(4) |
|---|
| 50 |
|
|---|
| 51 |
def asInverse4x4(self): |
|---|
| 52 |
"""Returns the inverse transformation in 4x4 Numeric array form. |
|---|
| 53 |
""" |
|---|
| 54 |
return LinearAlgebra.inverse(self.asArray4x4()) |
|---|
| 55 |
|
|---|
| 56 |
def Collapse(self): |
|---|
| 57 |
return Matrix(self.asArray3x3()) |
|---|
| 58 |
|
|---|
| 59 |
def __mul__(self, other): |
|---|
| 60 |
if isinstance(other, TransformPrimitive3dh): |
|---|
| 61 |
return Composite([self, other]) |
|---|
| 62 |
elif isinstance(other, Numeric.ArrayType): |
|---|
| 63 |
return Numeric.dot(self.asArray4x4(), other) |
|---|
| 64 |
else: return self.asArray4x4() * other |
|---|
| 65 |
|
|---|
| 66 |
def __rmul__(self, other): |
|---|
| 67 |
if isinstance(other, TransformPrimitive3dh): |
|---|
| 68 |
return Composite([other, self]) |
|---|
| 69 |
elif isinstance(other, Numeric.ArrayType): |
|---|
| 70 |
return Numeric.dot(other, self.asArray4x4()) |
|---|
| 71 |
else: return other * self.asArray4x4() |
|---|
| 72 |
|
|---|
| 73 |
def asPoints(self, points, includeDimRestore=False): |
|---|
| 74 |
dims = len(points[0]) |
|---|
| 75 |
if dims not in (2,3,4): |
|---|
| 76 |
raise ValueError, "Points are not of right dimension -- must be 2, 3 or 4, but found %d" % dims |
|---|
| 77 |
if dims == 2: |
|---|
| 78 |
ones = Numeric.ones((len(points), 1), self.NumericType) |
|---|
| 79 |
zeros = Numeric.zeros((len(points), 1), self.NumericType) |
|---|
| 80 |
points = Numeric.concatenate((points, zeros, ones), 1) |
|---|
| 81 |
correctdims = lambda pts: pts[:,:-2] # trim the z and homogenous coordinates -- assumes that they are all still 1. |
|---|
| 82 |
elif dims == 3: |
|---|
| 83 |
# add the homogeneous coordinate |
|---|
| 84 |
ones = Numeric.ones((len(points), 1), self.NumericType) |
|---|
| 85 |
points = Numeric.concatenate((points, ones), 1) |
|---|
| 86 |
correctdims = lambda pts: pts[:,:-1] # trim the homogenous coordinate -- assumes that they are all still 1. |
|---|
| 87 |
else: |
|---|
| 88 |
correctdims = lambda pts: pts |
|---|
| 89 |
|
|---|
| 90 |
if includeDimRestore: |
|---|
| 91 |
return points, correctdims |
|---|
| 92 |
else: return points |
|---|
| 93 |
|
|---|
| 94 |
def TransformPoints(self, points, bInverse=False): |
|---|
| 95 |
if bInverse: |
|---|
| 96 |
matrix = self.asInverse4x4() |
|---|
| 97 |
else: |
|---|
| 98 |
matrix = self.asArray4x4() |
|---|
| 99 |
|
|---|
| 100 |
points, correctdims = self.asPoints(points, True) |
|---|
| 101 |
result = Numeric.transpose(Numeric.dot(matrix, Numeric.transpose(points))) |
|---|
| 102 |
return correctdims(result) |
|---|
| 103 |
|
|---|
| 104 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 105 |
|
|---|
| 106 |
class Composite(TransformPrimitive3dh): |
|---|
| 107 |
""" |
|---|
| 108 |
# Non-sensical test -- detects changes more than anything |
|---|
| 109 |
>>> from Projections import * |
|---|
| 110 |
>>> c = Composite() |
|---|
| 111 |
>>> n = c.Add(Identity()) |
|---|
| 112 |
>>> n = c.Add(Translate((1,2,3))) |
|---|
| 113 |
>>> n = c.Add(Scale((2,3,4))) |
|---|
| 114 |
>>> n = c.Add(Rotate(23, (7,11,13))) |
|---|
| 115 |
>>> c |
|---|
| 116 |
<Composite: [<Identity>, <Translation: [1.0, 2.0, 3.0, 1.0]>, <Scale: [2.0, 3.0, 4.0, 1.0]>, <Rotation: Angle=23.0, Axis=[0.38018780946731567, 0.59743797779083252, 0.70606309175491333, 1.0]>] > |
|---|
| 117 |
>>> c.Inverse() |
|---|
| 118 |
<Composite: [<Rotation: Angle=23.0, Axis=[-0.38018780946731567, -0.59743797779083252, -0.70606309175491333, 1.0]>, <Scale: [0.5, 0.3333333432674408, 0.25, 1.0]>, <Translation: [-1.0, -2.0, -3.0, 1.0]>, <Identity>] > |
|---|
| 119 |
>>> (c * c.Inverse()).asArray4x4() |
|---|
| 120 |
array([[ 9.99999999e-001, 1.24926286e-010, 1.19565441e-010, 1.52539981e-010], |
|---|
| 121 |
[ 2.81084066e-010, 1.00000003e+000, -1.15097085e-009, -5.50221717e-008], |
|---|
| 122 |
[ 4.78261764e-010, -2.04617046e-009, 9.99999998e-001, 8.76708395e-009], |
|---|
| 123 |
[ 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 1.00000000e+000]]) |
|---|
| 124 |
>>> n = c.Add(Skew(2,3,4,5,6,7)) |
|---|
| 125 |
>>> n = c.Add(Shear(10,20,30,40,50,60)) |
|---|
| 126 |
>>> n = c.Add(Orthographic()) |
|---|
| 127 |
>>> n = c.Add(Frustum()) |
|---|
| 128 |
>>> n = c.Add(Perspective()) |
|---|
| 129 |
>>> c.asArray4x4()[0][0] |
|---|
| 130 |
44.29636824137652 |
|---|
| 131 |
>>> c.asInverse4x4()[0][0] |
|---|
| 132 |
-0.010173620849422499 |
|---|
| 133 |
""" |
|---|
| 134 |
|
|---|
| 135 |
def __init__(self, collection=[]): |
|---|
| 136 |
self.collection = collection[:] |
|---|
| 137 |
|
|---|
| 138 |
def __repr__(self): |
|---|
| 139 |
return "<Composite: %s >" % self.collection |
|---|
| 140 |
|
|---|
| 141 |
def __contains__(self, *args, **kw): |
|---|
| 142 |
return self.collection.__contains__(self, *args, **kw) |
|---|
| 143 |
def __iter__(self): |
|---|
| 144 |
return iter(self.collection) |
|---|
| 145 |
def __len__(self): |
|---|
| 146 |
return len(self.collection) |
|---|
| 147 |
def __getitem__(self, *args, **kw): |
|---|
| 148 |
return self.collection.__getitem__(*args, **kw) |
|---|
| 149 |
def __setitem__(self, *args, **kw): |
|---|
| 150 |
return self.collection.__setitem__(*args, **kw) |
|---|
| 151 |
def __delitem__(self, *args, **kw): |
|---|
| 152 |
return self.collection.__delitem__(*args, **kw) |
|---|
| 153 |
|
|---|
| 154 |
def __imul__(self, other): |
|---|
| 155 |
if isinstance(other, TransformPrimitive3dh): |
|---|
| 156 |
if isinstance(other, Composite): |
|---|
| 157 |
self.collection.extend(other.collection) |
|---|
| 158 |
else: |
|---|
| 159 |
self.collection.append(other) |
|---|
| 160 |
return self |
|---|
| 161 |
else: |
|---|
| 162 |
raise TypeError, "Can only inline multiply with other TransformPrimitive3dh" |
|---|
| 163 |
|
|---|
| 164 |
def __mul__(self, other): |
|---|
| 165 |
if isinstance(other, TransformPrimitive3dh): |
|---|
| 166 |
if isinstance(other, Composite): |
|---|
| 167 |
return Composite(self.collection + other.collection) |
|---|
| 168 |
else: |
|---|
| 169 |
return Composite(self.collection + [other]) |
|---|
| 170 |
else: TransformPrimitive3dh.__mul__(self, other) |
|---|
| 171 |
|
|---|
| 172 |
def __rmul__(self, other): |
|---|
| 173 |
if isinstance(other, TransformPrimitive3dh): |
|---|
| 174 |
if isinstance(other, Composite): |
|---|
| 175 |
return Composite(other.collection + self.collection) |
|---|
| 176 |
else: |
|---|
| 177 |
return Composite([other] + self.collection) |
|---|
| 178 |
else: TransformPrimitive3dh.__rmul__(self, other) |
|---|
| 179 |
|
|---|
| 180 |
def Add(self, Transform): |
|---|
| 181 |
assert isinstance(Transform, TransformPrimitive3dh) |
|---|
| 182 |
self.collection.append(Transform) |
|---|
| 183 |
return self.collection[-1] |
|---|
| 184 |
Append=Add |
|---|
| 185 |
|
|---|
| 186 |
def Insert(self, idx, Transform): |
|---|
| 187 |
self.collection.insert(idx, Transform) |
|---|
| 188 |
return self.collection[idx] |
|---|
| 189 |
|
|---|
| 190 |
def Clear(self): |
|---|
| 191 |
self.collection[:] = [] |
|---|
| 192 |
|
|---|
| 193 |
def asArray4x4(self): |
|---|
| 194 |
"""Returns the transformation in 4x4 Numeric array form""" |
|---|
| 195 |
r = Numeric.identity(4, self.NumericType) |
|---|
| 196 |
for xform in self.collection: |
|---|
| 197 |
r = Numeric.dot(r, xform.asArray4x4()) |
|---|
| 198 |
return r |
|---|
| 199 |
|
|---|
| 200 |
def Inverse(self): |
|---|
| 201 |
result = self.__class__() |
|---|
| 202 |
result.collection = [x.Inverse() for x in self.collection] |
|---|
| 203 |
result.collection.reverse() |
|---|
| 204 |
return result |
|---|
| 205 |
|
|---|
| 206 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 207 |
|
|---|
| 208 |
class Matrix(TransformPrimitive3dh): |
|---|
| 209 |
""" |
|---|
| 210 |
>>> a = Numeric.arange(1, 17) |
|---|
| 211 |
>>> a.shape = 4,4 |
|---|
| 212 |
>>> m = Matrix(a) |
|---|
| 213 |
>>> m |
|---|
| 214 |
<Matrix: [[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0], [13.0, 14.0, 15.0, 16.0]] > |
|---|
| 215 |
>>> m.asArray4x4() |
|---|
| 216 |
array([[ 1., 2., 3., 4.], |
|---|
| 217 |
[ 5., 6., 7., 8.], |
|---|
| 218 |
[ 9., 10., 11., 12.], |
|---|
| 219 |
[ 13., 14., 15., 16.]]) |
|---|
| 220 |
>>> m.asInverse4x4() |
|---|
| 221 |
array([[ 3.94064967e+015, -4.50359963e+015, -2.81474977e+015, 3.37769972e+015], |
|---|
| 222 |
[-4.12829966e+015, 4.50359963e+015, 3.37769972e+015, -3.75299969e+015], |
|---|
| 223 |
[-3.56534971e+015, 4.50359963e+015, 1.68884986e+015, -2.62709978e+015], |
|---|
| 224 |
[ 3.75299969e+015, -4.50359963e+015, -2.25179981e+015, 3.00239975e+015]]) |
|---|
| 225 |
""" |
|---|
| 226 |
|
|---|
| 227 |
def __init__(self, matrix=None): |
|---|
| 228 |
if matrix: self.matrix = Numeric.asarray(matrix, self.NumericType) |
|---|
| 229 |
else: self.matrix = Numeric.identity(4, self.NumericType) |
|---|
| 230 |
assert self.matrix.shape == (4,4) |
|---|
| 231 |
|
|---|
| 232 |
def __repr__(self): |
|---|
| 233 |
return "<Matrix: %s >" % self.matrix.tolist() |
|---|
| 234 |
|
|---|
| 235 |
def __imul__(self, other): |
|---|
| 236 |
if isinstance(other, TransformPrimitive3dh): |
|---|
| 237 |
self.matrix = Numeric.dot(self.matrix, other.asArray4x4()) |
|---|
| 238 |
assert self.matrix.shape == (4,4) |
|---|
| 239 |
return self |
|---|
| 240 |
else: |
|---|
| 241 |
raise TypeError, "Can only inline multiply with other TransformPrimitive3dh" |
|---|
| 242 |
|
|---|
| 243 |
def asArray4x4(self): |
|---|
| 244 |
return self.matrix |
|---|
| 245 |
|
|---|
| 246 |
def Inverse(self): |
|---|
| 247 |
return self.__class__(self.asInverse4x4()) |
|---|
| 248 |
|
|---|
| 249 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 250 |
|
|---|
| 251 |
class Identity(TransformPrimitive3dh): |
|---|
| 252 |
""" |
|---|
| 253 |
>>> i = Identity() |
|---|
| 254 |
>>> i |
|---|
| 255 |
<Identity> |
|---|
| 256 |
>>> i.asArray4x4() |
|---|
| 257 |
array([[ 1., 0., 0., 0.], |
|---|
| 258 |
[ 0., 1., 0., 0.], |
|---|
| 259 |
[ 0., 0., 1., 0.], |
|---|
| 260 |
[ 0., 0., 0., 1.]]) |
|---|
| 261 |
>>> i.asInverse4x4() |
|---|
| 262 |
array([[ 1., 0., 0., 0.], |
|---|
| 263 |
[ 0., 1., 0., 0.], |
|---|
| 264 |
[ 0., 0., 1., 0.], |
|---|
| 265 |
[ 0., 0., 0., 1.]]) |
|---|
| 266 |
|
|---|
| 267 |
>>> i.TransformPoints([(2., 3., 4., 1.)]) |
|---|
| 268 |
array([ [ 2., 3., 4., 1.]]) |
|---|
| 269 |
>>> i.TransformPoints([(2., 3., 4., 1.)], True) |
|---|
| 270 |
array([ [ 2., 3., 4., 1.]]) |
|---|
| 271 |
|
|---|
| 272 |
>>> i.TransformPoints([(2., 3., 4.)]) |
|---|
| 273 |
array([ [ 2., 3., 4.]]) |
|---|
| 274 |
>>> i.TransformPoints([(2., 3., 4.)], True) |
|---|
| 275 |
array([ [ 2., 3., 4.]]) |
|---|
| 276 |
|
|---|
| 277 |
>>> i.TransformPoints([(2., 3.)]) |
|---|
| 278 |
array([ [ 2., 3.]]) |
|---|
| 279 |
>>> i.TransformPoints([(2., 3.)], True) |
|---|
| 280 |
array([ [ 2., 3.]]) |
|---|
| 281 |
""" |
|---|
| 282 |
|
|---|
| 283 |
def __init__(self): |
|---|
| 284 |
pass |
|---|
| 285 |
|
|---|
| 286 |
def __repr__(self): |
|---|
| 287 |
return "<Identity>" |
|---|
| 288 |
|
|---|
| 289 |
def asArray4x4(self): |
|---|
| 290 |
return Numeric.identity(4, self.NumericType) |
|---|
| 291 |
|
|---|
| 292 |
def asInverse4x4(self): |
|---|
| 293 |
return Numeric.identity(4, self.NumericType) |
|---|
| 294 |
|
|---|
| 295 |
def Inverse(self): |
|---|
| 296 |
return self.__class__() |
|---|
| 297 |
|
|---|
| 298 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 299 |
|
|---|
| 300 |
class Translate(TransformPrimitive3dh): |
|---|
| 301 |
""" |
|---|
| 302 |
>>> t = Translate([-1,-2,-3]) |
|---|
| 303 |
>>> t |
|---|
| 304 |
<Translation: [-1.0, -2.0, -3.0, 1.0]> |
|---|
| 305 |
>>> t.asArray4x4() |
|---|
| 306 |
array([[ 1., 0., 0., -1.], |
|---|
| 307 |
[ 0., 1., 0., -2.], |
|---|
| 308 |
[ 0., 0., 1., -3.], |
|---|
| 309 |
[ 0., 0., 0., 1.]]) |
|---|
| 310 |
>>> t.asInverse4x4() |
|---|
| 311 |
array([[ 1., 0., 0., 1.], |
|---|
| 312 |
[ 0., 1., 0., 2.], |
|---|
| 313 |
[ 0., 0., 1., 3.], |
|---|
| 314 |
[ 0., 0., 0., 1.]]) |
|---|
| 315 |
""" |
|---|
| 316 |
|
|---|
| 317 |
Direction = Vector3HProperty('Direction', NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 318 |
|
|---|
| 319 |
def __init__(self, Direction=(0,0,0)): |
|---|
| 320 |
self.Direction = Direction |
|---|
| 321 |
|
|---|
| 322 |
def __repr__(self): |
|---|
| 323 |
return "<Translation: %s>" % (self.Direction.tolist(),) |
|---|
| 324 |
|
|---|
| 325 |
def asArray4x4(self): |
|---|
| 326 |
result = Numeric.identity(4, self.NumericType) |
|---|
| 327 |
result[:, 3] = self.Direction |
|---|
| 328 |
return result |
|---|
| 329 |
|
|---|
| 330 |
def asInverse4x4(self): |
|---|
| 331 |
result = Numeric.identity(4, self.NumericType) |
|---|
| 332 |
result[:, 3] = -self.Direction |
|---|
| 333 |
return result |
|---|
| 334 |
|
|---|
| 335 |
def Inverse(self): |
|---|
| 336 |
return self.__class__(-self.Direction) |
|---|
| 337 |
|
|---|
| 338 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 339 |
|
|---|
| 340 |
class Scale(TransformPrimitive3dh): |
|---|
| 341 |
""" |
|---|
| 342 |
>>> s = Scale([2,3,4]) |
|---|
| 343 |
>>> s |
|---|
| 344 |
<Scale: [2.0, 3.0, 4.0, 1.0]> |
|---|
| 345 |
>>> s.asArray4x4() |
|---|
| 346 |
array([[ 2., 0., 0., 0.], |
|---|
| 347 |
[ 0., 3., 0., 0.], |
|---|
| 348 |
[ 0., 0., 4., 0.], |
|---|
| 349 |
[ 0., 0., 0., 1.]]) |
|---|
| 350 |
>>> s.asInverse4x4() |
|---|
| 351 |
array([[ 0.5 , 0. , 0. , 0. ], |
|---|
| 352 |
[ 0. , 0.33333333, 0. , 0. ], |
|---|
| 353 |
[ 0. , 0. , 0.25 , 0. ], |
|---|
| 354 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 355 |
""" |
|---|
| 356 |
|
|---|
| 357 |
Scale = Vector3HProperty('Scale', (1.,1.,1.,1.), NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 358 |
|
|---|
| 359 |
def __init__(self, Scale=1.0): |
|---|
| 360 |
if not isinstance(Scale, (tuple,list)): |
|---|
| 361 |
# uniform scaling |
|---|
| 362 |
self.Scale = (Scale,) * 3 |
|---|
| 363 |
else: |
|---|
| 364 |
# make sure it is length 3 |
|---|
| 365 |
self.Scale = Scale |
|---|
| 366 |
|
|---|
| 367 |
def __repr__(self): |
|---|
| 368 |
return "<Scale: %s>" % (self.Scale.tolist(),) |
|---|
| 369 |
|
|---|
| 370 |
def asArray4x4(self): |
|---|
| 371 |
result = Numeric.identity(4, self.NumericType) |
|---|
| 372 |
for idx in range(4-1): result[idx,idx] = self.Scale[idx] |
|---|
| 373 |
return result |
|---|
| 374 |
|
|---|
| 375 |
def asInverse4x4(self): |
|---|
| 376 |
result = Numeric.identity(4, self.NumericType) |
|---|
| 377 |
for idx in range(4-1): result[idx,idx] = 1./self.Scale[idx] |
|---|
| 378 |
return result |
|---|
| 379 |
|
|---|
| 380 |
def Inverse(self): |
|---|
| 381 |
return self.__class__([1./x for x in self.Scale]) |
|---|
| 382 |
|
|---|
| 383 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 384 |
|
|---|
| 385 |
class Rotate(TransformPrimitive3dh): |
|---|
| 386 |
""" |
|---|
| 387 |
>>> Rotate(30).asArray4x4() |
|---|
| 388 |
array([[ 0.8660254, -0.5 , 0. , 0. ], |
|---|
| 389 |
[ 0.5 , 0.8660254, 0. , 0. ], |
|---|
| 390 |
[ 0. , 0. , 1. , 0. ], |
|---|
| 391 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 392 |
>>> Rotate(30, [1, 0, 0]).asArray4x4() |
|---|
| 393 |
array([[ 1. , 0. , 0. , 0. ], |
|---|
| 394 |
[ 0. , 0.8660254, -0.5 , 0. ], |
|---|
| 395 |
[ 0. , 0.5 , 0.8660254, 0. ], |
|---|
| 396 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 397 |
>>> Rotate(30, [0, 1, 0]).asArray4x4() |
|---|
| 398 |
array([[ 0.8660254, 0. , 0.5 , 0. ], |
|---|
| 399 |
[ 0. , 1. , 0. , 0. ], |
|---|
| 400 |
[-0.5 , 0. , 0.8660254, 0. ], |
|---|
| 401 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 402 |
>>> Rotate(30, [0, 0, 1]).asArray4x4() |
|---|
| 403 |
array([[ 0.8660254, -0.5 , 0. , 0. ], |
|---|
| 404 |
[ 0.5 , 0.8660254, 0. , 0. ], |
|---|
| 405 |
[ 0. , 0. , 1. , 0. ], |
|---|
| 406 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 407 |
>>> Rotate(37, [2, 3, 5]).asArray4x4() |
|---|
| 408 |
array([[ 0.81983177, -0.45634205, 0.34587252, 0. ], |
|---|
| 409 |
[ 0.51993083, 0.8463271 , -0.11576859, 0. ], |
|---|
| 410 |
[-0.23989122, 0.27474055, 0.93111215, 0. ], |
|---|
| 411 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 412 |
>>> Rotate(37, [2, 3, 5]).asInverse4x4() |
|---|
| 413 |
array([[ 0.81983178, 0.51993083, -0.23989121, 0. ], |
|---|
| 414 |
[-0.45634205, 0.84632711, 0.27474056, 0. ], |
|---|
| 415 |
[ 0.34587252, -0.11576859, 0.93111215, 0. ], |
|---|
| 416 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 417 |
>>> Rotate(37, [1., 2., 3.]).Axis |
|---|
| 418 |
<[0.26726123690605164, 0.53452247381210327, 0.80178368091583252, 1.0]> |
|---|
| 419 |
>>> Rotate(30, [1., 2., 3.]).Angle |
|---|
| 420 |
30.0 |
|---|
| 421 |
>>> Rotate(30, [1., 2., 3.]).Radians |
|---|
| 422 |
0.52359877559829882 |
|---|
| 423 |
>>> Rotate(30, [1., 2., 3.]) |
|---|
| 424 |
<Rotation: Angle=30.0, Axis=[0.26726123690605164, 0.53452247381210327, 0.80178368091583252, 1.0]> |
|---|
| 425 |
>>> a = Rotate(30, [1., 2., 3.]); a |
|---|
| 426 |
<Rotation: Angle=30.0, Axis=[0.26726123690605164, 0.53452247381210327, 0.80178368091583252, 1.0]> |
|---|
| 427 |
>>> ai = a.Inverse(); ai |
|---|
| 428 |
<Rotation: Angle=30.0, Axis=[-0.26726126670837402, -0.53452253341674805, -0.80178374052047729, 1.0]> |
|---|
| 429 |
>>> (a * ai).asArray4x4() |
|---|
| 430 |
array([[ 1.00000000e+000, 2.39797163e-008, -2.63590731e-008, 0.00000000e+000], |
|---|
| 431 |
[-2.55925432e-008, 9.99999998e-001, 9.66679894e-009, 0.00000000e+000], |
|---|
| 432 |
[ 2.70206916e-008, -1.20927169e-008, 1.00000000e+000, 0.00000000e+000], |
|---|
| 433 |
[ 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 1.00000000e+000]]) |
|---|
| 434 |
>>> (ai * a).asArray4x4() |
|---|
| 435 |
array([[ 1.00000000e+000, 2.34966624e-008, -2.58865884e-008, 0.00000000e+000], |
|---|
| 436 |
[-2.60755971e-008, 9.99999999e-001, 1.43609231e-008, 0.00000000e+000], |
|---|
| 437 |
[ 2.35488830e-008, -1.52871791e-008, 1.00000000e+000, 0.00000000e+000], |
|---|
| 438 |
[ 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 1.00000000e+000]]) |
|---|
| 439 |
""" |
|---|
| 440 |
|
|---|
| 441 |
Axis = UnitVector3HProperty('Axis', NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 442 |
|
|---|
| 443 |
def __init__(self, angle=0.0, axis=(0.0, 0.0, 1.0)): |
|---|
| 444 |
self.Angle = float(angle) |
|---|
| 445 |
self.Axis = axis |
|---|
| 446 |
|
|---|
| 447 |
def __repr__(self): |
|---|
| 448 |
return "<Rotation: Angle=%s, Axis=%s>" % (self.Angle, self.Axis.tolist(),) |
|---|
| 449 |
|
|---|
| 450 |
def _getRadians(self): |
|---|
| 451 |
return math.radians(self.Angle) |
|---|
| 452 |
def _setRadians(self, value): |
|---|
| 453 |
self.Angle = math.degrees(value) |
|---|
| 454 |
Radians = property(_getRadians, _setRadians) |
|---|
| 455 |
|
|---|
| 456 |
def asArray4x4(self): |
|---|
| 457 |
u = self.Axis[:-1] |
|---|
| 458 |
uut = Numeric.outerproduct(u, u) |
|---|
| 459 |
M = Numeric.identity(3, self.NumericType) - uut |
|---|
| 460 |
S = Numeric.asarray([[0., -u[2], u[1]], [u[2], 0., -u[0]], [-u[1], u[0], 0.]], self.NumericType) |
|---|
| 461 |
radians = self.Radians |
|---|
| 462 |
R = uut + Numeric.cos(radians) * M + Numeric.sin(radians) * S |
|---|
| 463 |
result = Numeric.identity(4, self.NumericType) |
|---|
| 464 |
result[:3,:3] = R |
|---|
| 465 |
return result |
|---|
| 466 |
|
|---|
| 467 |
def Inverse(self): |
|---|
| 468 |
return self.__class__(self.Angle, -self.Axis) |
|---|
| 469 |
|
|---|
| 470 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 471 |
|
|---|
| 472 |
class LookAt(TransformPrimitive3dh): |
|---|
| 473 |
""" |
|---|
| 474 |
>>> l = LookAt((13.,-12.,11.), (1.,2.,3.), (1.,1.,1.)); l |
|---|
| 475 |
<LookAt: Center=[1.0, 2.0, 3.0] Eye=[13.0, -12.0, 11.0] Up=[0.57735025882720947, 0.57735025882720947, 0.57735025882720947]> |
|---|
| 476 |
>>> l.asArray4x4() |
|---|
| 477 |
array([[ 0.64153302, 0.11664237, -0.75817537, 1.39970833], |
|---|
| 478 |
[ 0.4816635 , 0.70798737, 0.51648253, -3.44708487], |
|---|
| 479 |
[ 0.59702235, -0.69652605, 0.3980149 , -20.49776715], |
|---|
| 480 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 481 |
""" |
|---|
| 482 |
|
|---|
| 483 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 484 |
#~ Constants / Variables / Etc. |
|---|
| 485 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 486 |
|
|---|
| 487 |
Eye = Vector3Property('Eye', (0.,0.,1.), NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 488 |
Center = Vector3Property('Center', (0.,0.,0.), NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 489 |
Up = UnitVector3Property('Up', (0.,1.,0.), NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 490 |
|
|---|
| 491 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 492 |
#~ Public Methods |
|---|
| 493 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$ |
|---|
| 494 |
|
|---|
| 495 |
def __init__(self, Eye=None, Center=None, Up=None): |
|---|
| 496 |
TransformPrimitive3dh.__init__(self) |
|---|
| 497 |
if Eye is not None: self.Eye = Eye |
|---|
| 498 |
if Center is not None: self.Center = Center |
|---|
| 499 |
if Up is not None: self.Up = Up |
|---|
| 500 |
|
|---|
| 501 |
def __repr__(self): |
|---|
| 502 |
return "<LookAt: Center=%s Eye=%s Up=%s>" % (self.Center.tolist(), self.Eye.tolist(), self.Up.tolist()) |
|---|
| 503 |
|
|---|
| 504 |
def asArray4x4(self): |
|---|
| 505 |
E = self.Eye |
|---|
| 506 |
C = self.Center |
|---|
| 507 |
U = self.Up |
|---|
| 508 |
L = C - E |
|---|
| 509 |
L.iNormalize() |
|---|
| 510 |
S = L.Cross3(U) |
|---|
| 511 |
S.iNormalize() |
|---|
| 512 |
U_ = S.Cross3(L) |
|---|
| 513 |
|
|---|
| 514 |
result = Numeric.identity(4, self.NumericType) |
|---|
| 515 |
result[0,:-1] = S |
|---|
| 516 |
result[1,:-1] = U_ |
|---|
| 517 |
result[2,:-1] = -L |
|---|
| 518 |
xlate = Numeric.identity(4, self.NumericType) |
|---|
| 519 |
xlate[:-1,3] = -E |
|---|
| 520 |
return Numeric.dot(result, xlate) |
|---|
| 521 |
|
|---|
| 522 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 523 |
|
|---|
| 524 |
class SphericalLookAt(LookAt): |
|---|
| 525 |
""" |
|---|
| 526 |
>>> s = SphericalLookAt((10.,45.,45.)); s |
|---|
| 527 |
<Spherical LookAt: Center=[0.0, 0.0, 0.0] RhoThetaPhi=(10.0, 45.0, 45.0) Up=[0.0, 1.0, 0.0]> |
|---|
| 528 |
>>> s.asArray4x4() |
|---|
| 529 |
array([[ 7.07106769e-001, 0.00000000e+000, -7.07106769e-001, 0.00000000e+000], |
|---|
| 530 |
[-4.99999970e-001, 7.07106769e-001, -4.99999970e-001, -2.11174211e-007], |
|---|
| 531 |
[ 5.00000000e-001, 7.07106769e-001, 5.00000000e-001, -9.99999991e+000], |
|---|
| 532 |
[ 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 1.00000000e+000]]) |
|---|
| 533 |
>>> s.Eye |
|---|
| 534 |
<[5.0, 7.0710678100585937, 5.0]> |
|---|
| 535 |
""" |
|---|
| 536 |
|
|---|
| 537 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 538 |
#~ Constants / Variables / Etc. |
|---|
| 539 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 540 |
|
|---|
| 541 |
_RhoThetaPhi = 1., 0., 90 |
|---|
| 542 |
Center = Vector3Property('Center', (0.,0.,0.), NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 543 |
Spherical = Vector3Property('Spherical', (0.,0.,1.), NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 544 |
Up = UnitVector3Property('Up', (0.,1.,0.), NumericType=TransformPrimitive3dh.NumericType) |
|---|
| 545 |
|
|---|
| 546 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 547 |
#~ Public Methods |
|---|
| 548 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 549 |
|
|---|
| 550 |
def __init__(self, RhoThetaPhi=None, Center=None, Up=None): |
|---|
| 551 |
LookAt.__init__(self, None, Center=Center, Up=Up) |
|---|
| 552 |
if RhoThetaPhi is not None: self.RhoThetaPhi = RhoThetaPhi |
|---|
| 553 |
|
|---|
| 554 |
def __repr__(self): |
|---|
| 555 |
return "<Spherical LookAt: Center=%s RhoThetaPhi=%s Up=%s>" % (self.Center.tolist(), self.RhoThetaPhi, self.Up.tolist()) |
|---|
| 556 |
|
|---|
| 557 |
def _SetRhoThetaPhi(self, (row,theta,fi)): |
|---|
| 558 |
self._RhoThetaPhi = row,theta,fi |
|---|
| 559 |
rowsinfi = row*Numeric.sin(fi) |
|---|
| 560 |
x,y,z = (rowsinfi*Numeric.cos(theta),row*Numeric.cos(fi),rowsinfi*Numeric.sin(theta)) |
|---|
| 561 |
self.Spherical = x,y,z |
|---|
| 562 |
def _GetRhoThetaPhi(self): |
|---|
| 563 |
return self._RhoThetaPhi |
|---|
| 564 |
RhoThetaPhiRadians = property(_GetRhoThetaPhi, _SetRhoThetaPhi) |
|---|
| 565 |
|
|---|
| 566 |
def _SetRhoThetaPhi(self, (row,theta,fi)): |
|---|
| 567 |
self.RhoThetaPhiRadians = row, math.radians(theta), math.radians(fi) |
|---|
| 568 |
def _GetRhoThetaPhi(self): |
|---|
| 569 |
row, theta, fi = self.RhoThetaPhiRadians |
|---|
| 570 |
return row, math.degrees(theta), math.degrees(fi) |
|---|
| 571 |
RhoThetaPhi = property(_GetRhoThetaPhi, _SetRhoThetaPhi) |
|---|
| 572 |
|
|---|
| 573 |
def _GetEye(self): |
|---|
| 574 |
return self.Center + self.Spherical |
|---|
| 575 |
Eye = property(_GetEye) |
|---|
| 576 |
|
|---|
| 577 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 578 |
|
|---|
| 579 |
class Shear(Matrix): |
|---|
| 580 |
""" |
|---|
| 581 |
>>> s = Shear(1,2,3,4,5,6) |
|---|
| 582 |
>>> s |
|---|
| 583 |
<Shear: [[1.0, 1.0, 2.0, 0.0], [3.0, 1.0, 4.0, 0.0], [5.0, 6.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]] > |
|---|
| 584 |
>>> s.asArray4x4() |
|---|
| 585 |
array([[ 1., 1., 2., 0.], |
|---|
| 586 |
[ 3., 1., 4., 0.], |
|---|
| 587 |
[ 5., 6., 1., 0.], |
|---|
| 588 |
[ 0., 0., 0., 1.]]) |
|---|
| 589 |
>>> s.asInverse4x4() |
|---|
| 590 |
array([[-1.15, 0.55, 0.1 , 0. ], |
|---|
| 591 |
[ 0.85, -0.45, 0.1 , 0. ], |
|---|
| 592 |
[ 0.65, -0.05, -0.1 , 0. ], |
|---|
| 593 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 594 |
""" |
|---|
| 595 |
|
|---|
| 596 |
def __init__(self, xy=0.0, xz=0.0, yx=0.0, yz = 0.0, zx=0.0, zy=0.0): |
|---|
| 597 |
Matrix.__init__(self) |
|---|
| 598 |
self.matrix[0, 1] = xy |
|---|
| 599 |
self.matrix[0, 2] = xz |
|---|
| 600 |
self.matrix[1, 0] = yx |
|---|
| 601 |
self.matrix[1, 2] = yz |
|---|
| 602 |
self.matrix[2, 0] = zx |
|---|
| 603 |
self.matrix[2, 1] = zy |
|---|
| 604 |
|
|---|
| 605 |
def __repr__(self): |
|---|
| 606 |
return "<Shear: %s >" % self.matrix.tolist() |
|---|
| 607 |
|
|---|
| 608 |
def Inverse(self): |
|---|
| 609 |
result = Matrix(self.asInverse4x4()) |
|---|
| 610 |
result.__class__ = self.__class__ # a little black magic never hurt too much ;) |
|---|
| 611 |
return result |
|---|
| 612 |
|
|---|
| 613 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 614 |
|
|---|
| 615 |
class Skew(Shear): |
|---|
| 616 |
""" |
|---|
| 617 |
>>> s = Skew(10,20,30,40,50,60) |
|---|
| 618 |
>>> s |
|---|
| 619 |
<Skew: [[1.0, 0.17632698070846498, 0.36397023426620234, 0.0], [0.57735026918962573, 1.0, 0.83909963117727993, 0.0], [1.19175359259421, 1.7320508075688767, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]] > |
|---|
| 620 |
>>> s.asArray4x4() |
|---|
| 621 |
array([[ 1. , 0.17632698, 0.36397023, 0. ], |
|---|
| 622 |
[ 0.57735027, 1. , 0.83909963, 0. ], |
|---|
| 623 |
[ 1.19175359, 1.73205081, 1. , 0. ], |
|---|
| 624 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 625 |
>>> s.asInverse4x4() |
|---|
| 626 |
array([[ 1.01054753, -1.01216303, 0.4814964 , 0. ], |
|---|
| 627 |
[-0.94208715, -1.26214385, 1.40195612, 0. ], |
|---|
| 628 |
[ 0.42741917, 3.39234621, -2.00208431, 0. ], |
|---|
| 629 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 630 |
""" |
|---|
| 631 |
|
|---|
| 632 |
def __init__(self, xy=0.0, xz=0.0, yx=0.0, yz=0.0, zx=0.0, zy=0.0): |
|---|
| 633 |
kw = self._ConvertArgs(xy=xy, xz=xz, yx=yx, yz=yz, zx=zx, zy=zy) |
|---|
| 634 |
Shear.__init__(self, **kw) |
|---|
| 635 |
|
|---|
| 636 |
def __repr__(self): |
|---|
| 637 |
return "<Skew: %s >" % self.matrix.tolist() |
|---|
| 638 |
|
|---|
| 639 |
def _ConvertArgs(self, **kw): |
|---|
| 640 |
result = {} |
|---|
| 641 |
for key,value in kw.iteritems(): |
|---|
| 642 |
result[key] = Numeric.tan(math.radians(value)) |
|---|
| 643 |
return result |
|---|
| 644 |
|
|---|
| 645 |
def Inverse(self): |
|---|
| 646 |
result = Matrix(self.asInverse4x4()) |
|---|
| 647 |
result.__class__ = self.__class__ # a little black magic never hurt too much ;) |
|---|
| 648 |
return result |
|---|
| 649 |
|
|---|
| 650 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 651 |
|
|---|
| 652 |
class LinearMappingMatrix(Matrix): |
|---|
| 653 |
""" |
|---|
| 654 |
>>> M = LinearMappingMatrix() |
|---|
| 655 |
>>> M.toX = [0., 100.] |
|---|
| 656 |
>>> M.toY = [10., 20.] |
|---|
| 657 |
>>> M.fromZ = [10., 20.] |
|---|
| 658 |
>>> M |
|---|
| 659 |
<LinearMappingMatrix: [([-1.0, 1.0], [0.0, 100.0]), ([-1.0, 1.0], [10.0, 20.0]), ([10.0, 20.0], [-1.0, 1.0])] > |
|---|
| 660 |
>>> M.asArray4x4() |
|---|
| 661 |
array([[ 50. , 0. , 0. , 50. ], |
|---|
| 662 |
[ 0. , 5. , 0. , 15. ], |
|---|
| 663 |
[ 0. , 0. , 0.2, -3. ], |
|---|
| 664 |
[ 0. , 0. , 0. , 1. ]]) |
|---|
| 665 |
""" |
|---|
| 666 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 667 |
#~ Definitions |
|---|
| 668 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 669 |
|
|---|
| 670 |
fromX = [-1., 1.] |
|---|
| 671 |
fromY = [-1., 1.] |
|---|
| 672 |
fromZ = [-1., 1.] |
|---|
| 673 |
|
|---|
| 674 |
toX = [-1., 1.] |
|---|
| 675 |
toY = [-1., 1.] |
|---|
| 676 |
toZ = [-1., 1.] |
|---|
| 677 |
|
|---|
| 678 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 679 |
#~ Public Methods |
|---|
| 680 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 681 |
|
|---|
| 682 |
def __repr__(self): |
|---|
| 683 |
return "<LinearMappingMatrix: %s >" % ([(self.fromX, self.toX), (self.fromY, self.toY), (self.fromZ, self.toZ)],) |
|---|
| 684 |
|
|---|
| 685 |
def SetFromRect(self, rect): |
|---|
| 686 |
self.fromX = [rect[0], rect[0] + rect[2]] |
|---|
| 687 |
self.fromY = [rect[1], rect[1] + rect[3]] |
|---|
| 688 |
|
|---|
| 689 |
def SetToRect(self, rect): |
|---|
| 690 |
self.toX = [rect[0], rect[0] + rect[2]] |
|---|
| 691 |
self.toY = [rect[1], rect[1] + rect[3]] |
|---|
| 692 |
|
|---|
| 693 |
def asArray4x4(self): |
|---|
| 694 |
Xs,Xt = LinearMapping(self.fromX, self.toX, False) |
|---|
| 695 |
Ys,Yt = LinearMapping(self.fromY, self.toY, False) |
|---|
| 696 |
Zs,Zt = LinearMapping(self.fromZ, self.toZ, False) |
|---|
| 697 |
result = Numeric.asarray([ |
|---|
| 698 |
[Xs, 0, 0, Xt], |
|---|
| 699 |
[0, Ys, 0, Yt], |
|---|
| 700 |
[0, 0, Zs, Zt], |
|---|
| 701 |
[0, 0, 0, 1]], |
|---|
| 702 |
self.NumericType) |
|---|
| 703 |
return result |
|---|
| 704 |
|
|---|
| 705 |
def asInverse4x4(self): |
|---|
| 706 |
Xs,Xt = LinearMapping(self.toX, self.fromX, False) |
|---|
| 707 |
Ys,Yt = LinearMapping(self.toY, self.fromY, False) |
|---|
| 708 |
Zs,Zt = LinearMapping(self.toZ, self.fromZ, False) |
|---|
| 709 |
result = Numeric.asarray([ |
|---|
| 710 |
[Xs, 0, 0, Xt], |
|---|
| 711 |
[0, Ys, 0, Yt], |
|---|
| 712 |
[0, 0, Zs, Zt], |
|---|
| 713 |
[0, 0, 0, 1]], |
|---|
| 714 |
self.NumericType) |
|---|
| 715 |
return result |
|---|
| 716 |
|
|---|
| 717 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 718 |
#~ Testing |
|---|
| 719 |
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 720 |
|
|---|
| 721 |
if __name__=='__main__': |
|---|
| 722 |
print "Testing..." |
|---|
| 723 |
import doctest, Transformations |
|---|
| 724 |
doctest.testmod(Transformations) |
|---|
| 725 |
print "Test complete." |
|---|
| 726 |
|
|---|
| 727 |
|
|---|