def shortest_way(self, a: Vec2D, b: Vec2D): """shortest vector from a to b""" dx, dy = b.x - a.x, b.y - a.y if self.torus_enabled: if abs(dx) > self.w * 0.5: dx = dx - self.w if dx > 0 else dx + self.w if abs(dy) > self.h * 0.5: dy = dy - self.h if dy > 0 else dy + self.h return Vec2D(dx, dy)
def move_in_dir(self, dir: Union[Vec2D, float]): if type(dir) == Vec2D: if dir.is_zero_vec(): return self.move_rel(dir) dir = dir.angle() c, s = math.cos(dir), math.sin(dir) cabs, sabs = abs(c), abs(s) mi, ma = cabs, sabs c_is_max = cabs > sabs if c_is_max: mi, ma = ma, mi min_p = mi / ma if ma > 0 else 0 move_min = random.random() < min_p dx, dy = -1 if c < 0 else 1, -1 if s < 0 else 1 if not move_min: if c_is_max: dy = 0 else: dx = 0 return self.move_rel(Vec2D(dx, dy))
def move_away_from(self, pos: Vec2D): dir = self.world.shortest_way(pos, self.pos()) if dir.is_zero_vec(): return self.move_in_dir(Vec2D.random_grid_dir()) else: return self.move_in_dir(dir)
def random_pos(self): return Vec2D(random.randint(0, self.w - 1), random.randint(0, self.h - 1))
def torus(self, pos: Vec2D): return Vec2D(pos.x % self.w, pos.y % self.h)