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]
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)
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
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
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)
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
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())]
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]
def test_vec_displacement_creates_a_new_object(self, obj): new = obj.move_vec(Vec(1, 1)) assert new is not obj
def __init__(self, points): self._points = list(Vec(*pt) for pt in points)
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):
def pos(self): x = (self.xmin + self.xmax) / 2 y = (self.ymin + self.ymax) / 2 return Vec(x, y)
def vertices(self): return (Vec(self.xmin, self.ymin), Vec(self.xmax, self.ymin), Vec(self.xmax, self.ymax), Vec(self.xmin, self.ymax))
def pos(self): return Vec(self._x, self._y)
def test_clamp(): u = Vec(3, 4) assert u.clamp(1, 10) == u assert u.clamp(10) == 2 * u assert u.clamp(2, 4) == u.normalize() * 4
def test_rotations(self): v = Vec(1, 0) assert simeq(v.rotate(pi / 2), Vec(0, 1)) assert simeq(v.rotate_at(pi / 2, Vec(1, 0)), v)