Пример #1
0
def asvector(v):
    '''Retorna o objeto como uma instância da classe Vetor'''

    if isinstance(v, Vec2):
        return v
    else:
        return Vec2.from_seq(v)
Пример #2
0
    def __init__(self, data):
        '''Implementa um array de vetores bidimensionais. As operações
        matemáticas podem ser aplicadas diretamente ao array

        Exemplo
        -------

        Criamos um array inicializando com uma lista de vetores ou uma lista
        de duplas

        >>> a = VecArray([(0, 0), (1, 0), (0, 1)]); a
        VecArray([(0, 0), (1, 0), (0, 1)])

        Sob muitos aspectos, um VecArray funciona como uma lista de vetores

        >>> a[0], a[1]
        (Vec2(0, 0), Vec2(1, 0))

        As operações matemáticas ocorrem termo a termo

        >>> a + (1, 1)
        VecArray([(1, 1), (2, 1), (1, 2)])

        Já as funções de vetores são propagadas para cada elemento e retornam
        um Array numérico ou um VecArray

        >>> a.norm()
        Array([0, 1, 1])
        '''

        self._data = list(Vec2(x) for x in data)
Пример #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 Vec2((-A * T_.x + B * T.x) * C, (-A * T_.y + B * T.y) * C)
Пример #4
0
    def rotate(self, theta, axis=None):
        '''Retorna um vetor rotacionado por um ângulo theta'''

        axis = Vec2(axis)
        R = RotMat2(theta)
        if axis is None:
            return VecArray([R * u for u in self._data])
        else:
            v = axis
            return VecArray([v + R * (u - v) for u in self._data])
Пример #5
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(Vec2(-y, x))
        return out
Пример #6
0
def normals_aabb_circle(A, B):
    # Encontra o vértice mais próximo do centro
    D = float('inf')
    pt = Vec2(0, 0)
    for v in A.vertices:
        delta = B.pos - v
        dnew = delta.norm()
        if dnew < D:
            D = dnew
            pt = delta

    return [pt.normalize(), e1, e2]
Пример #7
0
    def __init__(self, N, length, theta=None, pos=None):
        alpha = pi / N
        R = RotMat2(2 * alpha)
        p = Vec2(length / (2 * sin(alpha)), 0)
        vertices = []
        for _ in range(N):
            vertices.append(p)
            p = R * p
        super(RegularPoly, self).__init__(vertices)

        # Altera posição e ângulo
        if pos is not None:
            self += pos
        if theta is not None:
            self.irotate(theta)
Пример #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 = Vec2((x + xmax) / 2.0, (y + ymax) / 2.0)
    shape = (xmax - x, ymax - y)
    return center, shape
Пример #9
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
    -------

    >>> convex_hull([(0, 0), (1, 1), (1, 0), (0, 1), (0.5, 0.5)])
    [Vec2(0, 0), Vec2(1, 0), Vec2(1, 1), Vec2(0, 1)]
    '''

    # Ordena os pontos pela coordenada x, depois pela coordenada y
    points = sorted(set(map(tuple, points)))
    points = [Vec2(*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]
Пример #10
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)
    Vec2(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 Vec2(x_cm, y_cm)
Пример #11
0
# -*- coding: utf8 -*-

import cython as C
from mathtools import Vec2, dot
from mathtools.shapes import Circle
from mathtools.util import pyinject
if not C.compiled:
    import mathtools.mathfuncs as m

__all__ = [
    'AABB', 'aabb_rect', 'aabb_bbox', 'aabb_pshape', 'aabb_shape',
    'aabb_center'
]

dir_x = Vec2(1, 0)
dir_y = Vec2(0, 1)


class AABB(object):
    '''Representa uma caixa de contorno retangular alinhada aos eixos.

    Atributos
    ---------

    xmin, xmax, ymin, ymax
        Limites da AABB
    bbox
        Tupla com (xmin, xmax, ymin, ymax)
    shape
        Tupla com (largura, altura)
    pos
Пример #12
0
 def __init__(self, point1, point2):
     self._point1 = Vec2(point1)
     self._point2 = Vec2(point2)
Пример #13
0
 def __init__(self, radius, pos=(0, 0)):
     self.radius = radius
     self.pos = Vec2(*pos)
Пример #14
0
 def vertices(self):
     return (Vec2(self.xmin, self.ymin), Vec2(self.xmax, self.ymin),
             Vec2(self.xmax, self.ymax), Vec2(self.xmin, self.ymax))
Пример #15
0
 def __iter__(self):
     return iter(Vec2(u) for u in self._data)
Пример #16
0
 def pos_nw(self):
     return Vec2(self.xmin, self.ymax)
Пример #17
0
 def pos_ne(self):
     return Vec2(self.xmax, self.ymax)
Пример #18
0
 def pos_sw(self):
     return Vec2(self.xmin, self.ymin)
Пример #19
0
 def pos_se(self):
     return Vec2(self.xmax, self.ymin)
Пример #20
0
    def __getitem__(self, i):
        '''x.__getitem__(i) <==> x[i]'''

        return Vec2(self._data[i])
Пример #21
0
 def insert(self, idx, value):
     self._data.insert(idx, Vec2(value))
Пример #22
0
    def __add__(self, other):
        '''x.__add__(y) <==> x + y'''

        other = Vec2(other)
        return self._new(u + other for u in self._data)
Пример #23
0
    def __rsub__(self, other):
        '''x.__rsub__(y) <==> y - x'''

        other = Vec2(other)
        return self._new(other - u for u in self._data)
Пример #24
0
    def __sub__(self, other):
        '''x.__sub__(y) <==> x - y'''

        other = Vec2(other)
        return self._new(u - other for u in self._data)
Пример #25
0
 def pos(self):
     x = (self.xmin + self.xmax) / 2
     y = (self.ymin + self.ymax) / 2
     return Vec2(x, y)
Пример #26
0
'''
Implementa o separating axis theorem (sat) para detecção de colisão entre as
formas de colisão básicas.
'''
from FGAme.util.multidispatch import multifunction
from mathtools import Vec2
from mathtools.shapes import Circle, AABB

e1 = Vec2(1, 0)
e2 = Vec2(0, 1)

###############################################################################
#                         Cálculo de sombras
###############################################################################


@multifunction(None, None)
def shadow(A, normal):
    return A.shadow(normal)


@multifunction(AABB, None)
def shadow_aabb(A, normal):
    if normal is e1:
        return A.xmin, A.xmax
    elif normal is e2:
        return A.ymin, A.ymax
    else:
        return A.shadow(normal)