feat(sim): geometry primitives and collision math
This commit is contained in:
1 parent
ed564f1e37
commit
990fd2dd0e
2 files changed
+170
No files matched your search
@@ -0,0 +1,156 @@
|
||||
import math
|
||||
|
||||
|
||||
class Vec2:
|
||||
__slots__ = ("x", "y")
|
||||
|
||||
def __init__(self, x=0.0, y=0.0):
|
||||
self.x = float(x)
|
||||
self.y = float(y)
|
||||
|
||||
def copy(self):
|
||||
return Vec2(self.x, self.y)
|
||||
|
||||
def set(self, x, y):
|
||||
self.x = float(x)
|
||||
self.y = float(y)
|
||||
return self
|
||||
|
||||
def add(self, other):
|
||||
return Vec2(self.x + other.x, self.y + other.y)
|
||||
|
||||
def sub(self, other):
|
||||
return Vec2(self.x - other.x, self.y - other.y)
|
||||
|
||||
def scale(self, factor):
|
||||
return Vec2(self.x * factor, self.y * factor)
|
||||
|
||||
def length(self):
|
||||
return math.hypot(self.x, self.y)
|
||||
|
||||
def lengthSq(self):
|
||||
return self.x * self.x + self.y * self.y
|
||||
|
||||
def normalized(self):
|
||||
mag = self.length()
|
||||
if mag == 0.0:
|
||||
return Vec2(0.0, 0.0)
|
||||
return Vec2(self.x / mag, self.y / mag)
|
||||
|
||||
def distanceTo(self, other):
|
||||
return math.hypot(self.x - other.x, self.y - other.y)
|
||||
|
||||
def asTuple(self):
|
||||
return (self.x, self.y)
|
||||
|
||||
def __repr__(self):
|
||||
return "Vec2(%.3f, %.3f)" % (self.x, self.y)
|
||||
|
||||
|
||||
class Aabb:
|
||||
__slots__ = ("x", "y", "w", "h")
|
||||
|
||||
def __init__(self, x, y, w, h):
|
||||
self.x = float(x)
|
||||
self.y = float(y)
|
||||
self.w = float(w)
|
||||
self.h = float(h)
|
||||
|
||||
@property
|
||||
def left(self):
|
||||
return self.x
|
||||
|
||||
@property
|
||||
def right(self):
|
||||
return self.x + self.w
|
||||
|
||||
@property
|
||||
def top(self):
|
||||
return self.y
|
||||
|
||||
@property
|
||||
def bottom(self):
|
||||
return self.y + self.h
|
||||
|
||||
@property
|
||||
def centerX(self):
|
||||
return self.x + self.w * 0.5
|
||||
|
||||
@property
|
||||
def centerY(self):
|
||||
return self.y + self.h * 0.5
|
||||
|
||||
@property
|
||||
def center(self):
|
||||
return Vec2(self.centerX, self.centerY)
|
||||
|
||||
def copy(self):
|
||||
return Aabb(self.x, self.y, self.w, self.h)
|
||||
|
||||
def moved(self, dx, dy):
|
||||
return Aabb(self.x + dx, self.y + dy, self.w, self.h)
|
||||
|
||||
def intersects(self, other):
|
||||
return (
|
||||
self.left < other.right
|
||||
and self.right > other.left
|
||||
and self.top < other.bottom
|
||||
and self.bottom > other.top
|
||||
)
|
||||
|
||||
def touches(self, other):
|
||||
return (
|
||||
self.left <= other.right
|
||||
and self.right >= other.left
|
||||
and self.top <= other.bottom
|
||||
and self.bottom >= other.top
|
||||
)
|
||||
|
||||
def containsPoint(self, px, py):
|
||||
return self.left <= px <= self.right and self.top <= py <= self.bottom
|
||||
|
||||
def overlapArea(self, other):
|
||||
overlapX = min(self.right, other.right) - max(self.left, other.left)
|
||||
overlapY = min(self.bottom, other.bottom) - max(self.top, other.top)
|
||||
if overlapX <= 0.0 or overlapY <= 0.0:
|
||||
return 0.0
|
||||
return overlapX * overlapY
|
||||
|
||||
def inflated(self, marginX, marginY):
|
||||
return Aabb(
|
||||
self.x - marginX,
|
||||
self.y - marginY,
|
||||
self.w + marginX * 2.0,
|
||||
self.h + marginY * 2.0,
|
||||
)
|
||||
|
||||
def asTuple(self):
|
||||
return (self.x, self.y, self.w, self.h)
|
||||
|
||||
def asIntRect(self):
|
||||
return (int(self.x), int(self.y), int(self.w), int(self.h))
|
||||
|
||||
def __repr__(self):
|
||||
return "Aabb(%.2f, %.2f, %.2f, %.2f)" % (self.x, self.y, self.w, self.h)
|
||||
|
||||
|
||||
def clamp(value, low, high):
|
||||
if value < low:
|
||||
return low
|
||||
if value > high:
|
||||
return high
|
||||
return value
|
||||
|
||||
|
||||
def sign(value):
|
||||
if value > 0:
|
||||
return 1
|
||||
if value < 0:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
|
||||
def approach(current, target, delta):
|
||||
if current < target:
|
||||
return min(current + delta, target)
|
||||
return max(current - delta, target)
|
||||
Reference in new issue
Block a user