amino  1.0-beta2
Lightweight Robot Utility Library
tf.py
Go to the documentation of this file.
1 # Copyright (c) 2019, Colorado School of Mines
2 # All rights reserved.
3 #
4 # Author(s): Neil T. Dantam <ndantam@mines.edu>
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 #
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following
15 # disclaimer in the documentation and/or other materials provided
16 # with the distribution.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
23 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
25 # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
28 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
29 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 # SUCH DAMAGE.
31 
32 
35 """Euclidean transformation representations."""
36 
37 import ctypes
38 from amino.lib import libamino
39 from amino.mixin import VecMixin, CopyEltsMixin, MatMixin
40 from amino.mat import DVec, is_scalar
41 from amino.util import ensure
42 
43 
44 class Vec3(ctypes.Structure, VecMixin):
45  """Length-3 vectors"""
46 
47  _fields_ = [("x", ctypes.c_double), ("y", ctypes.c_double),
48  ("z", ctypes.c_double)]
49 
50  def __init__(self, arg=None):
51  """Constructs a Vec3 object
52 
53  * If arg is None, the object is unitialized.
54  * If arg is a list, the list elements are copied to the object.
55  """
56  if arg is None:
57  super(Vec3, self).__init__(0, 0, 0)
58  elif len(arg) == 3:
59  super(Vec3, self).__init__(arg[0], arg[1], arg[2])
60  else:
61  raise IndexError()
62 
63  def zero(self):
64  """Sets to zero."""
65  self.xx = 0
66  self.yy = 0
67  self.zz = 0
68 
69  @staticmethod
70  def ensure(thing):
71  """Ensures thing is a Vec3. If it's not, convert it."""
72  return ensure(thing, Vec3)
73 
74  @staticmethod
75  def identity():
76  """Returns the identity Vec3."""
77  return Vec3([0, 0, 0])
78 
79  def ssd(self, other):
80  """Sum-square-differences of self and other."""
81  return libamino.aa_tf_vssd(self, Vec3.ensure(other))
82 
83  def nrm2(self):
84  """2-norm (Euclidean) of self"""
85  return libamino.aa_tf_vnorm(self)
86 
87  def __getitem__(self, key):
88  if key == 0:
89  return self.xx
90  if key == 1:
91  return self.yy
92  if key == 2:
93  return self.zz
94  raise IndexError(key)
95 
96  def __setitem__(self, key, item):
97  if key == 0:
98  self.xx = item
99  elif key == 1:
100  self.yy = item
101  elif key == 2:
102  self.zz = item
103  else:
104  raise IndexError(key)
105 
106  def cross(self, other):
107  """Computes the cross product"""
108  r = Vec3()
109  libamino.aa_tf_cross(self, Vec3.ensure(other), r)
110  return r
111 
112  def dot(self, other):
113  """Computes the dot product"""
114  return libamino.aa_tf_vdot(self, Vec3.ensure(other))
115 
116  def __len__(self):
117  return 3
118 
119  def __repr__(self):
120  return 'Vec3((%f, %f, %f))' % (self.xx, self.yy, self.zz)
121 
122  def __iadd__(self, other):
123  if isinstance(other, Vec3):
124  self.xx += other.x
125  self.yy += other.y
126  self.zz += other.z
127  return self
128 
129  if is_scalar(other):
130  self.xx += other
131  self.yy += other
132  self.zz += other
133  return self
134 
135  # try to convert and then add
136  return self.__iadd____iadd__(Vec3(other))
137 
138  def __add__(self, other):
139  return Vec3(self).__iadd__(other)
140 
141  def __radd__(self, other):
142  return Vec3(self).__iadd__(other)
143 
144  def __isub__(self, other):
145  if isinstance(other, Vec3):
146  self.xx -= other.x
147  self.yy -= other.y
148  self.zz -= other.z
149  return self
150 
151  if is_scalar(other):
152  self.xx -= other
153  self.yy -= other
154  self.zz -= other
155  return self
156 
157  return self.__isub____isub__(Vec3(other))
158 
159  def __sub__(self, other):
160  """Subtracts a scalar or vector from self"""
161 
162  return Vec3(self).__isub__(other)
163 
164  def __rsub__(self, other):
165  """Subtracts self or vector from self"""
166  if is_scalar(other):
167  v = Vec3()
168  v.x = other - self.xx
169  v.y = other - self.yy
170  v.z = other - self.zz
171  return v
172 
173  return Vec3(other).__isub__(self)
174 
175  def __imul__(self, other):
176  if is_scalar(other):
177  self.xx *= other
178  self.yy *= other
179  self.zz *= other
180  return self
181  raise TypeError()
182 
183  def __mul__(self, other):
184  v = Vec3(self)
185  v *= other
186  return v
187 
188  def __rmul__(self, other):
189  return self * other
190 
191  def __itruediv__(self, other):
192  if is_scalar(other):
193  self.xx /= other
194  self.yy /= other
195  self.zz /= other
196  return self
197  raise TypeError()
198 
199  def __truediv__(self, other):
200  return Vec3(self).__itruediv__(other)
201 
202  def to_quat(self, h):
203  """Converts to a quaternion and copies to h.
204 
205  This functions sets the vector (xyz) part of h. The scalar
206  part (w) of h will be zero
207 
208  """
209  h.x = self.xx
210  h.y = self.yy
211  h.z = self.zz
212  h.w = 0
213 
214 
215 class XAngle(ctypes.Structure):
216  """Rotation about the X axis"""
217  _fields_ = [("value", ctypes.c_double)]
218 
219  def to_quat(self, h):
220  """Converts to a quaternion and store in h"""
221  libamino.aa_tf_xangle2quat(self.value, h)
222 
223  def to_rotmat(self, r):
224  """Converts to a rotation matrix and store in r"""
225  libamino.aa_tf_xangle2rotmat(self.value, r)
226 
227  def to_axang(self, a):
228  """Converts to an axis-angle and store in a"""
229  libamino.aa_tf_xangle2axang(self.value, a)
230 
231  def to_eulerzyx(self, e):
232  """Converts to an Euler XYZ"""
233  e.x = self.value
234  e.y = 0
235  e.z = 0
236 
237  def __repr__(self):
238  return 'XAngle(%f)' % (self.value)
239 
240 
241 class YAngle(ctypes.Structure):
242  """Rotation about the Y axis"""
243  _fields_ = [("value", ctypes.c_double)]
244 
245  def to_quat(self, h):
246  """Converts to a quaternion and store in h"""
247  libamino.aa_tf_yangle2quat(self.value, h)
248 
249  def to_rotmat(self, r):
250  """Converts to a rotation matrix and store in r"""
251  libamino.aa_tf_yangle2rotmat(self.value, r)
252 
253  def to_axang(self, a):
254  """Converts to an axis-angle and store in a"""
255  libamino.aa_tf_yangle2axang(self.value, a)
256 
257  def to_eulerzyx(self, e):
258  """Converts to an Euler XYZ and store in e"""
259  e.x = 0
260  e.y = self.value
261  e.z = 0
262 
263  def __repr__(self):
264  return 'YAngle(%f)' % (self.value)
265 
266 
267 class ZAngle(ctypes.Structure):
268  """Rotation about the Z axis"""
269  _fields_ = [("value", ctypes.c_double)]
270 
271  def to_quat(self, h):
272  """Converts to a quaternion and store in h"""
273  libamino.aa_tf_zangle2quat(self.value, h)
274 
275  def to_rotmat(self, r):
276  """Converts to a rotation matrix and store in r"""
277  libamino.aa_tf_zangle2rotmat(self.value, r)
278 
279  def to_axang(self, a):
280  """Converts to an axis-angle and store in a"""
281  libamino.aa_tf_zangle2axang(self.value, a)
282 
283  def to_eulerzyx(self, e):
284  """Converts to an Euler XYZ and store in e"""
285  e.x = 0
286  e.y = 0
287  e.z = self.value
288 
289  def __repr__(self):
290  return 'ZAngle(%f)' % (self.value)
291 
292 
293 class EulerZYX(ctypes.Structure):
294  """Z-Y-X Euler angles"""
295  _fields_ = [("_z", ctypes.c_double), ("_y", ctypes.c_double),
296  ("_x", ctypes.c_double)]
297 
298  def __init__(self, arg=None):
299  if arg is None:
300  super(EulerZYX, self).__init__(0, 0, 0)
301  elif isinstance(arg, (list, tuple)):
302  if len(arg) != 3:
303  raise IndexError()
304  super(EulerZYX, self).__init__(arg[0], arg[1], arg[2])
305  else:
306  arg.to_eulerzyx(self)
307 
308  def to_quat(self, h):
309  """Converts to a quaternion"""
310  libamino.aa_tf_eulerzyx2quat(self._z_z, self._y_y, self._x_x, h)
311 
312  def to_rotmat(self, r):
313  """Converts to a rotation matrix and store in r"""
314  libamino.aa_tf_eulerzyx2rotmat(self._z_z, self._y_y, self._x_x, r)
315 
316  @property
317  def x(self):
318  """X-axis rotation."""
319  return self._x_x
320 
321  @x.setter
322  def x(self, value):
323  self._x_x = value
324 
325  @property
326  def y(self):
327  """Y-axis rotation."""
328  return self._y_y
329 
330  @y.setter
331  def y(self, value):
332  self._y_y = value
333 
334  @property
335  def z(self):
336  """Z-axis rotation."""
337  return self._z_z
338 
339  @z.setter
340  def z(self, value):
341  self._z_z = value
342 
343  def __repr__(self):
344  return 'EulerZYX((%f, %f, %f))' % (self.zzz, self.yyy, self.xxx)
345 
346 
347 class EulerRPY(EulerZYX):
348  """Roll-Pitch-Yaw Euler angles"""
349 
350  def __init__(self, arg=None):
351  if isinstance(arg, (list, tuple)):
352  if len(arg) != 3:
353  raise IndexError()
354  arg = (arg[2], arg[1], arg[0])
355  super(EulerRPY, self).__init__(arg)
356 
357  @property
358  def r(self):
359  """Roll."""
360  return self._x_x
361 
362  @r.setter
363  def r(self, value):
364  self._x_x_x = value
365 
366  @property
367  def p(self):
368  """Pitch."""
369  return self._y_y_y
370 
371  @p.setter
372  def p(self, value):
373  self._y_y_y = value
374 
375  @property
376  def y(self):
377  """Yaw."""
378  return self._z_z_z
379 
380  @y.setter
381  def y(self, value):
382  self._z_z_z = value
383 
384  def __repr__(self):
385  return 'EulerRPY((%f, %f, %f))' % (self.rrr, self.ppp, self.yyyyy)
386 
387 
388 class AxAng(ctypes.Structure):
389  """3D rotation about an arbitrary axis"""
390  _fields_ = [("axis", Vec3), ("angle", ctypes.c_double)]
391 
392  def __init__(self, arg=None):
393  if arg is None:
394  self.set_identity()
395  else:
396  self.conv_from(arg)
397 
398  def set_identity(self):
399  """Set to identity"""
400  self.axis.copy_from((0, 0, 1))
401  self.angle = 0
402 
403  def conv_from(self, src):
404  """Converts src into an AxAng."""
405  if isinstance(src, (tuple, list)):
406  if len(src) != 4:
407  raise IndexError()
408  libamino.aa_tf_axang_make(src[0], src[1], src[2], src[3], self)
409  else:
410  src.to_axang(self)
411 
412  def normalize(self):
413  """Ensures the axis is a unit vector"""
414  libamino.aa_tf_axang_normalize(self)
415  return self
416 
417  def to_quat(self, h):
418  """Converts to a quaternion"""
419  libamino.aa_tf_axang2quat(self, h)
420 
421  def to_rotmat(self, r):
422  """Converts to a rotation matrix and store in r"""
423  libamino.aa_tf_axang2rotmat(self, r)
424 
425  def to_axang(self, a):
426  """Converts to an axis-angle and store in a"""
427  a.axis.copy_from(self.axis)
428  a.angle = self.angleangle
429 
430  def __invert__(self):
431  """Returns the inverse"""
432  a = AxAng()
433  a.axis = self.axis
434  a.angle = -self.angleangle
435  return a
436 
437  def rotate(self, p):
438  """Rotate a point by self"""
439  q = Vec3()
440  libamino.aa_tf_axang_rot(self, Vec3.ensure(p), q)
441  return q
442 
443  def __repr__(self):
444  axis = self.axis
445  angle = self.angleangle
446  return 'AxAng((%f, %f, %f, %f))' % (axis.x, axis.y, axis.z, angle)
447 
448 
449 class Quat(ctypes.Structure, VecMixin):
450  """Class for quaternions"""
451  _fields_ = [
452  ("x", ctypes.c_double),
453  ("y", ctypes.c_double),
454  ("z", ctypes.c_double),
455  ("w", ctypes.c_double),
456  ]
457 
458  def __init__(self, arg=None):
459  """Construct a Quat object
460 
461  * If arg is None, the object is unitialized.
462  * If arg is a list, the list elements are copied to the object.
463  * If arg is an int or float, the scalar (w) of the object is set
464  and the vector (xyz) is zero
465  * If arg is a Vec3, the vector (xyz) of the object is set
466  and the scalar (w) is zero
467  * Else arg is converted to a Quat
468  """
469  if arg is None:
470  self.set_identityset_identity()
471  else:
472  self.conv_fromconv_from(arg)
473 
474  def conv_from(self, src):
475  """Converts src to a quaternion."""
476  if is_scalar(src):
477  self.xx = 0
478  self.yy = 0
479  self.zz = 0
480  self.ww = src
481  elif isinstance(src, (list, tuple)):
482  self.copy_fromcopy_from(src)
483  else:
484  src.to_quat(self)
485  return self
486 
487  @staticmethod
488  def identity():
489  """Returns the identity quaternion."""
490  return Quat(1)
491 
492  @staticmethod
493  def ensure(thing):
494  """Ensures thing is a Quat. If it's not, convert it."""
495  return ensure(thing, Quat)
496 
497  def to_quat(self, h):
498  """Converts (copy) to a quaternion"""
499  h.x = self.xx
500  h.y = self.yy
501  h.z = self.zz
502  h.w = self.ww
503 
504  def to_rotmat(self, r):
505  """Converts to a rotation matrix and store in r"""
506  libamino.aa_tf_quat2rotmat(self, r)
507 
508  def to_axang(self, a):
509  """Converts to an axis-angle and store in a"""
510  libamino.aa_tf_quat2axang(self, a)
511 
512  def to_eulerzyx(self):
513  """Converts to an euler zyx angle representation"""
514  ang = (ctypes.c_double * 3)()
515  libamino.aa_tf_quat2eulerzyx(self, ang)
516  x = [ang[0], ang[1], ang[2]]
517  return EulerZYX(x)
518 
519  def vector(self):
520  """Returns the vector (xyz) part"""
521  return Vec3([self.xx, self.yy, self.zz])
522 
523  def scalar(self):
524  """Returns the scalar (w) part"""
525  return self.ww
526 
527  def ssd(self, other):
528  """Sum-square-differences of self and other."""
529  return libamino.aa_tf_qssd(self, Quat.ensure(other))
530 
531  def nrm2(self):
532  """2-norm (Euclidean) of self."""
533  return libamino.aa_tf_qnorm(self)
534 
535  # Do not define addition/subtraction for scalars. The meaning is
536  # non-obvious since we could either add/sub every quaternion
537  # element or only the w (quaternion scalar) element.
538  def __iadd__(self, other):
539  libamino.aa_tf_qiadd(self, Quat.ensure(other))
540  return self
541 
542  def __isub__(self, other):
543  libamino.aa_tf_qisub(self, Quat.ensure(other))
544  return self
545 
546  def __add__(self, other):
547  h = Quat()
548  libamino.aa_tf_qadd(self, Quat.ensure(other), h)
549  return h
550 
551  def __radd__(self, other):
552  return self + other
553 
554  def __sub__(self, other):
555  h = Quat()
556  libamino.aa_tf_qsub(self, Quat.ensure(other), h)
557  return h
558 
559  def __rsub__(self, other):
560  h = Quat()
561  libamino.aa_tf_qsub(Quat.ensure(other), self, h)
562  return h
563 
564  def normalize(self):
565  """Normalize this object, i.e., divide by the magnitude."""
566  libamino.aa_tf_qnormalize(self)
567  return self
568 
569  def minimize(self):
570  """Converts to the minimal quaternion for the represented rotation."""
571  libamino.aa_tf_qminimize(self)
572  return self
573 
574  def set_identity(self):
575  """Set to identity"""
576  self.xx = 0
577  self.yy = 0
578  self.zz = 0
579  self.ww = 1
580 
581  def zero(self):
582  """Set to zero"""
583  self.xx = 0
584  self.yy = 0
585  self.zz = 0
586  self.ww = 0
587 
588  def __imul__(self, other):
589  if is_scalar(other):
590  libamino.aa_tf_qscal(self, other)
591  else:
592  raise TypeError()
593  return self
594 
595  def __rmul__(self, other):
596  if is_scalar(other):
597  return Quat(self).__imul__(other)
598 
599  h = Quat()
600  libamino.aa_tf_qmul(Quat.ensure(other), self, h)
601  return h
602 
603  def __mul__(self, other):
604  if is_scalar(other):
605  return Quat(self).__imul__(other)
606 
607  h = Quat()
608  libamino.aa_tf_qmul(self, Quat.ensure(other), h)
609  return h
610 
611  def __getitem__(self, key):
612  if key == 0:
613  return self.xx
614  elif key == 1:
615  return self.yy
616  elif key == 2:
617  return self.zz
618  elif key == 3:
619  return self.ww
620  else:
621  raise IndexError(key)
622 
623  def __setitem__(self, key, item):
624  if key == 0:
625  self.xx = item
626  elif key == 1:
627  self.yy = item
628  elif key == 2:
629  self.zz = item
630  elif key == 3:
631  self.ww = item
632  else:
633  raise IndexError(key)
634 
635  def __len__(self):
636  return 4
637 
638  def conj(self):
639  """Returns the conjugate"""
640  h = Quat()
641  libamino.aa_tf_qconj(self, h)
642  return h
643 
644  def __invert__(self):
645  """Returns the inverse"""
646  h = Quat()
647  libamino.aa_tf_qinv(self, h)
648  return h
649 
650  def exp(self):
651  """Returns the exponential"""
652  h = Quat()
653  libamino.aa_tf_qexp(self, h)
654  return h
655 
656  def ln(self):
657  """Returns the natural logarithm"""
658  h = Quat()
659  libamino.aa_tf_qln(self, h)
660  return h
661 
662  def rotate(self, p):
663  """Rotate a point by this quaternion"""
664  q = Vec3()
665  libamino.aa_tf_qrot(self, Vec3.ensure(p), q)
666  return q
667 
668  def __repr__(self):
669  return 'Quat((%f, %f, %f, %f))' % (self.xx, self.yy, self.zz, self.ww)
670 
671 
672 class RotMat(ctypes.Structure, MatMixin):
673  """Class for rotation matrices"""
674  _fields_ = [("cx", Vec3), ("cy", Vec3), ("cz", Vec3)]
675 
676  def __init__(self, arg=None):
677  """Construct a RotMat object
678 
679  * If arg is None, the object is unitialized.
680  * If arg is 1, the object is the identity rotation matrix.
681  * Else arg is converted to a rotation matrix.
682  """
683  if arg is None:
684  self.set_identityset_identity()
685  else:
686  self.conv_fromconv_from(arg)
687 
688  def conv_from(self, src):
689  """Converts src to a rotation matrix."""
690  if src == 1:
691  self.set_identityset_identity()
692  else:
693  src.to_rotmat(self)
694 
695  def set_identity(self):
696  """Set to identity"""
697  self.cx.copy_from((1, 0, 0))
698  self.cy.copy_from((0, 1, 0))
699  self.cz.copy_from((0, 0, 1))
700 
701  def rotate(self, p):
702  """Rotate a point."""
703  q = Vec3(None)
704  libamino.aa_tf_rotmat_rot(self, Vec3.ensure(p), q)
705  return q
706 
707  @staticmethod
708  def ensure(thing):
709  """Ensures thing is a RotMat. If it's not, convert it."""
710  return ensure(thing, RotMat)
711 
712  def __mul__(self, other):
713  """Chains two matrices"""
714  r = RotMat()
715  libamino.aa_tf_rotmat_mul(self, RotMat.ensure(other), r)
716  return r
717 
718  def to_quat(self, h):
719  """Converts to a quaternion and store in h"""
720  libamino.aa_tf_rotmat2quat(self, h)
721 
722  def to_rotmat(self, r):
723  """Converts (copy) to a rotation matrix and store in r"""
724  r.cx = self.cx
725  r.cy = self.cy
726  r.cz = self.cz
727 
728  def to_axang(self, a):
729  """Converts to an axis-angle and store in a"""
730  libamino.aa_tf_rotmat2axang(self, a)
731 
732  def ln(self):
733  """Returns the natural logarithm"""
734  h = Vec3()
735  libamino.aa_tf_rotmat_lnv(self, h)
736  return h
737 
738  def __invert__(self):
739  """Returns the inverse"""
740  r = RotMat()
741  libamino.aa_tf_rotmat_inv2(self, r)
742  return r
743 
744  def __getitem__(self, key):
745  i, j = key
746  if j == 0:
747  return self.cx[i]
748  if j == 1:
749  return self.cy[i]
750  if j == 2:
751  return self.cz[i]
752  raise IndexError(key)
753 
754  def __setitem__(self, key, item):
755  i, j = key
756  if j == 0:
757  self.cx[i] = item
758  elif j == 1:
759  self.cy[i] = item
760  elif j == 2:
761  self.cz[i] = item
762  else:
763  raise IndexError(key)
764 
765  @property
766  def rows(self):
767  """Number of rows."""
768  return 3;
769 
770  @property
771  def cols(self):
772  """Number of columns."""
773  return 3;
774 
775  @staticmethod
776  def row_matrix(args):
777  """Constructs rotation matrix from rows in args."""
778  if len(args) != 3:
779  raise IndexError()
780  A = RotMat()
781  for i in range(0, 3):
782  if len(args[i]) != 3:
783  raise IndexError()
784  for j in range(0, 3):
785  A[i, j] = args[i][j]
786  return A
787 
788  @staticmethod
789  def col_matrix(args):
790  """Constructs rotation matrix from columns in args."""
791  if len(args) != 3:
792  raise IndexError()
793  A = RotMat()
794  for j in range(0, 3):
795  if len(args[j]) != 3:
796  raise IndexError()
797  for i in range(0, 3):
798  A[i, j] = args[j][i]
799  return A
800 
801  def __repr__(self):
802  return self._str_helper_str_helper("RotMat.row_matrix")
803 
804  def isclose(self, other, tol=1e-9):
805  """Returns True if self is within tol rotation angle to other."""
806  other = RotMat.ensure(other)
807  v = (self * ~other).ln().nrm2()
808  return v <= tol
809 
810 
811 class TfMat(ctypes.Structure, MatMixin):
812  """Class for transformation matrices"""
813  _fields_ = [("R", RotMat), ("v", Vec3)]
814 
815  def __init__(self, arg=None):
816  if arg is None:
817  self.set_identityset_identity()
818  else:
819  self.conv_fromconv_from(arg)
820 
821  def conv_from(self, src):
822  """Converts src to a transformation matrix."""
823  if isinstance(src, tuple):
824  R, v = src
825  self.R.conv_from(R)
826  self.v.copy_from(v)
827  else:
828  self.conv_fromconv_from((src.rotation, src.translation))
829 
830  def __mul__(self, other):
831  """Chains two TF matrices"""
832  r = TfMat()
833  libamino.aa_tf_tfmat_mul(self, other, r)
834  return r
835 
836  def set_identity(self):
837  """Set to identity"""
838  self.R.set_identity()
839  self.v.copy_from((0, 0, 0))
840 
841  def __invert__(self):
842  """Returns the inverse"""
843  h = TfMat()
844  libamino.aa_tf_tfmat_inv2(self, h)
845  return h
846 
847  def transform(self, p):
848  """Chains two TF matrices"""
849  q = Vec3()
850  libamino.aa_tf_tfmat_tf(self, Vec3.ensure(p), q)
851  return q
852 
853  @property
854  def rotation(self):
855  """Rotation part"""
856  return self.R
857 
858  @rotation.setter
859  def rotation(self, value):
860  self.R.conv_from(value)
861 
862  @property
863  def translation(self):
864  """Translation part"""
865  return self.v
866 
867  @translation.setter
868  def translation(self, value):
869  return self.v.copy_from(value)
870 
871  def __getitem__(self, key):
872  i, j = key
873  if j < 3:
874  return self.R[key]
875  elif j == 3:
876  return self.v[i]
877  else:
878  raise IndexError(key)
879 
880  def __setitem__(self, key, item):
881  i, j = key
882  if j < 3:
883  self.R[key] = item
884  elif j == 3:
885  self.v[i] = item
886  else:
887  raise IndexError(key)
888 
889  @staticmethod
890  def ensure(thing):
891  """Ensures thing is a TfMat. If it's not, convert it."""
892  return ensure(thing, TfMat)
893 
894  @staticmethod
895  def row_matrix(args):
896  """Constructs transformation matrix from rows in args."""
897  m = len(args)
898  A = TfMat()
899  if m != 3:
900  raise IndexError()
901  for i in range(0, m):
902  n = len(args[i])
903  if n != 4:
904  raise IndexError()
905  for j in range(0, n):
906  A[i, j] = args[i][j]
907 
908  return A
909 
910  def __repr__(self):
911  return self._str_helper_str_helper("TfMat.row_matrix", 3, 4)
912 
913  def __len__(self):
914  return 12
915 
916 
917 class DualQuat(ctypes.Structure, CopyEltsMixin):
918  """Class for Dual Number Quaternions"""
919  _fields_ = [("real", Quat), ("dual", Quat)]
920 
921  def __init__(self, arg=None):
922  if arg is None:
923  self.set_identityset_identity()
924  else:
925  self.conv_fromconv_from(arg)
926 
927  def set_identity(self):
928  """Set to identity"""
929  self.real.set_identity()
930  self.dual.zero()
931 
932  def conv_from(self, src):
933  """Converts src to a Dual Quaternion."""
934  if isinstance(src, tuple):
935  h, v = src
936  libamino.aa_tf_qv2duqu(Quat.ensure(h), Vec3.ensure(v), self)
937  elif isinstance(src, list):
938  self.copy_from(src)
939  else:
940  self.conv_fromconv_from((src.rotation, src.translation))
941 
942  def __mul__(self, other):
943  """Chains two Dual Quaternions"""
944  r = DualQuat()
945  libamino.aa_tf_duqu_mul(self, other, r)
946  return r
947 
948  def conj(self):
949  """Returns the conjugate"""
950  h = DualQuat()
951  libamino.aa_tf_duqu_conj(self, h)
952  return h
953 
954  def __invert__(self):
955  """Returns the inverse"""
956  # TODO: should we use the actual inverse?
957  return self.conjconj()
958 
959  def ln(self):
960  """Returns the dual quaternion logarithm"""
961  h = DualQuat()
962  libamino.aa_tf_duqu_ln(self, h)
963  return h
964 
965  @staticmethod
966  def identity():
967  """Returns the identity dual quaternion."""
968  return DualQuat((Quat.identity(), Vec3.identity()))
969 
970  @staticmethod
971  def ensure(thing):
972  """Ensures thing is a DualQuat. If it's not, convert it."""
973  return ensure(thing, DualQuat)
974 
975  def norm_parts(self):
976  """Real and dual parts 2-norm (Euclidean)"""
977  r = ctypes.c_double()
978  d = ctypes.c_double()
979  libamino.aa_tf_duqu_norm(self, ctypes.byref(r), ctypes.byref(d))
980  return (r.value, d.value)
981 
982  def transform(self, p):
983  """Transform point p"""
984  q = Vec3()
985  libamino.aa_tf_duqu_tf(self, Vec3.ensure(p), q)
986  return q
987 
988  def __repr__(self):
989  return 'DualQuat((%s, %s))' % (self.rotationrotationrotation, self.translationtranslationtranslation)
990 
991  def __getitem__(self, key):
992  if key == 0:
993  v = self.real.x
994  elif key == 1:
995  v = self.real.y
996  elif key == 2:
997  v = self.real.z
998  elif key == 3:
999  v = self.real.w
1000  elif key == 4:
1001  v = self.dual.x
1002  elif key == 5:
1003  v = self.dual.y
1004  elif key == 6:
1005  v = self.dual.z
1006  elif key == 7:
1007  v = self.dual.w
1008  else:
1009  raise IndexError(key)
1010  return v
1011 
1012  def __setitem__(self, key, item):
1013  if key == 0:
1014  self.real.x = item
1015  elif key == 1:
1016  self.real.y = item
1017  elif key == 2:
1018  self.real.z = item
1019  elif key == 3:
1020  self.real.w = item
1021  elif key == 4:
1022  self.dual.x = item
1023  elif key == 5:
1024  self.dual.y = item
1025  elif key == 6:
1026  self.dual.z = item
1027  elif key == 7:
1028  self.dual.w = item
1029  else:
1030  raise IndexError(key)
1031 
1032  def __len__(self):
1033  return 8
1034 
1035 
1036  @property
1037  def rotation(self):
1038  """Rotation part"""
1039  return Quat(self.real)
1040 
1041  @property
1042  def translation(self):
1043  """Translation"""
1044  v = Vec3()
1045  libamino.aa_tf_duqu_trans(self, v)
1046  return v
1047 
1048  @rotation.setter
1049  def rotation(self, value):
1050  h = Quat(value)
1051  v = self.translationtranslationtranslation
1052  libamino.aa_tf_qv2duqu(h, v, self)
1053 
1054  @translation.setter
1055  def translation(self, value):
1056  h = self.rotationrotationrotation
1057  v = Vec3(value)
1058  libamino.aa_tf_qv2duqu(h, v, self)
1059 
1060 
1061 class QuatTrans(ctypes.Structure, CopyEltsMixin):
1062  """Class for Quaternion-Translation"""
1063  _fields_ = [("quat", Quat), ("trans", Vec3)]
1064 
1065  def __init__(self, arg=None):
1066  if arg is None:
1067  self.set_identityset_identity()
1068  else:
1069  self.conv_fromconv_from(arg)
1070 
1071  def set_identity(self):
1072  """Set to identity"""
1073  self.quat.set_identity()
1074  self.trans.copy_from((0, 0, 0))
1075 
1076  def conv_from(self, src):
1077  """Converts src to quaternion-translation."""
1078  if isinstance(src, tuple):
1079  (R, v) = src
1080  self.quat.conv_from(R)
1081  self.trans.copy_from(v)
1082  elif isinstance(src, list):
1083  self.copy_fromcopy_from(src)
1084  else:
1085  self.conv_fromconv_from((src.rotation, src.translation))
1086 
1087  @staticmethod
1088  def identity():
1089  """Returns the identity QuatTrans."""
1090  return QuatTrans((Quat.identity(), Vec3.identity()))
1091 
1092  @staticmethod
1093  def ensure(thing):
1094  """Ensures thing is a QuatTrans. If it's not, convert it."""
1095  return ensure(thing, QuatTrans)
1096 
1097  def __mul__(self, other):
1098  """Chains two Dual Quaternions"""
1099  r = QuatTrans()
1100  libamino.aa_tf_qutr_mul(self, other, r)
1101  return r
1102 
1103  def conj(self):
1104  """Returns the conjugate"""
1106  libamino.aa_tf_qutr_conj(self, h)
1107  return h
1108 
1109  def __invert__(self):
1110  """Returns the inverse (same as conjugate)"""
1111  return self.conjconj()
1112 
1113  def transform(self, p):
1114  """Chains two Quaternion-translations"""
1115  q = Vec3()
1116  libamino.aa_tf_qutr_tf(self, Vec3.ensure(p), q)
1117  return q
1118 
1119  def __repr__(self):
1120  return 'QuatTrans((%s, %s))' % (self.quat, self.trans)
1121 
1122  def __getitem__(self, key):
1123  if key == 0:
1124  v = self.quat.x
1125  elif key == 1:
1126  v = self.quat.y
1127  elif key == 2:
1128  v = self.quat.z
1129  elif key == 3:
1130  v = self.quat.w
1131  elif key == 4:
1132  v = self.trans.x
1133  elif key == 5:
1134  v = self.trans.y
1135  elif key == 6:
1136  v = self.trans.z
1137  else:
1138  raise IndexError(key)
1139  return v
1140 
1141  def __setitem__(self, key, item):
1142  if key == 0:
1143  self.quat.x = item
1144  elif key == 1:
1145  self.quat.y = item
1146  elif key == 2:
1147  self.quat.z = item
1148  elif key == 3:
1149  self.quat.w = item
1150  elif key == 4:
1151  self.trans.x = item
1152  elif key == 5:
1153  self.trans.y = item
1154  elif key == 6:
1155  self.trans.z = item
1156  else:
1157  raise IndexError(key)
1158 
1159  @property
1160  def rotation(self):
1161  """Rotation part"""
1162  return self.quat
1163 
1164  @rotation.setter
1165  def rotation(self, value):
1166  return self.quat.conv_from(value)
1167 
1168  @property
1169  def translation(self):
1170  """Translation"""
1171  return self.trans
1172 
1173  @translation.setter
1174  def translation(self, value):
1175  return self.trans.copy_from(value)
1176 
1177  def __len__(self):
1178  return 7
1179 
1180 
1181 #--------------#
1182 # Differential #
1183 #--------------#
1184 class TfVec(ctypes.Structure):
1185  """six-element vector with rotational and translational parts."""
1186  _fields_ = [("trans", Vec3), ("rot", Vec3)]
1187 
1188  def _first(self):
1189  return self.trans
1190 
1191  def _second(self):
1192  return self.rot
1193 
1194  @property
1195  def rotational(self):
1196  """Rotational part"""
1197  return self.rot
1198 
1199  @property
1200  def translational(self):
1201  """Translational part"""
1202  return self.trans
1204  @translational.setter
1205  def translational(self, x):
1206  """Set the translational part from x"""
1207  self.trans.copy_from(x)
1208 
1209  @rotational.setter
1210  def rotational(self, x):
1211  """Set the rotational part from x"""
1212  self.rot.copy_from(x)
1213 
1214  def copy_from(self, src):
1215  """Copies src into self."""
1216  self.rotational = src.rotational
1217  self.translational = src.translational
1219  def zero(self):
1220  """Set to zero."""
1221  self.rot.zero()
1222  self.trans.zero()
1223 
1224  def __len__(self):
1225  """Number of elements in self"""
1226  return 6
1227 
1228  def __getitem__(self, key):
1229  if key < 0:
1230  raise IndexError(key)
1231  elif key < 3:
1232  return self._first_first()[key]
1233  elif key < 6:
1234  return self._second_second()[key - 3]
1235  else:
1236  raise IndexError(key)
1238  def __setitem__(self, key, item):
1239  if key < 0:
1240  raise IndexError(key)
1241  elif key < 3:
1242  self._first_first()[key] = item
1243  elif key < 6:
1244  self._second_second()[key - 3] = item
1245  else:
1246  raise IndexError(key)
1248  def to_dvec(self, vec=DVec(6)):
1249  """Copies self to a vec."""
1250  vec.copy_from(self)
1251  return vec
1252 
1253  def from_dvec(self, vec):
1254  """Copies vec to self."""
1255  vec.copy_to(self)
1257 
1258 class TfVel(TfVec):
1259  """A rotational and translational velocity."""
1260 
1261  def __init__(self):
1262  pass
1263 
1264 
1265 class Twist(TfVec):
1266  """A twist velocity."""
1267 
1268  def __init__(self):
1269  pass
1270 
1271 
1272 #---------------#
1273 # LIBRARY CALLS #
1274 #---------------#
1275 
1276 libamino.aa_tf_xangle2quat.argtypes = [ctypes.c_double, ctypes.POINTER(Quat)]
1277 libamino.aa_tf_yangle2quat.argtypes = [ctypes.c_double, ctypes.POINTER(Quat)]
1278 libamino.aa_tf_zangle2quat.argtypes = [ctypes.c_double, ctypes.POINTER(Quat)]
1279 
1280 libamino.aa_tf_xangle2rotmat.argtypes = [
1281  ctypes.c_double, ctypes.POINTER(RotMat)
1282 ]
1283 libamino.aa_tf_yangle2rotmat.argtypes = [
1284  ctypes.c_double, ctypes.POINTER(RotMat)
1286 libamino.aa_tf_zangle2rotmat.argtypes = [
1287  ctypes.c_double, ctypes.POINTER(RotMat)
1288 ]
1289 
1290 libamino.aa_tf_xangle2axang.argtypes = [ctypes.c_double, ctypes.POINTER(AxAng)]
1291 libamino.aa_tf_yangle2axang.argtypes = [ctypes.c_double, ctypes.POINTER(AxAng)]
1292 libamino.aa_tf_zangle2axang.argtypes = [ctypes.c_double, ctypes.POINTER(AxAng)]
1293 
1294 libamino.aa_tf_eulerzyx2rotmat.argtypes = [
1295  ctypes.c_double, ctypes.c_double, ctypes.c_double,
1296  ctypes.POINTER(RotMat)
1297 ]
1298 
1299 libamino.aa_tf_eulerzyx2quat.argtypes = [
1300  ctypes.c_double, ctypes.c_double, ctypes.c_double,
1301  ctypes.POINTER(Quat)
1303 
1304 libamino.aa_tf_quat2eulerzyx.argtypes = [ctypes.POINTER(Quat),
1305  ctypes.POINTER(ctypes.c_double)]
1306 
1307 libamino.aa_tf_quat2rotmat.argtypes = [
1308  ctypes.POINTER(Quat), ctypes.POINTER(RotMat)
1309 ]
1310 libamino.aa_tf_rotmat2quat.argtypes = [
1311  ctypes.POINTER(RotMat), ctypes.POINTER(Quat)
1312 ]
1313 
1314 libamino.aa_tf_axang2quat.argtypes = [
1315  ctypes.POINTER(AxAng), ctypes.POINTER(Quat)
1316 ]
1317 libamino.aa_tf_quat2axang.argtypes = [
1318  ctypes.POINTER(Quat), ctypes.POINTER(AxAng)
1319 ]
1320 
1321 libamino.aa_tf_axang2rotmat.argtypes = [
1322  ctypes.POINTER(AxAng), ctypes.POINTER(RotMat)
1323 ]
1324 libamino.aa_tf_rotmat2axang.argtypes = [
1325  ctypes.POINTER(RotMat), ctypes.POINTER(AxAng)
1326 ]
1327 
1328 libamino.aa_tf_qv2duqu.argtypes = [
1329  ctypes.POINTER(Quat),
1330  ctypes.POINTER(Vec3),
1331  ctypes.POINTER(DualQuat)
1332 ]
1333 
1334 libamino.aa_tf_duqu2qv.argtypes = [
1335  ctypes.POINTER(DualQuat),
1336  ctypes.POINTER(Quat),
1337  ctypes.POINTER(Vec3)
1338 ]
1339 
1340 libamino.aa_tf_duqu2qv.argtypes = [
1341  ctypes.POINTER(DualQuat),
1342  ctypes.POINTER(Quat),
1343  ctypes.POINTER(Vec3)
1344 ]
1345 
1346 libamino.aa_tf_duqu_trans.argtypes = [
1347  ctypes.POINTER(DualQuat), ctypes.POINTER(Vec3)
1348 ]
1349 
1350 libamino.aa_tf_duqu_trans.argtypes = [
1351  ctypes.POINTER(DualQuat), ctypes.POINTER(Vec3)
1352 ]
1353 
1354 # axang
1355 libamino.aa_tf_axang_make.argtypes = [
1356  ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double,
1357  ctypes.POINTER(AxAng)
1358 ]
1359 
1360 libamino.aa_tf_axang_normalize.argtypes = [ctypes.POINTER(AxAng)]
1361 
1362 libamino.aa_tf_axang_rot.argtypes = [
1363  ctypes.POINTER(AxAng),
1364  ctypes.POINTER(Vec3),
1365  ctypes.POINTER(Vec3)
1366 ]
1367 
1368 # vector functions
1369 libamino.aa_tf_vssd.argtypes = [ctypes.POINTER(Vec3), ctypes.POINTER(Vec3)]
1370 libamino.aa_tf_vssd.restype = ctypes.c_double
1371 
1372 libamino.aa_tf_vnorm.argtypes = [ctypes.POINTER(Vec3)]
1373 libamino.aa_tf_vnorm.restype = ctypes.c_double
1374 
1375 libamino.aa_tf_vdot.argtypes = [ctypes.POINTER(Vec3), ctypes.POINTER(Vec3)]
1376 libamino.aa_tf_vdot.restype = ctypes.c_double
1377 
1378 libamino.aa_tf_cross.argtypes = [
1379  ctypes.POINTER(Vec3),
1380  ctypes.POINTER(Vec3),
1381  ctypes.POINTER(Vec3)
1382 ]
1383 
1384 # quaternion functions
1385 
1386 libamino.aa_tf_qssd.argtypes = [ctypes.POINTER(Quat), ctypes.POINTER(Quat)]
1387 libamino.aa_tf_qssd.restype = ctypes.c_double
1388 
1389 libamino.aa_tf_qminimize.argtypes = [ctypes.POINTER(Quat)]
1390 
1391 libamino.aa_tf_qnorm.argtypes = [ctypes.POINTER(Quat)]
1392 libamino.aa_tf_qnorm.restype = ctypes.c_double
1393 
1394 libamino.aa_tf_qscal.argtypes = [ctypes.POINTER(Quat), ctypes.c_double]
1395 
1396 libamino.aa_tf_qnormalize.argtypes = [ctypes.POINTER(Quat)]
1397 
1398 libamino.aa_tf_qmul.argtypes = [
1399  ctypes.POINTER(Quat),
1400  ctypes.POINTER(Quat),
1401  ctypes.POINTER(Quat)
1402 ]
1403 libamino.aa_tf_qadd.argtypes = [
1404  ctypes.POINTER(Quat),
1405  ctypes.POINTER(Quat),
1406  ctypes.POINTER(Quat)
1407 ]
1408 libamino.aa_tf_qsub.argtypes = [
1409  ctypes.POINTER(Quat),
1410  ctypes.POINTER(Quat),
1411  ctypes.POINTER(Quat)
1412 ]
1413 libamino.aa_tf_qiadd.argtypes = [ctypes.POINTER(Quat), ctypes.POINTER(Quat)]
1414 libamino.aa_tf_qisub.argtypes = [ctypes.POINTER(Quat), ctypes.POINTER(Quat)]
1415 libamino.aa_tf_qinv.argtypes = [ctypes.POINTER(Quat), ctypes.POINTER(Quat)]
1416 libamino.aa_tf_qconj.argtypes = [ctypes.POINTER(Quat), ctypes.POINTER(Quat)]
1417 libamino.aa_tf_qexp.argtypes = [ctypes.POINTER(Quat), ctypes.POINTER(Quat)]
1418 libamino.aa_tf_qln.argtypes = [ctypes.POINTER(Quat), ctypes.POINTER(Quat)]
1419 
1420 libamino.aa_tf_qrot.argtypes = [
1421  ctypes.POINTER(Quat),
1422  ctypes.POINTER(Vec3),
1423  ctypes.POINTER(Vec3)
1424 ]
1425 
1426 # rotation matrix
1427 
1428 libamino.aa_tf_rotmat_rot.argtypes = [
1429  ctypes.POINTER(RotMat),
1430  ctypes.POINTER(Vec3),
1431  ctypes.POINTER(Vec3)
1432 ]
1433 
1434 libamino.aa_tf_rotmat_mul.argtypes = [
1435  ctypes.POINTER(RotMat),
1436  ctypes.POINTER(RotMat),
1437  ctypes.POINTER(RotMat)
1438 ]
1439 
1440 libamino.aa_tf_rotmat_inv2.argtypes = [
1441  ctypes.POINTER(RotMat), ctypes.POINTER(RotMat)
1442 ]
1443 
1444 libamino.aa_tf_rotmat_lnv.argtypes = [
1445  ctypes.POINTER(RotMat), ctypes.POINTER(Vec3)
1446 ]
1447 
1448 # Transforms
1449 libamino.aa_tf_tfmat_tf.argtypes = [
1450  ctypes.POINTER(TfMat),
1451  ctypes.POINTER(Vec3),
1452  ctypes.POINTER(Vec3)
1453 ]
1454 
1455 libamino.aa_tf_qutr_tf.argtypes = [
1456  ctypes.POINTER(QuatTrans),
1457  ctypes.POINTER(Vec3),
1458  ctypes.POINTER(Vec3)
1459 ]
1460 
1461 libamino.aa_tf_duqu_tf.argtypes = [
1462  ctypes.POINTER(DualQuat),
1463  ctypes.POINTER(Vec3),
1464  ctypes.POINTER(Vec3)
1465 ]
1466 
1467 libamino.aa_tf_duqu_ln.argtypes = [
1468  ctypes.POINTER(DualQuat),
1469  ctypes.POINTER(DualQuat)
1470 ]
1471 
1472 libamino.aa_tf_duqu_norm.argtypes = [
1473  ctypes.POINTER(DualQuat),
1474  ctypes.POINTER(ctypes.c_double),
1475  ctypes.POINTER(ctypes.c_double)
1476 ]
1477 
1478 libamino.aa_tf_tfmat_mul.argtypes = [
1479  ctypes.POINTER(TfMat),
1480  ctypes.POINTER(TfMat),
1481  ctypes.POINTER(TfMat)
1482 ]
1483 
1484 libamino.aa_tf_duqu_mul.argtypes = [
1485  ctypes.POINTER(DualQuat),
1486  ctypes.POINTER(DualQuat),
1487  ctypes.POINTER(DualQuat)
1488 ]
1489 
1490 libamino.aa_tf_qutr_mul.argtypes = [
1491  ctypes.POINTER(QuatTrans),
1492  ctypes.POINTER(QuatTrans),
1493  ctypes.POINTER(QuatTrans)
1494 ]
1495 
1496 libamino.aa_tf_tfmat_inv2.argtypes = [
1497  ctypes.POINTER(TfMat), ctypes.POINTER(TfMat)
1498 ]
1499 
1500 libamino.aa_tf_duqu_conj.argtypes = [
1501  ctypes.POINTER(DualQuat),
1502  ctypes.POINTER(DualQuat)
1503 ]
1504 
1505 libamino.aa_tf_qutr_conj.argtypes = [
1506  ctypes.POINTER(QuatTrans),
1507  ctypes.POINTER(QuatTrans)
1508 ]
1509 
1510 libamino.aa_tf_qutr_conj.argtypes = [
1511  ctypes.POINTER(QuatTrans),
1512  ctypes.POINTER(QuatTrans)
1513 ]
Copy Elements mixin.
Definition: mixin.py:56
def copy_from(self, src)
Copy elements from src to self.
Definition: mixin.py:59
Mixin for matrix-like objects.
Definition: mixin.py:95
def _str_helper(self, name, m=None, n=None)
Definition: mixin.py:96
Mixin for vector-like objects.
Definition: mixin.py:88
3D rotation about an arbitrary axis
Definition: tf.py:404
def to_axang(self, a)
Converts to an axis-angle and store in a.
Definition: tf.py:444
def to_quat(self, h)
Converts to a quaternion.
Definition: tf.py:436
def normalize(self)
Ensures the axis is a unit vecto.
Definition: tf.py:431
def rotate(self, p)
Rotate a point by self.
Definition: tf.py:456
def to_rotmat(self, r)
Converts to a rotation matrix and store in.
Definition: tf.py:440
def __invert__(self)
Returns the inverse.
Definition: tf.py:449
Class for Dual Number Quaternions.
Definition: tf.py:945
def norm_parts(self)
Real and dual parts 2-norm (Euclidean)
Definition: tf.py:1006
def ln(self)
Returns the dual quaternion logarithm.
Definition: tf.py:990
def identity()
Returns the identity dual quaternion.
Definition: tf.py:997
def rotation(self, value)
Definition: tf.py:1079
def conv_from(self, src)
Converts src to a Dual Quaternion.
Definition: tf.py:963
def conj(self)
Returns the conjugate.
Definition: tf.py:979
def set_identity(self)
Set to identity.
Definition: tf.py:958
def rotation(self)
Rotation part.
Definition: tf.py:1068
def translation(self)
Translation.
Definition: tf.py:1073
def transform(self, p)
Transform point p.
Definition: tf.py:1013
def translation(self, value)
Definition: tf.py:1085
def __invert__(self)
Returns the inverse.
Definition: tf.py:985
def ensure(thing)
Ensures thing is a DualQuat.
Definition: tf.py:1002
Roll-Pitch-Yaw Euler angles.
Definition: tf.py:363
def r(self)
Roll.
Definition: tf.py:374
def r(self, value)
Definition: tf.py:378
def p(self)
Pitch.
Definition: tf.py:383
def y(self)
Yaw.
Definition: tf.py:392
def y(self, value)
Definition: tf.py:396
def p(self, value)
Definition: tf.py:387
Z-Y-X Euler angles.
Definition: tf.py:306
def z(self, value)
Definition: tf.py:355
def to_quat(self, h)
Converts to a quaternion.
Definition: tf.py:324
def x(self, value)
Definition: tf.py:337
def to_rotmat(self, r)
Converts to a rotation matrix and store in.
Definition: tf.py:328
def y(self, value)
Definition: tf.py:346
def y(self)
Y-axis rotation.
Definition: tf.py:342
def x(self)
X-axis rotation.
Definition: tf.py:333
def z(self)
Z-axis rotation.
Definition: tf.py:351
Class for Quaternion-Translation.
Definition: tf.py:1092
def transform(self, p)
Chains two Quaternion-translations.
Definition: tf.py:1147
def conj(self)
Returns the conjugate.
Definition: tf.py:1137
def __mul__(self, other)
Chains two Dual Quaternions.
Definition: tf.py:1131
def ensure(thing)
Ensures thing is a QuatTrans.
Definition: tf.py:1127
def rotation(self)
Rotation part.
Definition: tf.py:1194
def conv_from(self, src)
Converts src to quaternion-translation.
Definition: tf.py:1110
def translation(self)
Translation.
Definition: tf.py:1203
def __invert__(self)
Returns the inverse (same as conjugate)
Definition: tf.py:1143
Class for quaternions.
Definition: tf.py:468
def rotate(self, p)
Rotate a point by this quaternion.
Definition: tf.py:684
def ensure(thing)
Ensures thing is a Quat.
Definition: tf.py:515
def ln(self)
Returns the natural logarithm.
Definition: tf.py:678
def set_identity(self)
Set to identity.
Definition: tf.py:596
def conv_from(self, src)
Converts src to a quaternion.
Definition: tf.py:496
def __init__(self, arg=None)
Construct a Quat object.
Definition: tf.py:489
def normalize(self)
Normalize this object, i.e., divide by the magnitude.
Definition: tf.py:586
def conj(self)
Returns the conjugate.
Definition: tf.py:660
def scalar(self)
Returns the scalar (w) part.
Definition: tf.py:545
def exp(self)
Returns the exponential.
Definition: tf.py:672
def ssd(self, other)
Sum-square-differences of self and other.
Definition: tf.py:549
def to_quat(self, h)
Converts (copy) to a quaternion.
Definition: tf.py:519
def __invert__(self)
Returns the inverse.
Definition: tf.py:666
def identity()
Returns the identity quaternion.
Definition: tf.py:510
def minimize(self)
Converts to the minimal quaternion for the represented rotation.
Definition: tf.py:591
def vector(self)
Returns the vector (xyz) part.
Definition: tf.py:541
def to_axang(self, a)
Converts to an axis-angle and store in a.
Definition: tf.py:530
def to_rotmat(self, r)
Converts to a rotation matrix and store in.
Definition: tf.py:526
def nrm2(self)
2-norm (Euclidean) of self.
Definition: tf.py:553
def to_eulerzyx(self)
Converts to an euler zyx angle representation.
Definition: tf.py:534
def zero(self)
Set to zero.
Definition: tf.py:603
Class for rotation matrices.
Definition: tf.py:694
def to_rotmat(self, r)
Converts (copy) to a rotation matrix and store in.
Definition: tf.py:747
def to_quat(self, h)
Converts to a quaternion and store in h.
Definition: tf.py:743
def col_matrix(args)
Constructs rotation matrix from columns in args.
Definition: tf.py:814
def rotate(self, p)
Rotate a point.
Definition: tf.py:726
def rows(self)
Number of rows.
Definition: tf.py:791
def row_matrix(args)
Constructs rotation matrix from rows in args.
Definition: tf.py:801
def __mul__(self, other)
Chains two matrices.
Definition: tf.py:737
def __invert__(self)
Returns the inverse.
Definition: tf.py:763
def conv_from(self, src)
Converts src to a rotation matrix.
Definition: tf.py:713
def __init__(self, arg=None)
Construct a RotMat object.
Definition: tf.py:706
def ensure(thing)
Ensures thing is a RotMat.
Definition: tf.py:733
def cols(self)
Number of columns.
Definition: tf.py:796
def set_identity(self)
Set to identity.
Definition: tf.py:720
def isclose(self, other, tol=1e-9)
Returns True if self is within tol rotation angle to other.
Definition: tf.py:829
def ln(self)
Returns the natural logarithm.
Definition: tf.py:757
def to_axang(self, a)
Converts to an axis-angle and store in a.
Definition: tf.py:753
Class for transformation matrices.
Definition: tf.py:836
def translation(self)
Translation part.
Definition: tf.py:891
def row_matrix(args)
Constructs transformation matrix from rows in args.
Definition: tf.py:923
def __invert__(self)
Returns the inverse.
Definition: tf.py:869
def transform(self, p)
Chains two TF matrices.
Definition: tf.py:875
def __mul__(self, other)
Chains two TF matrices.
Definition: tf.py:858
def set_identity(self)
Set to identity.
Definition: tf.py:864
def conv_from(self, src)
Converts src to a transformation matrix.
Definition: tf.py:849
def rotation(self)
Rotation part.
Definition: tf.py:882
def ensure(thing)
Ensures thing is a TfMat.
Definition: tf.py:918
six-element vector with rotational and translational parts.
Definition: tf.py:1218
def from_dvec(self, vec)
Copies vec to self.
Definition: tf.py:1290
def zero(self)
Set to zero.
Definition: tf.py:1256
def to_dvec(self, vec=DVec(6))
Copies self to a vec.
Definition: tf.py:1285
def _second(self)
Definition: tf.py:1227
def __len__(self)
Number of elements in self.
Definition: tf.py:1261
def _first(self)
Definition: tf.py:1224
A rotational and translational velocity.
Definition: tf.py:1295
Length-3 vectors.
Definition: tf.py:45
def cross(self, other)
Computes the cross product.
Definition: tf.py:110
def __iadd__(self, other)
Definition: tf.py:125
def nrm2(self)
2-norm (Euclidean) of self
Definition: tf.py:87
def dot(self, other)
Computes the dot product.
Definition: tf.py:116
def __isub__(self, other)
Definition: tf.py:147
def identity()
Returns the identity Vec3.
Definition: tf.py:79
def __sub__(self, other)
Subtracts a scalar or vector from self.
Definition: tf.py:163
def to_quat(self, h)
Converts to a quaternion and copies to h.
Definition: tf.py:211
def zero(self)
Sets to zero.
Definition: tf.py:67
def ssd(self, other)
Sum-square-differences of self and other.
Definition: tf.py:83
def __rsub__(self, other)
Subtracts self or vector from self.
Definition: tf.py:168
def __init__(self, arg=None)
Constructs a Vec3 object.
Definition: tf.py:58
def ensure(thing)
Ensures thing is a Vec3.
Definition: tf.py:74
Rotation about the X axis.
Definition: tf.py:219
def to_quat(self, h)
Converts to a quaternion and store in h.
Definition: tf.py:226
def to_rotmat(self, r)
Converts to a rotation matrix and store in.
Definition: tf.py:230
def to_eulerzyx(self, e)
Converts to an Euler XYZ.
Definition: tf.py:238
def to_axang(self, a)
Converts to an axis-angle and store in a.
Definition: tf.py:234
Rotation about the Y axis.
Definition: tf.py:248
def to_rotmat(self, r)
Converts to a rotation matrix and store in.
Definition: tf.py:259
def to_eulerzyx(self, e)
Converts to an Euler XYZ and store in e.
Definition: tf.py:267
def to_quat(self, h)
Converts to a quaternion and store in h.
Definition: tf.py:255
def to_axang(self, a)
Converts to an axis-angle and store in a.
Definition: tf.py:263
Rotation about the Z axis.
Definition: tf.py:277
def to_axang(self, a)
Converts to an axis-angle and store in a.
Definition: tf.py:292
def to_eulerzyx(self, e)
Converts to an Euler XYZ and store in e.
Definition: tf.py:296
Definition: lib.py:1
Definition: mat.py:1