Esempio n. 1
0
    def __truediv__(self, scalar):
        '''Returns a new instance where all the moments are divided by a scalar.'''
        return type(self)(self.m0 / scalar, self.m1 / scalar, self.m2 / scalar)


def moments_from_pointlist(pl):
    '''Constructs a Moments object from a list of points.

    Parameters
    ----------
    pl : PointList
        list of points from which the moments are computed

    Returns
    -------
    Moments, Moments2d or Moments3d
        raw moments of the point list, depending on the value of `ndim` provided
    '''
    arr = pl.points
    m0 = len(arr)
    m1 = arr.sum(axis=0)
    m2 = np.dot(arr.T, arr)
    if arr.shape[1] == 2:
        return Moments2d(m0, m1, m2)
    if arr.shape[1] == 3:
        return Moments3d(m0, m1, m2)
    return Moments(m0, m1, m2)


_bc.register_cast(PointList, Moments, moments_from_pointlist)
Esempio n. 2
0
    points : `numpy.ndarray(shape=(N,2))`
        The list of 2D vertices in numpy.
    '''

    # ----- internal representations -----

    @property
    def shapely(self):
        '''Shapely representation for fast intersection operations.'''
        if not hasattr(self, '_shapely'):
            import shapely.geometry as _sg
            self._shapely = _sg.Polygon(self.points)
            self._shapely = self._shapely.buffer(
                0.0001
            )  # to clean up any (multi and/or non-simple) polygon into a simple polygon
        return self._shapely


_bc.register_castable(np.ndarray, Polygon,
                      lambda x: castable_ndarray_PointList(x, 2))
_bc.register_cast(np.ndarray, Polygon, lambda x: Polygon(x, check=False))

_bc.register_cast(PointList2d, Polygon,
                  lambda x: Polygon(x.points, check=False))

# ----- joining volumes -----

register_join_volume(Rect, Polygon, join_volume_shapely)
register_join_volume(Polygon, Rect, join_volume_shapely)
register_join_volume(Polygon, Polygon, join_volume_shapely)
Esempio n. 3
0
    def multiply(self, other):
        if not isinstance(other, Sim2d):
            return super(Sim2d, self).__mul__(other)
        return Sim2d(
            self << other.offset,
            self.scale * other.scale,
            self.angle - other.angle if self.on else self.angle + other.angle,
            not self.on != (not other.on)  # fastest xor
        )

    multiply.__doc__ = Dliso.multiply.__doc__

    def invert(self):
        invScale = 1 / self.scale
        invAngle = self.angle if self.on else -self.angle
        mat = Sim2d.get_linear(invAngle, self.on, invScale)
        return Sim2d(np.dot(mat, -self.offset), invScale, invAngle, self.on)

    invert.__doc__ = Dliso.invert.__doc__


# ----- casting -----

_bc.register_cast(
    Sim2d, Dliso,
    lambda x: Dliso(offset=x.offset, scale=x.scale, unitary=x.unitary))
_bc.register_cast(
    Sim2d, Aff2d,
    lambda x: Aff2d(offset=x.offset, linear=Lin2d.from_matrix(x.linear)))
Esempio n. 4
0
                     ],
                     removed_version="0.6.0",
                     docstring_prefix="        ")
    def from_bounding_rect(x):
        '''Returns an axis-aligned ellipse bounded by the given axis-aligned rectangle x.'''
        if not isinstance(x, Rect):
            raise ValueError("Input type must be a `Rect`, '{}' given.".format(
                x.__class__))
        return Ellipse(
            Aff2d(linear=Lin2d(scale=[x.w / 2, x.h / 2]), offset=x.center_pt))


# ----- casting -----

register_cast(
    Ellipse, Hyperellipsoid,
    lambda x: Hyperellipsoid(cast(x.aff_tfm, Aff), make_normalised=False))
register_cast(Hyperellipsoid, Ellipse,
              lambda x: Ellipse(cast(x.aff_tfm, Aff2d), make_normalised=False))
register_castable(Hyperellipsoid, Ellipse, lambda x: x.ndim == 2)


def cast_Ellipse_to_Moments2d(obj):
    '''Extracts Moments2d from an Ellipse instance.'''
    a = np.pi / 4
    moments = Moments2d(np.pi, [0, 0],
                        [[a, 0], [0, a]])  # unit circle's moments
    return transform(obj.aff_tfm, moments)  # transform


register_cast(Ellipse, Moments2d, cast_Ellipse_to_Moments2d)
Esempio n. 5
0
    det.__doc__ = Aff.det.__doc__

    # ----- methods -----

    def __init__(self, offset=np.zeros(2), linear=Lin2d()):
        self.offset = offset
        self.linear = linear

    def __repr__(self):
        return "Aff2d(offset={}, linear={})".format(self.offset, self.linear)


# ----- casting -----

_bc.register_cast(
    Aff2d, Aff,
    lambda x: Aff(weights=x.weight, bias=x.offset, check_shapes=False))
_bc.register_cast(
    Aff, Aff2d,
    lambda x: Aff2d(offset=x.bias, linear=Lin2d.from_matrix(x.weight)))
_bc.register_castable(Aff, Aff2d, lambda x: x.ndim == 2)

# ----- transform functions -----


def transform_Aff2d_on_Moments2d(aff_tfm, moments):
    '''Transform a Moments2d using a 2D affine transformation.

    Parameters
    ----------
    aff_tfm : Aff2d
Esempio n. 6
0
'''Raw moments up to 2nd order of 3D points.'''

from mt import np
import sys as _sys

import mt.base.casting as _bc

from ..geo import ThreeD
from ..geond import Moments, moments_from_pointlist
from .point_list import PointList3d


__all__ = ['Moments3d']


class Moments3d(ThreeD, Moments):
    '''Raw moments up to 2nd order of points living in 3D. See Moments for more details.'''

    def __repr__(self):
        return "Moments3d(m0={}, mean={}, cov={})".format(self.m0, self.mean, self.cov.tolist())
_bc.register_cast(Moments3d, Moments, lambda x: Moments(x.m0, x.m1, x.m2))
_bc.register_cast(Moments, Moments3d, lambda x: Moments3d(x.m0, x.m1, x.m2))
_bc.register_castable(Moments, Moments3d, lambda x: x.ndim==3)


_bc.register_cast(PointList3d, Moments3d, moments_from_pointlist)
Esempio n. 7
0
'''The base class to represent a point. 

For efficiency reasons, please try to bunch points into arrays or lists and use appropriate representations instead of using single points implemented here.
'''

import numpy as np
import mt.base.casting as _bc
from ..geo import TwoD
from ..geond import Point, castable_ndarray_Point

__all__ = ['Point2d']


class Point2d(TwoD, Point):
    '''A 2D point. See Point for more details.'''
    pass


_bc.register_castable(np.ndarray, Point2d,
                      lambda x: castable_ndarray_Point(x, 2))
_bc.register_cast(np.ndarray, Point2d, lambda x: Point2d(x, check=False))
_bc.register_cast(Point2d, Point, lambda x: Point(x.point, check=False))
_bc.register_cast(Point, Point2d, lambda x: Point2d(x.point, check=False))
_bc.register_castable(Point, Point2d, lambda x: x.ndim == 2)
Esempio n. 8
0
    def multiply(self, other):
        if not isinstance(other, Dlt):
            return super(Dlt, self).multiply(other)
        return Dlt(self << other.offset, self.scale*other.scale)
    multiply.__doc__ = Aff.multiply.__doc__

    def invert(self):
        return Dlt(-self.offset/self.scale, 1/self.scale)
    invert.__doc__ = Aff.invert.__doc__


# ----- casting -----


_bc.register_cast(Dlt, Aff, lambda x: Aff(weight=x.weight, bias=x.bias, check_shapes=False))
_bc.register_cast(Aff, Dlt, lambda x: Dlt(offset=x.bias, scale=np.diagonal(x.weight)))
_bc.register_castable(Aff, Dlt, lambda x: np.count_nonzero(x.weight - np.diag(np._diagonal(x.weight))) > 0)


# ----- transform functions -----


def transform_Dlt_on_Moments(dlt_tfm, moments):
    '''Transform the Moments using an affine transformation.

    Parameters
    ----------
    dlt_tfm : Dlt
        general dilatation
    moments : Moments
Esempio n. 9
0
        """
        if u == 0:  # special case, deform to translation only
            return Dltra(offset=v)  # scale == 1
        s = math.exp(u)
        t = ((s - 1) / u) * v
        return Dltra(offset=t, scale=s)

    def pow(self, k: float):
        """Raises the Dltra to a scalar power."""
        u, v = self.logm()
        return Dltra.expm(u * k, v * k)


# ----- casting -----

_bc.register_cast(Dltra, Dliso,
                  lambda x: Dliso(offset=x.offset, scale=x.scale))
_bc.register_cast(
    Dltra,
    Dlt,
    lambda x: Dlt(offset=x.offset, scale=np.diag(x.scale), check_shapes=False),
)

# ----- approximation ------


def approx_Dliso_to_Dltra(obj):
    """Approximates an Dliso instance with a Dltra by ignoring the unitary part."""
    return Dltra(offset=obj.offset, scale=obj.scale)


register_approx(Dliso, Dltra, approx_Dliso_to_Dltra)
Esempio n. 10
0
    Returns
    -------
    Momens2d
        th ecollection of moments up to 2nd order

    Examples
    --------
    >>> from mt.geo2d.polygon_integral import to_moments2d
    >>> import mt.geo2d.polygon as mp
    >>> poly = mp.Polygon([[3,3],[2,2],[3,1]])
    >>> m = to_moments2d(poly)
    >>> round(m.m0, 3)
    -1.0
    >>> round(m.m1.sum(), 3)
    -4.667
    >>> round(m.m2.sum(), 3)
    -22.0
    >>> round(m.mean.sum(), 3)
    4.667
    >>> round(m.cov.sum(), 3)
    -22.444
    '''
    m0 = signed_area(poly)
    m1 = [moment_x(poly), moment_y(poly)]
    mxy = moment_xy(poly)
    m2 = [[moment_xx(poly), mxy], [mxy, moment_yy(poly)]]
    return Moments2d(m0, m1, m2)


_bc.register_cast(Polygon, Moments2d, to_moments2d)
Esempio n. 11
0
    @property
    def center_pt(self):
        '''center point'''
        return self.dlt_tfm.offset

    @property
    def size(self):
        '''box size'''
        return np.abs(self.dlt_tfm.scale * 2)

    # ----- methods -----

    def __init__(self, offset_or_dltra, scale=1):
        if isinstance(min_coords, Dltra):
            self.dltra_tfm = offset_or_dltra
        else:
            self.dltra_tfm = Dltra(offset=offset_or_dltra, scale=scale)

    def __repr__(self):
        return "Hypercube({})".format(self.dltra_tfm)


# ----- casting -----

register_cast(Hypercube, Hyperbox, lambda x: Hyperbox(cast(x.dltra_tfm, Dlt)))

# ----- approximation ------

register_approx(Hyperbox, Hypercube,
                lambda x: Hypercube(approx(x.dlt_tfm, Dltra)))
Esempio n. 12
0
    @property
    def surface_area(self):
        '''The surface area of the ellipsoid.'''
        raise NotImplementedError(
            "It's quite complicated to compute the surface area of an ellipsoid. I will only be implemented when there's a real demand. MT has to check with the Wiki page first."
        )

    def normalised(self):
        '''Returns an equivalent ellipsoid where f1, f2 and f3 are perpendicular (linearly independent).'''
        return Ellipsoid(self.aff_tfm, make_normalised=True)


# ----- casting -----

register_cast(Ellipsoid, Hyperellipsoid,
              lambda x: Hyperellipsoid(x.aff_tfm, make_normalised=False))
register_cast(Hyperellipsoid, Ellipsoid,
              lambda x: Ellipsoid(x.aff_tfm, make_normalised=False))
register_castable(Hyperellipsoid, Ellipsoid, lambda x: x.ndim == 3)

# ----- bounding -----


def upper_bound_Ellipsoid_to_Box(obj):
    '''Returns a bounding axis-aligned box of the ellipsoid.

    Parameters
    ----------
    obj : Ellipsoid
        the ellipsoid to be upper-bounded
Esempio n. 13
0
    @property
    def bias_dim(self):
        '''Returns the dimension of the bias vector. Raises ValueError if it is not 3.'''
        if self.bias.shape[0] != 3:
            raise ValueError("Expected bias dim to be 3, but seeing {}.".format(self.bias.shape[0]))

    # ----- methods -----

    def __repr__(self):
        return "Aff3d(weight_diagonal={}, bias={})".format(self.weight.diagonal(), self.bias)


# ----- casting -----


_bc.register_cast(Aff3d, Aff, lambda x: Aff(weights=x.weight, bias=x.offset, check_shapes=False))
_bc.register_cast(Aff, Aff3d, lambda x: Aff3d(weight=x.weight, bias=x.bias, check_shape=False))
_bc.register_castable(Aff, Aff3d, lambda x: x.ndim==3)


# ----- transform functions -----


def transform_Aff3d_on_Moments3d(aff_tfm, moments):
    '''Transform a Moments3d using a 3D affine transformation.

    Parameters
    ----------
    aff_tfm : Aff3d
        3D affine transformation
    moments : Moments3d
Esempio n. 14
0
'''The base class to represent a list of points.'''

import numpy as np
import mt.base.casting as _bc
from ..geo import ThreeD
from ..geond import PointList, castable_ndarray_PointList

__all__ = ['PointList3d']


class PointList3d(ThreeD, PointList):
    '''A list of 3D points. See PointList for more details.'''
    pass


_bc.register_castable(np.ndarray, PointList3d,
                      lambda x: castable_ndarray_PointList(x, 3))
_bc.register_cast(np.ndarray, PointList3d,
                  lambda x: PointList3d(x, check=False))
_bc.register_cast(PointList3d, PointList,
                  lambda x: PointList(x.points, check=False))
_bc.register_cast(PointList, PointList3d,
                  lambda x: PointList3d(x.points, check=False))
_bc.register_castable(PointList, PointList3d, lambda x: x.ndim == 3)
Esempio n. 15
0
        self.unitary = unitary

    def __repr__(self):
        return "Iso(offset={}, unitary_diagonal={})".format(
            self.offset, self.unitary.diagonal())

    # ----- base adaptation -----

    def multiply(self, other):
        if not isinstance(other, Iso):
            return super(Iso, self).__mul__(other)
        return Iso(offset=self << other.offset,
                   unitary=np.dot(self.unitary, other.unitary))

    multiply.__doc__ = Dliso.multiply.__doc__

    def invert(self):
        invUnitary = np.linalg.inv(
            self.unitary
        )  # slow, and assuming the unitary matrix is invertible
        return Iso(offset=np.dot(invUnitary, -self.offset), unitary=invUnitary)

    invert.__doc__ = Dliso.invert.__doc__


# ----- casting -----

_bc.register_cast(Iso, Dliso,
                  lambda x: Dliso(offset=x.offset, unitary=x.unitary))
_bc.register_cast(Iso, Aff, lambda x: Aff(bias=x.offset, weight=x.weight))