summaryrefslogtreecommitdiffstats
path: root/src/cython/_cy_affine.pyx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cython/_cy_affine.pyx736
1 files changed, 736 insertions, 0 deletions
diff --git a/src/cython/_cy_affine.pyx b/src/cython/_cy_affine.pyx
new file mode 100644
index 0000000..19aa9ef
--- /dev/null
+++ b/src/cython/_cy_affine.pyx
@@ -0,0 +1,736 @@
+from cython.operator cimport dereference as deref
+
+from numbers import Number
+
+
+cdef class cy_Affine:
+
+ """Class representing affine transform in 2D plane.
+
+ Corresponds to Affine class in 2geom.
+ """
+
+ def __cinit__(self, c0=None,
+ Coord c1=0,
+ Coord c2=0,
+ Coord c3=1,
+ Coord c4=0,
+ Coord c5=0):
+ """Create Affine instance from either transform or from coefficients."""
+ if c0 is None:
+ self.thisptr = new Affine()
+ elif is_transform(c0):
+ self.thisptr = new Affine( get_Affine(c0) )
+ else:
+ self.thisptr = new Affine(<Coord> float(c0) ,c1 ,c2 ,c3 ,c4 ,c5)
+
+ def __str__(self):
+ """str(self)"""
+ return "Affine({}, {}, {}, {}, {}, {})".format( self[0],
+ self[1],
+ self[2],
+ self[3],
+ self[4],
+ self[5],
+ )
+ def __repr__(self):
+ """repr(self)"""
+ return str(self)
+
+ def __dealloc__(self):
+ del self.thisptr
+
+ def __getitem__(self, int i):
+ """Get coefficients."""
+ if i >= 6:
+ raise IndexError("Affine has only 6 coefficients.")
+ return deref(self.thisptr) [i]
+
+ def __mul__(cy_Affine self, other):
+ """Compose with another transformation."""
+ if isinstance(other, cy_Affine):
+ return wrap_Affine( deref(self.thisptr) * deref( (<cy_Affine> other).thisptr ) )
+ elif isinstance(other, cy_Translate):
+ return wrap_Affine( deref(self.thisptr) * deref( (<cy_Translate> other).thisptr ) )
+ elif isinstance(other, cy_Scale):
+ return wrap_Affine( deref(self.thisptr) * deref( (<cy_Scale> other).thisptr ) )
+ elif isinstance(other, cy_Rotate):
+ return wrap_Affine( deref(self.thisptr) * deref( (<cy_Rotate> other).thisptr ) )
+ elif isinstance(other, cy_HShear):
+ return wrap_Affine( deref(self.thisptr) * deref( (<cy_HShear> other).thisptr ) )
+ elif isinstance(other, cy_VShear):
+ return wrap_Affine( deref(self.thisptr) * deref( (<cy_VShear> other).thisptr ) )
+ elif isinstance(other, cy_Zoom):
+ return wrap_Affine( deref(self.thisptr) * deref( (<cy_Zoom> other).thisptr ) )
+
+ def __pow__(cy_Affine self, int n, z):
+ """Compose with self n times."""
+ return wrap_Affine(pow( deref(self.thisptr), n ))
+
+ def __richcmp__(cy_Affine self, cy_Affine other, int op):
+ if op == 2:
+ return deref(self.thisptr) == deref(other.thisptr)
+ elif op == 3:
+ return deref(self.thisptr) != deref(other.thisptr)
+
+ def x_axis(self):
+ """Transformation of unit x vector without translation."""
+ return wrap_Point(self.thisptr.xAxis())
+
+ def y_axis(self):
+ """Transformation of unit y vector without translation."""
+ return wrap_Point(self.thisptr.yAxis())
+
+ def translation(self):
+ """Translation of transformation."""
+ return wrap_Point(self.thisptr.translation())
+
+ def expansion_X(self):
+ """Expansion of unit x vector."""
+ return self.thisptr.expansionX()
+
+ def expansion_Y(self):
+ """Expansion of unit y vector."""
+ return self.thisptr.expansionY()
+
+ def expansion(self):
+ """Point( self.expansion_X(), self.expansion_Y() )"""
+ return wrap_Point(self.thisptr.expansion())
+
+ def set_X_axis(self, cy_Point vec):
+ """Set transformation of x unit vector without translation."""
+ self.thisptr.setXAxis(deref( vec.thisptr ))
+
+ def set_Y_axis(self, cy_Point vec):
+ """Set transformation of y unit vector without translation."""
+ self.thisptr.setYAxis(deref( vec.thisptr ))
+
+ def set_translation(self, cy_Point loc):
+ """Set translation of origin."""
+ self.thisptr.setTranslation(deref( loc.thisptr ))
+
+ def set_expansion_X(self, Coord val):
+ """Set expansion of x unit vector."""
+ self.thisptr.setExpansionX(val)
+
+ def set_expansion_Y(self, Coord val):
+ """Set expansion of y unit vector."""
+ self.thisptr.setExpansionY(val)
+
+ def set_identity(self):
+ """Set self to identity transformation."""
+ self.thisptr.setIdentity()
+
+ def is_identity(self, Coord eps=EPSILON):
+ """Return true if self is close to identity transform.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isIdentity(eps)
+
+ def is_translation(self, Coord eps=EPSILON):
+ """Return true if self is close to transformation.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isTranslation(eps)
+
+ def is_scale(self, Coord eps=EPSILON):
+ """Return true if self is close to scale.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isScale(eps)
+
+ def is_uniform_scale(self, Coord eps=EPSILON):
+ """Return true if self is close to uniform scale.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isUniformScale(eps)
+
+ def is_rotation(self, Coord eps=EPSILON):
+ """Return true if self is close to rotation.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isRotation(eps)
+
+ def is_HShear(self, Coord eps=EPSILON):
+ """Return true if self is close to horizontal shear.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isHShear(eps)
+
+ def is_VShear(self, Coord eps=EPSILON):
+ """Return true if self is close to vertical shear.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isVShear(eps)
+
+ def is_nonzero_translation(self, Coord eps=EPSILON):
+ """Return true if self is close to translation and is identity.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isNonzeroTranslation(eps)
+
+ def is_nonzero_scale(self, Coord eps=EPSILON):
+ """Return true if self is close to scale and is identity.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isNonzeroScale(eps)
+
+ def is_nonzero_uniform_scale(self, Coord eps=EPSILON):
+ """Return true if self is close to scale and is identity.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isNonzeroUniformScale(eps)
+
+ def is_nonzero_rotation(self, Coord eps=EPSILON):
+ """Return true if self is close to rotation and is identity.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isNonzeroRotation(eps)
+
+ def is_nonzero_HShear(self, Coord eps=EPSILON):
+ """Return true if self is close to horizontal shear and is not identity.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isNonzeroHShear(eps)
+
+ def is_nonzero_VShear(self, Coord eps=EPSILON):
+ """Return true if self is close to vertical shear and is not identity.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isNonzeroVShear(eps)
+
+ def is_zoom(self, Coord eps=EPSILON):
+ """Return true if self is close to zoom.
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.isZoom(eps)
+
+ def preserves_area(self, Coord eps=EPSILON):
+ """Return true if areas are preserved after transformation
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.preservesArea(eps)
+
+ def preserves_angles(self, Coord eps=EPSILON):
+ """Return true if angles are preserved after transformation
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.preservesAngles(eps)
+
+ def preserves_distances(self, Coord eps=EPSILON):
+ """Return true if distances are preserved after transformation
+
+ Use second argument eps to specify tolerance.
+ """
+ return self.thisptr.preservesDistances(eps)
+
+ def flips(self):
+ """Return true if transformation flips - it has negative scaling."""
+ return self.thisptr.flips()
+
+ def is_singular(self, Coord eps=EPSILON):
+ """Check whether transformation matrix is singular."""
+ return self.thisptr.isSingular(eps)
+
+ def without_translation(self):
+ """Return transformation without translation part."""
+ return wrap_Affine(self.thisptr.withoutTranslation())
+
+ def inverse(self):
+ """Return inverse transformation."""
+ return wrap_Affine(self.thisptr.inverse())
+
+ def det(self):
+ """Return determinant of transformation matrix."""
+ return self.thisptr.det()
+
+ def descrim2(self):
+ """Return absolute value of self.det()"""
+ return self.thisptr.descrim2()
+
+ def descrim(self):
+ """Return square root of self.descrim2()"""
+ return self.thisptr.descrim()
+
+ @classmethod
+ def identity(self):
+ """Create identity transformation."""
+ return wrap_Affine(a_identity())
+
+ @classmethod
+ def are_near(cls, A, B, Coord eps=EPSILON):
+ """Test if two transforms are near."""
+ if is_transform(A) & is_transform(B):
+ return are_near(get_Affine(A), get_Affine(B), eps)
+
+ @classmethod
+ def reflection(cls, cy_Point vector, cy_Point origin):
+ """Create transformation reflecting along line specified by vector and origin."""
+ return wrap_Affine( reflection( deref(vector.thisptr), deref(origin.thisptr) ) )
+
+cdef cy_Affine wrap_Affine(Affine p):
+ cdef Affine * retp = new Affine()
+ retp[0] = p
+ cdef cy_Affine r = cy_Affine.__new__(cy_Affine)
+ r.thisptr = retp
+ return r
+
+cdef Affine get_Affine(t):
+ if isinstance(t, cy_Affine ):
+ return deref( (<cy_Affine> t).thisptr )
+ elif isinstance(t, cy_Translate):
+ return <Affine> deref( (<cy_Translate> t).thisptr )
+ elif isinstance(t, cy_Scale):
+ return <Affine> deref( (<cy_Scale> t).thisptr )
+ elif isinstance(t, cy_Rotate):
+ return <Affine> deref( (<cy_Rotate> t).thisptr )
+ elif isinstance(t, cy_HShear):
+ return <Affine> deref( (<cy_HShear> t).thisptr )
+ elif isinstance(t, cy_VShear):
+ return <Affine> deref( (<cy_VShear> t).thisptr )
+ elif isinstance(t, cy_Zoom):
+ return <Affine> deref( (<cy_Zoom> t).thisptr )
+
+cdef bint is_transform(t):
+ return any([isinstance(t, cy_Affine),
+ isinstance(t, cy_Translate),
+ isinstance(t, cy_Scale),
+ isinstance(t, cy_Rotate),
+ isinstance(t, cy_HShear),
+ isinstance(t, cy_VShear),
+ isinstance(t, cy_Zoom)
+ ])
+
+
+cdef class cy_Translate:
+
+ """Translation in 2D plane
+
+ Corresponds to Translate class in 2geom.
+ """
+
+ def __cinit__(self, *args):
+ """Create Translate instance form point or it's two coordinates."""
+ if len(args) == 0:
+ self.thisptr = new Translate()
+ elif len(args) == 1:
+ self.thisptr = new Translate( deref( (<cy_Point> args[0]).thisptr ) )
+ elif len(args) == 2:
+ self.thisptr = new Translate(float(args[0]), float(args[1]))
+
+ def __dealloc__(self):
+ del self.thisptr
+
+
+ def __getitem__(self, Dim2 dim):
+ """Get components of displacement vector."""
+ return deref( self.thisptr ) [dim]
+
+ def __mul__(cy_Translate self, o):
+ """Compose with another transformation."""
+ if isinstance(o, cy_Translate):
+ return wrap_Translate(deref( self.thisptr ) * deref( (<cy_Translate>o).thisptr ))
+ elif is_transform(o):
+ return wrap_Affine(deref(self.thisptr) * get_Affine(o))
+
+ def __pow__(cy_Translate self, int n, z):
+ """Compose with self n times."""
+ return wrap_Translate(pow( deref(self.thisptr), n ))
+
+ def vector(self):
+ """Get displacement vector."""
+ return wrap_Point(self.thisptr.vector())
+
+ def inverse(self):
+ """Return inverse transformation."""
+ return wrap_Translate(self.thisptr.inverse())
+
+ @classmethod
+ def identity(self):
+ """Create identity translation."""
+ return wrap_Translate(t_identity())
+
+ def __richcmp__(cy_Translate self, cy_Translate t, op):
+ if op == 2:
+ return deref(self.thisptr) == deref(t.thisptr)
+ elif op == 3:
+ return deref(self.thisptr) != deref(t.thisptr)
+
+cdef cy_Translate wrap_Translate(Translate p):
+ cdef Translate * retp = new Translate()
+ retp[0] = p
+ cdef cy_Translate r = cy_Translate.__new__(cy_Translate)
+ r.thisptr = retp
+ return r
+
+
+cdef class cy_Scale:
+
+ """Scale in 2D plane.
+
+ Corresponds to Scale in 2geom.
+ """
+
+ def __cinit__(self, *args):
+ """Create scale from number, point or it's two coordinates.
+
+ One number creates uniform scale, point or two numbers create
+ scale with different x and y scale factor.
+ """
+ if len(args) == 0:
+ self.thisptr = new Scale()
+ elif len(args) == 1:
+ if isinstance(args[0], Number):
+ self.thisptr = new Scale(<Coord> float(args[0]))
+ elif isinstance(args[0], cy_Point):
+ self.thisptr = new Scale( deref( (<cy_Point> args[0]).thisptr ) )
+ elif len(args) == 2:
+ self.thisptr = new Scale(float(args[0]), float(args[1]))
+
+ def __dealloc__(self):
+ del self.thisptr
+
+ def __getitem__(self, Dim2 d):
+ """Get scale factors for each axis."""
+ return deref( self.thisptr ) [d]
+
+ def __mul__(cy_Scale self, o):
+ """Compose with another transformation."""
+ if isinstance(o, cy_Scale):
+ return wrap_Scale(deref( self.thisptr ) * deref( (<cy_Scale>o).thisptr ))
+ elif is_transform(o):
+ return wrap_Affine(deref(self.thisptr) * get_Affine(o))
+
+ def __pow__(cy_Scale self, int n, z):
+ """Compose with self n times."""
+ return wrap_Scale(pow( deref(self.thisptr), n ))
+
+ def vector(self):
+ """Get both scale factors as a point."""
+ return wrap_Point(self.thisptr.vector())
+
+ def inverse(self):
+ """Return inverse transformation."""
+ return wrap_Scale(self.thisptr.inverse())
+
+ @classmethod
+ def identity(self):
+ """Create identity scale."""
+ return wrap_Scale(s_identity())
+
+ def __richcmp__(cy_Scale self, cy_Scale s, op):
+ if op == 2:
+ return deref(self.thisptr) == deref(s.thisptr)
+ elif op == 3:
+ return deref(self.thisptr) != deref(s.thisptr)
+
+cdef cy_Scale wrap_Scale(Scale p):
+ cdef Scale * retp = new Scale()
+ retp[0] = p
+ cdef cy_Scale r = cy_Scale.__new__(cy_Scale)
+ r.thisptr = retp
+ return r
+
+
+cdef class cy_Rotate:
+
+ """Rotation in 2D plane.
+
+ Corresponds to Rotate in 2geom.
+ """
+
+ def __cinit__(self, *args):
+ """Create new Rotate instance, specifying angle.
+
+ Use one number to set the angle, or point/its two coordinates,
+ using point's angle with x-axis as a rotation angle.
+ """
+ if len(args) == 0:
+ self.thisptr = new Rotate()
+ elif len(args) == 1:
+ if isinstance(args[0], Number):
+ self.thisptr = new Rotate(<Coord> float(args[0]))
+ elif isinstance(args[0], cy_Point):
+ self.thisptr = new Rotate( deref( (<cy_Point> args[0]).thisptr ) )
+ elif len(args) == 2:
+ self.thisptr = new Rotate(float(args[0]), float(args[1]))
+
+ def __dealloc__(self):
+ del self.thisptr
+
+ def vector(self):
+ """Return Point(1, 0)*self."""
+ return wrap_Point(self.thisptr.vector())
+
+ def __getitem__(self, Dim2 dim):
+ """Get components of self.vector()"""
+ return deref( self.thisptr ) [dim]
+
+ def __mul__(cy_Rotate self, o):
+ """Compose with another transformation."""
+ if isinstance(o, cy_Rotate):
+ return wrap_Rotate(deref( self.thisptr ) * deref( (<cy_Rotate>o).thisptr ))
+ elif is_transform(o):
+ return wrap_Affine(deref(self.thisptr) * get_Affine(o))
+
+ def __pow__(cy_Rotate self, int n, z):
+ """Compose with self n times."""
+ return wrap_Rotate(pow( deref(self.thisptr), n ))
+
+ def inverse(self):
+ """Return inverse transformation."""
+ return wrap_Rotate(self.thisptr.inverse())
+
+ @classmethod
+ def identity(cls):
+ """Create identity rotation."""
+ return wrap_Rotate(r_identity())
+
+ @classmethod
+ def from_degrees(cls, Coord deg):
+ """Create rotation from angle in degrees."""
+ return wrap_Rotate(from_degrees(deg))
+
+ def __richcmp__(cy_Rotate self, cy_Rotate r, op):
+ if op == 2:
+ return deref(self.thisptr) == deref(r.thisptr)
+ elif op == 3:
+ return deref(self.thisptr) != deref(r.thisptr)
+
+cdef cy_Rotate wrap_Rotate(Rotate p):
+ cdef Rotate * retp = new Rotate()
+ retp[0] = p
+ cdef cy_Rotate r = cy_Rotate.__new__(cy_Rotate)
+ r.thisptr = retp
+ return r
+
+
+cdef class cy_VShear:
+
+ """Vertical shear in 2D plane
+
+ Corresponds to VShear in 2geom.
+ """
+
+ def __cinit__(self, Coord h):
+ """Create VShear instance form shearing factor."""
+ self.thisptr = new VShear(h)
+
+ def __dealloc__(self):
+ del self.thisptr
+
+ def factor(self):
+ """Get shearing factor."""
+ return self.thisptr.factor()
+
+ def set_factor(self, Coord nf):
+ """Set shearing factor."""
+ self.thisptr.setFactor(nf)
+
+ def __mul__(cy_VShear self, o):
+ """Compose with another transformation."""
+ if isinstance(o, cy_VShear):
+ return wrap_VShear(deref( self.thisptr ) * deref( (<cy_VShear>o).thisptr ))
+ elif is_transform(o):
+ return wrap_Affine(deref(self.thisptr) * get_Affine(o))
+
+ def __pow__(cy_VShear self, int n, z):
+ """Compose with self n times."""
+ return wrap_VShear(pow( deref(self.thisptr), n ))
+
+ def inverse(self):
+ """Return inverse transformation."""
+ return wrap_VShear(self.thisptr.inverse())
+
+ @classmethod
+ def identity(cls):
+ """Create identity VShear."""
+ return wrap_VShear( vs_identity() )
+
+ def __richcmp__(cy_VShear self, cy_VShear hs, op):
+ if op == 2:
+ return deref(self.thisptr) == deref(hs.thisptr)
+ elif op == 3:
+ return deref(self.thisptr) != deref(hs.thisptr)
+
+
+
+cdef cy_VShear wrap_VShear(VShear p):
+ cdef VShear * retp = new VShear(0)
+ retp[0] = p
+ cdef cy_VShear r = cy_VShear.__new__(cy_VShear, 0)
+ r.thisptr = retp
+ return r
+
+cdef class cy_HShear:
+
+ """Horizontal shear in 2D plane
+
+ Corresponds to HShear in 2geom.
+ """
+
+ def __cinit__(self, Coord h):
+ """Create HShear instance form shearing factor."""
+ self.thisptr = new HShear(h)
+
+ def __dealloc__(self):
+ del self.thisptr
+
+ def factor(self):
+ """Get shearing factor."""
+ return self.thisptr.factor()
+
+ def set_factor(self, Coord nf):
+ """Set shearing factor."""
+ self.thisptr.setFactor(nf)
+
+ def __mul__(cy_HShear self, o):
+ """Compose with another transformation."""
+ if isinstance(o, cy_HShear):
+ return wrap_HShear(deref( self.thisptr ) * deref( (<cy_HShear>o).thisptr ))
+ elif is_transform(o):
+ return wrap_Affine(deref(self.thisptr) * get_Affine(o))
+
+ def __pow__(cy_HShear self, int n, z):
+ """Compose with self n times."""
+ return wrap_HShear(pow( deref(self.thisptr), n ))
+
+ def inverse(self):
+ """Return inverse transformation."""
+ return wrap_HShear(self.thisptr.inverse())
+
+ @classmethod
+ def identity(cls):
+ """Create identity HShear."""
+ return wrap_HShear( hs_identity() )
+
+ def __richcmp__(cy_HShear self, cy_HShear hs, op):
+ if op == 2:
+ return deref(self.thisptr) == deref(hs.thisptr)
+ elif op == 3:
+ return deref(self.thisptr) != deref(hs.thisptr)
+
+cdef cy_HShear wrap_HShear(HShear p):
+ cdef HShear * retp = new HShear(0)
+ retp[0] = p
+ cdef cy_HShear r = cy_HShear.__new__(cy_HShear, 0)
+ r.thisptr = retp
+ return r
+
+
+cdef class cy_Zoom:
+
+ """Zoom in 2D plane, consisting of uniform scale and translation.
+
+ Corresponds to Zoom in 2geom.
+ """
+
+ def __cinit__(self, Coord scale=1, cy_Translate translate=cy_Translate()):
+ """Create Zoom from scale factor and translation"""
+ self.thisptr = new Zoom( scale, deref( translate.thisptr ) )
+
+ def __dealloc__(self):
+ del self.thisptr
+
+ def __mul__(cy_Zoom self, cy_Zoom z):
+ """Compose with another transformation."""
+ return wrap_Zoom( deref(self.thisptr) * deref( z.thisptr ))
+
+ def __pow__(cy_Zoom self, int n, z):
+ """Compose with self n times."""
+ return wrap_Zoom(pow( deref(self.thisptr), n ))
+
+ def __richcmp__(cy_Zoom self, cy_Zoom z, op):
+ if op == 2:
+ return deref(self.thisptr) == deref(z.thisptr)
+ elif op == 3:
+ return deref(self.thisptr) != deref(z.thisptr)
+
+ def scale(self):
+ """Get scale factor."""
+ return self.thisptr.scale()
+
+ def set_scale(self, Coord s):
+ """Set scale factor."""
+ self.thisptr.setScale(s)
+
+ def translation(self):
+ """Get translation as a point."""
+ return wrap_Point(self.thisptr.translation())
+
+ def set_translation(self, cy_Point p):
+ """Set translation."""
+ self.thisptr.setTranslation(deref( p.thisptr ))
+
+ def inverse(self):
+ """Return inverse transformation."""
+ return wrap_Zoom(self.thisptr.inverse())
+
+ @classmethod
+ def identity(cls):
+ """Create identity zoom."""
+ return wrap_Zoom(z_identity())
+
+ @classmethod
+ def map_rect(self, cy_Rect old_r, cy_Rect new_r):
+ """Create zooming used to go from old rectangle to new."""
+ return wrap_Zoom(map_rect(deref( old_r.thisptr ) ,deref( new_r.thisptr )))
+
+cdef cy_Zoom wrap_Zoom(Zoom p):
+ cdef Zoom * retp = new Zoom(0)
+ retp[0] = p
+ cdef cy_Zoom r = cy_Zoom.__new__(cy_Zoom, 0)
+ r.thisptr = retp
+ return r
+
+
+cdef class cy_Eigen:
+
+ """Class computing eigenvalues and eigenvectors of 2x2 matrix.
+
+ Corresponds to Eigen class in 2geom.
+ """
+
+ cdef Eigen* thisptr
+
+ def __cinit__(self, a):
+ """Create Eigen form 2D transform or 2x2 list - matrix."""
+ cdef Affine at
+ cdef double m[2][2]
+ if is_transform(a):
+ at = get_Affine(a)
+ self.thisptr = new Eigen(at)
+ else:
+ for i in range(2):
+ for j in range(2):
+ m[i][j] = a[i][j]
+ self.thisptr = new Eigen(m)
+
+ def __dealloc__(self):
+ del self.thisptr
+
+ @property
+ def vectors(self):
+ """Eigenvectors of matrix."""
+ return (wrap_Point(self.thisptr.vectors[0]), wrap_Point(self.thisptr.vectors[1]))
+
+ @property
+ def values(self):
+ """Eigenvalues of matrix."""
+ return (self.thisptr.values[0], self.thisptr.values[1])