예제 #1
0
def center_of_mass(L):
    """
    Return the center of mass vector for a solid polygon defined by the given
    list of points.

    Example:
        >>> pts = [(0, 0), (1, 0), (1, 1), (0, 1)]
        >>> center_of_mass(pts)
        Vec(0.5, 0.5)
    """

    W = _w_list(L)
    A = sum(W)
    N = len(L)
    x_cm = 0
    y_cm = 0
    if A == 0:
        return Vec(*L[0])
    for i in range(N):
        x1, y1 = L[(i + 1) % N]
        x0, y0 = L[i]
        wi = W[i]
        x_cm += (x1 + x0) * wi / 3.0
        y_cm += (y1 + y0) * wi / 3.0
    x_cm /= A
    y_cm /= A
    return Vec(x_cm, y_cm)
예제 #2
0
    def eigenpairs(self):
        a, b, c, d = self.flat
        l1 = (d + a + self._sqrt(d * d - 2 * a * d + a * a + 4 * c * b)) / 2
        l2 = (d + a - self._sqrt(d * d - 2 * a * d + a * a + 4 * c * b)) / 2

        try:
            v1 = Vec(b / (l1 - a), 1)
        except ZeroDivisionError:
            v1 = Vec(1, 0)
        try:
            v2 = Vec(b / (l2 - a), 1)
        except ZeroDivisionError:
            v2 = Vec(1, 0)

        return [(l1, v1.normalize()), (l2, v2.normalize())]
예제 #3
0
    def intercept_point():
        '''Retorna o ponto de intercepção entre os segmentos formados por
        ``r1 - r0`` e ``v1 - v0``'''

        A = r0.x * r1.y - r0.y * r1.x
        B = v0.x * v1.y - v0.y * v1.x
        C = 1.0 / (T.x * T_.y - T.y * T_.x)
        return Vec((-A * T_.x + B * T.x) * C, (-A * T_.y + B * T.y) * C)
예제 #4
0
 def __getitem__(self, idx):
     N = len(self._data) // 2
     if idx < -N or idx >= N:
         raise IndexError(idx)
     elif idx < 0:
         idx = N + idx
     i = 2 * idx
     return Vec(*self._data[i:i + 2])
예제 #5
0
    def intercept_point():
        """
        Return intercept between segments formed by ``r1 - r0`` and ``v1 - v0``.
        """

        A = r0.x * r1.y - r0.y * r1.x
        B = v0.x * v1.y - v0.y * v1.x
        C = 1.0 / (T.x * T_.y - T.y * T_.x)
        return Vec((-A * T_.x + B * T.x) * C, (-A * T_.y + B * T.y) * C)
예제 #6
0
    def pos(self):
        pt0 = self[-1]
        M, S = 0, Vec(0, 0)

        for pt in self:
            L = (pt - pt0).norm()
            M += L
            S += (pt + pt0) * (L / 2)
            pt0 = pt
        return S / M
예제 #7
0
    def directions(self, n):
        '''Retorna a lista de direções exaustivas para o teste do SAT
        associadas ao objeto.'''

        out = []
        p0 = self._data[-1]
        for p in self._data:
            x, y = p - p0
            p0 = p
            out.append(Vec(-y, x))
        return out
예제 #8
0
def aabb_pshape(xmin=None, xmax=None,
                ymin=None, ymax=None,
                bbox=None, rect=None,
                shape=None, pos=None):
    '''
    Retorna uma tupla de (centro, shape) a partir dos parâmetros fornecidos.
    '''
    x, xmax, y, ymax = aabb_bbox(xmin, xmax, ymin, ymax,
                                 bbox, rect, shape, pos)
    center = Vec((x + xmax) / 2.0, (y + ymax) / 2.0)
    shape = (xmax - x, ymax - y)
    return center, shape
예제 #9
0
 def pos(self):
     length = 0
     vector_part = Vec(0.0, 0.0)
     pt0 = self[-1]
     for pt in self:
         delta = asvector(pt -
                          pt0).norm()  #FIXME: Point subtraction --> Vec
         middle = asvector(pt.middle(pt0))
         vector_part += delta * middle
         length += delta
         pt0 = pt
     return vector_part / length
예제 #10
0
def normals_aabb_circle(A, B):
    # Encontra o vértice mais próximo do centro
    D = float('inf')
    pt = Vec(0, 0)
    for v in A.vertices:
        delta = B.pos - v
        dnew = delta.norm()
        if dnew < D:
            D = dnew
            pt = delta

    return [pt.normalized(), e1, e2]
예제 #11
0
def aabb_center(xmin=None,
                xmax=None,
                ymin=None,
                ymax=None,
                rect=None,
                shape=None,
                pos=None):
    """
    Return AABB's center position vector from given parameters.
    """

    xmin, xmax, ymin, ymax = aabb_coords(xmin, ymin, xmax, ymax, rect, shape,
                                         pos)
    return Vec((xmin + xmax) / 2, (ymin + ymax) / 2)
예제 #12
0
    def __init__(self, N, length, theta=None, pos=None):
        alpha = pi / N
        R = Rotation2d(2 * alpha)
        p = Vec(length / (2 * sin(alpha)), 0)
        vertices = []
        for _ in range(N):
            vertices.append(p)
            p = R * p
        super(RegularPolyAny, self).__init__(vertices)

        # Altera posição e ângulo
        if pos is not None:
            self += pos
        if theta is not None:
            self.rotate(theta)
예제 #13
0
def aabb_pshape(xmin=None,
                xmax=None,
                ymin=None,
                ymax=None,
                rect=None,
                shape=None,
                pos=None):
    """
    Return AABB's (pos, shape) from given parameters.
    """

    x, xmax, y, ymax = aabb_coords(xmin, xmax, ymin, ymax, rect, shape, pos)
    center = Vec((x + xmax) / 2.0, (y + ymax) / 2.0)
    shape = (xmax - x, ymax - y)
    return center, shape
예제 #14
0
def convex_hull(points):
    '''Retorna a envoltória convexa do conjunto de pontos fornecidos.

    Implementa o algorítimo da cadeia monótona de Andrew, O(n log n)

    Exemplo
    -------

    >>> hull = convex_hull([(0, 0), (1, 1), (1, 0), (0, 1), (0.5, 0.5)])
    >>> hull == [(0, 0), (1, 0), (1, 1), (0, 1)]
    True
    '''

    # Ordena os pontos pela coordenada x, depois pela coordenada y
    points = sorted(set(map(tuple, points)))
    points = [Vec(*pt) for pt in points]
    if len(points) <= 1:
        return points

    # Cria a lista L: lista com os vértices da parte inferior da envoltória
    #
    # Algoritimo: acrescenta os pontos de points em L e a cada novo ponto
    # remove o último caso não faça uma volta na direção anti-horária
    L = []
    for p in points:
        while len(L) >= 2 and (L[-1] - L[-2]).cross(p - L[-2]) <= 0:
            L.pop()
        L.append(p)

    # Cria a lista U: vértices da parte superior
    # Semelhante à anterior, mas itera sobre os pontos na ordem inversa
    U = []
    for p in reversed(points):
        while len(U) >= 2 and (U[-1] - U[-2]).cross(p - U[-2]) <= 0:
            U.pop()
        U.append(p)

    # Remove o último ponto de cada lista, pois ele se repete na outra
    return L[:-1] + U[:-1]
예제 #15
0
def center_of_mass(L):
    '''Calcula o vetor centro de massa de um polígono definido por uma lista de
    pontos.

    >>> pontos = [(0, 0), (1, 0), (1, 1), (0, 1)]
    >>> center_of_mass(pontos)
    Vec(0.5, 0.5)
    '''

    W = _w_list(L)
    A = sum(W)
    N = len(L)
    x_cm = 0
    y_cm = 0
    for i in range(N):
        x1, y1 = L[(i + 1) % N]
        x0, y0 = L[i]
        wi = W[i]
        x_cm += (x1 + x0) * wi / 3.0
        y_cm += (y1 + y0) * wi / 3.0
    x_cm /= A
    y_cm /= A
    return Vec(x_cm, y_cm)
예제 #16
0
def convex_hull(points):
    """
    Convex hull for the list of points.

    Uses Andrew's monotonic chain algorithm in O(n log n).

    Example:
        >>> hull = convex_hull([(0, 0), (1, 1), (1, 0), (0, 1), (0.5, 0.5)])
        >>> hull == [(0, 0), (1, 0), (1, 1), (0, 1)]
        True
    """

    # Lexicographical sort
    points = sorted(set(map(tuple, points)))
    points = [Vec(*pt) for pt in points]
    if len(points) <= 1:
        return points

    # L: lower vertices
    # Adds points to L if the result preserves an counter-clockwise direction.
    L = []
    for p in points:
        while len(L) >= 2 and (L[-1] - L[-2]).cross(p - L[-2]) <= 0:
            L.pop()
        L.append(p)

    # U: upper vertices
    # Similar as before, but iterates in the opposite order.
    U = []
    for p in reversed(points):
        while len(U) >= 2 and (U[-1] - U[-2]).cross(p - U[-2]) <= 0:
            U.pop()
        U.append(p)

    # Remove last point since it is duplicated
    return L[:-1] + U[:-1]
예제 #17
0
def test_rows():
    M1 = Mat([1, 2], [3, 4], [5, 6])
    assert list(M1.rows()) == [Vec(1, 2), Vec(3, 4), Vec(5, 6)]
예제 #18
0
def test_cols():
    M1 = Mat([1, 2], [3, 4], [5, 6])
    assert list(M1.cols()) == [Vec(1, 3, 5), Vec(2, 4, 6)]
예제 #19
0
 def test_identity_solve(self, I, N):
     b = Vec(*range(1, N + 1))
     assert I.solve(b) == b
     assert I.solve_jacobi(b) == b
     assert I.solve_gauss(b) == b
     assert I.solve_triangular(b) == b
예제 #20
0
 def vertices(self):
     return (Vec(self.xmin, self.ymin), Vec(self.xmax, self.ymin),
             Vec(self.xmax, self.ymax), Vec(self.xmin, self.ymax))
예제 #21
0
 def pos(self):
     x = (self.xmin + self.xmax) / 2
     y = (self.ymin + self.ymax) / 2
     return Vec(x, y)
예제 #22
0
 def __init__(self, points):
     self._points = list(Vec(*pt) for pt in points)
예제 #23
0
 def pos(self):
     return Vec(self._x, self._y)
예제 #24
0
 def move(self, x_or_delta, y=None):
     if y is not None:
         x_or_delta = Vec(x_or_delta, y)
     self._data[:] = [u + x_or_delta for u in self._data]
예제 #25
0
def test_droppingrow():
    M1 = Mat([1, 2], [3, 4], [5, 6])
    M2 = Mat([1, 2], [5, 6])
    assert M1.drop_row(1) == (M2, Vec(3, 4))
예제 #26
0
from smallshapes import Convex
from smallvectors import dot, Vec
from smallvectors.core.mutability import Mutable, Immutable

direction_x = Vec(1, 0)
direction_y = Vec(0, 1)


class AABBAny(Convex):
    """
    Base class for AABB and mAABB.
    """

    __slots__ = ('xmin', 'xmax', 'ymin', 'ymax')

    _vec = Vec[2, float]

    @property
    def pos(self):
        x = (self.xmin + self.xmax) / 2
        y = (self.ymin + self.ymax) / 2
        return self._vec(x, y)

    @property
    def vertices(self):
        vec = self._vec
        return (vec(self.xmin, self.ymin), vec(self.xmax, self.ymin),
                vec(self.xmax, self.ymax), vec(self.xmin, self.ymax))

    @property
    def cbb_radius(self):
예제 #27
0
def test_droppingcol():
    M1 = Mat([1, 2], [3, 4], [5, 6])
    M2 = Mat([1], [3], [5])
    assert M1.drop_col(1) == (M2, Vec(2, 4, 6))
예제 #28
0
 def test_vec_displacement_creates_a_new_object(self, obj):
     new = obj.move_vec(Vec(1, 1))
     assert new is not obj
예제 #29
0
 def insert(self, idx, value):
     self._data.insert(idx, Vec(value))
예제 #30
0
 def standing_object_has_heading(self, obj):
     obj.vel *= 0
     assert obj.heading == Vec(1, 0)