| | class Collider: |
| | def __init__(self, pos1 = (None,) * 3, pos2 = (None,) * 3): |
| | |
| | |
| |
|
| | self.x1, self.y1, self.z1 = pos1 |
| | self.x2, self.y2, self.z2 = pos2 |
| | |
| | def __add__(self, pos): |
| | x, y, z = pos |
| |
|
| | return Collider( |
| | (self.x1 + x, self.y1 + y, self.z1 + z), |
| | (self.x2 + x, self.y2 + y, self.z2 + z) |
| | ) |
| | |
| | def __and__(self, collider): |
| | x = min(self.x2, collider.x2) - max(self.x1, collider.x1) |
| | y = min(self.y2, collider.y2) - max(self.y1, collider.y1) |
| | z = min(self.z2, collider.z2) - max(self.z1, collider.z1) |
| |
|
| | return x > 0 and y > 0 and z > 0 |
| | |
| | def collide(self, collider, velocity): |
| | |
| | |
| |
|
| | no_collision = 1, None |
| |
|
| | |
| |
|
| | vx, vy, vz = velocity |
| |
|
| | time = lambda x, y: x / y if y else float('-' * (x > 0) + "inf") |
| |
|
| | x_entry = time(collider.x1 - self.x2 if vx > 0 else collider.x2 - self.x1, vx) |
| | x_exit = time(collider.x2 - self.x1 if vx > 0 else collider.x1 - self.x2, vx) |
| |
|
| | y_entry = time(collider.y1 - self.y2 if vy > 0 else collider.y2 - self.y1, vy) |
| | y_exit = time(collider.y2 - self.y1 if vy > 0 else collider.y1 - self.y2, vy) |
| |
|
| | z_entry = time(collider.z1 - self.z2 if vz > 0 else collider.z2 - self.z1, vz) |
| | z_exit = time(collider.z2 - self.z1 if vz > 0 else collider.z1 - self.z2, vz) |
| |
|
| | |
| |
|
| | if x_entry < 0 and y_entry < 0 and z_entry < 0: |
| | return no_collision |
| |
|
| | if x_entry > 1 or y_entry > 1 or z_entry > 1: |
| | return no_collision |
| | |
| | |
| |
|
| | entry = max(x_entry, y_entry, z_entry) |
| | exit_ = min(x_exit, y_exit, z_exit ) |
| |
|
| | if entry > exit_: |
| | return no_collision |
| | |
| | |
| |
|
| | nx = (0, -1 if vx > 0 else 1)[entry == x_entry] |
| | ny = (0, -1 if vy > 0 else 1)[entry == y_entry] |
| | nz = (0, -1 if vz > 0 else 1)[entry == z_entry] |
| |
|
| | return entry, (nx, ny, nz) |