def check_open_directions_for_circle_avoiding_segment3(): placements = [] radius = 0.25 step = 0.15 center = P(0.5, 0.5) circ = Circle(center, radius) for i in range(1000): p = P.polar(0.37, i / 1000 * 2 * np.pi) + P(0.43, 0.38) q = p + P(0.1, 0.2) seg = S(p, q) directions = GRegion.open_directions_for_circle_avoiding_segment( circ, seg, step) if len(directions.regions) > 1: shift = seg.dir.perp().resize(radius) print(seg.p.x, seg.p.y, seg.q.x, seg.q.y) box = Polygon([p - shift, p + shift, q + shift, q - shift]) l = [(Circle(center, step), "lightgreen"), (box, "lightgrey"), (Circle(p, radius), "lightgrey"), (Circle(q, radius), "lightgrey"), (directions, "black"), (seg, "red"), (Circle(center, 0.004), "red")] placements.append(l) movie = Movie() movie.background(l) movie.just_draw() break exit(0)
def check_open_directions_for_circle_avoiding_segment2(): radius = 0.25 step = 0.15 center = P(0.5, 0.5) circ = Circle(center, radius) p = P(0.12661771955, 0.59179988647) q = P(0.22661771955, 0.79179988647) seg = S(p, q) directions = GRegion.open_directions_for_circle_avoiding_segment( circ, seg, step) shift = seg.dir.perp().resize(radius) box = Polygon([p - shift, p + shift, q + shift, q - shift]) l = [ (Circle(center, step), "lightgreen"), (box, "lightgrey"), # (Circle(p, radius), "lightgrey"), # (Circle(q, radius), "lightgrey"), (directions, "black"), (seg, "red"), (Circle(center, 0.004), "red") ] movie = Movie() movie.background(l) movie.just_draw() exit(0)
def check_open_directions_for_point2(): stones = PolygonSet() stones.add(Polygon.square(P(0.6, 0.2), 0.2, 0)) directions = stones.open_directions_for_point(P(0.5, 0.5), 0.4) movie.background([(s, "red") for s in stones] + [(directions, "green")]) movie.just_draw() exit()
def check_open_directions_for_circle_avoiding_segment(): placements = [] radius = 0.25 step = 0.15 center = P(0.5, 0.5) circ = Circle(center, radius) m = 0 for i in range(10000): p = P.polar(0.35, i / 1000 * 2 * np.pi) + P(0.5, 0.5) q = p + P.polar(0.2, i / 314 * 2 * np.pi) seg = S(p, q) directions = GRegion.open_directions_for_circle_avoiding_segment( circ, seg, step) shift = seg.dir.perp().resize(radius) box = Polygon([p - shift, p + shift, q + shift, q - shift]) l = [(Circle(center, step), "lightgreen"), (box, "lightgrey"), (Circle(p, radius), "lightgrey"), (Circle(q, radius), "lightgrey"), (directions, "black"), (seg, "red"), (Circle(center, 0.004), "red")] pp, dist = seg.closest_point(center) if dist >= radius: for r in directions.regions: for t in r: cut = seg.intersect_with_circle(center + t.resize(step), radius) if cut and cut.length() > 0.00000001: l += [(Circle(center + t.resize(step), radius), "pink")] m = max(m, cut.length()) print(m) placements.append(l) movie = Movie() movie.run_animation(placements, 10) exit()
def move(self, bx, by, alpha=P(0.9,0.9)): ''' Move the camera to the given coordinates (Camera can't go over the field boundary) Uses exponential smoothing to minimize jittering ''' new_c = P(0,0) new_c.x = min(max(bx, self.params['pt'].x//4), W - self.params['pt'].x//4) new_c.y = min(max(by, self.params['pt'].y//4), H - self.params['pt'].y//4) self.c = alpha*self.c + (P(1,1)-alpha)*new_c
def check_open_directions_for_point(): placements = [] for i in range(1000): stones = PolygonSet() stones.add( Polygon.square( P.polar(0.3, i / 1000 * 2 * np.pi) + P(0.3, 0.40), 0.2, 0.2)) directions = stones.open_directions_for_point(P(0.5, 0.5), 0.4) placements.append([(s, "red") for s in stones] + [(directions, "green")]) movie.run_animation(placements, 10) exit()
def square(p, size, angle): sq = [p] for i in range(3): p = p + P.polar(size, angle) sq.append(p) angle += np.pi / 2 return Polygon(sq)
def rand_point(self, size): """ Generate a random vector within the allowable region. :param size: norm of the vector to be generated :return: a random vector within the allowable regions (class P) """ if self.full: # if all motion is allowed, generate a completely random vector return P(misc.rand() - 0.5, misc.rand() - 0.5).resize(size) # else, generate a vector within the allowable regions # Draw a random angle within the accumulated allowed # regions total angle t = misc.rand() * self.width() total = 0 # Find in which region this randomly generated angle falls for r in self.regions: total += r.angle() if total >= t: res = r.rand_point( size) # Generate a random vector of norm=size within the # randomly chosen region return res print("Apparently stuck", self.width()) exit(1)
def test_neighbors(self): self.assertEqual( { P(4, 4), P(4, 5), P(4, 6), P(5, 4), P(5, 6), P(6, 4), P(6, 5), P(6, 6) }, P(5, 5).neighbors())
def rect(self, win, col, coords, width=0): ''' Draw a rectangle according to the cameras mode (attributes are same as ```pygame.draw.rect```)''' if self.mode == 'full': pygame.draw.rect(win, col, coords, width) elif self.rect_in_view(coords): x,y,w,h = coords new_pt = self.pt(P(x,y)) pygame.draw.rect(win, col, (new_pt.x, new_pt.y, w*self.params['fact'], h*self.params['fact']), width)
def check_segment_stuff(): s = S(P(0.30000000000000004, 0.8000000000000002), P(0.3, 0.3)) center = P(0.2987672191724942, 0.8145637895291986) radius = 0.014705882352941176 closest, dist = s.closest_point(center) if dist >= radius: print("Shouldn't") s2 = s.intersect_with_circle(center, radius) if not s2: print("Got it") s = S(P(0.3, 0.8), P(0.3, 0.3)) s2 = s.intersect_with_circle(center, radius) if not s2: print("Got it??") exit(1)
def point_at_angle(self, angle, size=1.0): """ Generate vector within the region. :param angle: relative angle (within the region) of the generated vector :param size: norm of the generated vector :return: the vector generated (class P) """ return P.polar(size, self.p1.angle() + angle)
def polygon(self, win, col, pts): if self.mode == 'full': pygame.draw.polygon(win, col, pts) else: new_pts = [] for p in pts: new_pts.append(self.pt(P(p)).val) pygame.draw.polygon(win, col, new_pts)
def restart(self): """Resets the runner to the first location/target with given/random seed. """ super().restart() self.dist_on_same_target = 0 self.cheerio = self.cfg.start self.current_target = self.cfg.nest self.v = P(0, 0)
def params(self): ''' Helper method to reduce code redundancy ''' if self.mode == 'full': return {'pt': P(0, 0), 'fact': 1} elif self.mode == 'default': return {'pt': CAM_DEF, 'fact': DEF_FACTOR} else: return {'pt': CAM_ZOOM, 'fact': ZOOM_FACTOR}
def polygon(self, win, col, pts): ''' Draw a polygon according to the cameras mode (attributes are same as ```pygame.draw.polygon```)''' if self.mode == 'full': pygame.draw.polygon(win, col, pts) else: new_pts = [] for p in pts: new_pts.append(self.pt(P(p)).val) pygame.draw.polygon(win, col, new_pts)
def check_circle_set(movie): to_draw = [] m = Circle(P(0.5, 0.5), 0.2) to_draw.append((m, "black")) s = CircleSet(0.1) for i in range(3): c = Circle(P.random(), 0.1) s.add(c, c) to_draw.append((c, "yellow")) for c in s.intersecting(m): print(c) to_draw.append((c, "red")) movie.background(to_draw) movie.just_draw()
def rect(self, win, col, coords, width=0): if self.mode == 'full': pygame.draw.rect(win, col, coords, width) elif self.rect_in_view(coords): x, y, w, h = coords new_pt = self.pt(P(x, y)) pygame.draw.rect(win, col, (new_pt.x, new_pt.y, w * self.params['fact'], h * self.params['fact']), width)
def closest_point(self, p): """Return the point on the segment that is closest to p, and the distance to it""" a, b = P.solve(self.dir, self.dir.perp(), p - self.p) if 0 < a < 1: return self.p + self.dir * a, self.dir.norm() * abs(b) p_dist, q_dist = p.dist(self.p), p.dist(self.q) if p_dist < q_dist: return self.p, p_dist else: return self.q, q_dist
def check_open_directions_for_circle_avoiding_point(): placements = [] radius = 0.2 step = 0.15 center = P(0.55, 0.5) circ = Circle(center, radius) for i in range(1000): p = P.polar(0.35, i / 1000 * 2 * np.pi) + P(0.4, 0.40) dirs = GRegion.open_directions_for_circle_avoiding_point(circ, p, step) directions = GRegion(center=circ.center) if dirs: directions.intersect_with(dirs) placements.append([(Circle(center, step), "green"), (Circle(p, radius), "lightgrey"), (directions, "black")]) movie = Movie() movie.run_animation(placements, 10) exit()
def check_circle_set2(movie): gran = 0.09 to_draw = [] s = CircleSet(gran) c = Circle(P(0.5, 0.5), 0.3) s.add(c, c) to_draw.append((c, "red")) for i in range(50): for j in range(50): p = P(i * gran, j * gran) if s.intersecting(Circle(p, 0.001)): to_draw.append((p, "black")) else: to_draw.append((p, "gold")) movie.background(to_draw) movie.just_draw()
def to_draw(self): self.diffuse() res = [] m = max(h for i, j, h in self) for i, j, h in self: x, y = i * self.dx, j * self.dx strength = sqrt(h + 1) / sqrt(m + 1) * 3 strength = max(0, min(strength, 1)) strength = 1 - strength color = (strength, strength, strength) res.append((Circle(P(x, y), self.dx), color)) return res
def draw(self, ax, center=P.zero(), color="black", size=0.5): a1 = S(center, center + self.p1.resize(size)).draw_arrow(ax, color) a2 = S(center, center + self.p2.resize(size)).draw_arrow(ax, color) a3 = patches.Arc((center.x, center.y), size, size, 0, self.p1.angle_degrees(), self.p2.angle_degrees(), color=color) ax.add_patch(a3) return a1 + a2 + [a3]
def check_segment_stuff2(): s = S(P(0.3, 0.5), P(0.7, 0.4)) radius = 0.2 movie.background([(s, "black")]) placements = [] for i in range(5000): center = P.polar(i / 10000, i / 1000 * 2 * np.pi) + P(0.5, 0.5) current = [(Circle(center, radius), "red")] intersect = s.intersect_with_circle(center, radius) closest, dist = s.closest_point(center) if intersect: current.append((intersect, "yellow")) current.append((closest, "green")) if dist < radius and not intersect: print("WHAT??") placements.append(current) movie.run_animation(placements, 10) exit()
def tilted_rectangle(p, size1, size2, angle): sq = [p] size = size1 for i in range(3): p += P.polar(size, angle) sq.append(p) angle -= np.pi / 2 if size == size1: size = size2 else: size = size1 return Polygon(sq)
def random_step(self, stones: PolygonSet, step_size: float, bias: P): last = self.last() directions = stones.open_directions_for_point(last, step_size) if not directions: print("walk stuck") exit(1) if misc.rand() < 0.5: random_directions = [ directions.rand_point(step_size) for i in range(2) ] direction = bias.resize(step_size).closest_point(random_directions) else: direction = directions.rand_point(step_size) self.points.append(last + direction)
def draw_distribution(sigma): direction = P(0.3, 0) stones = PolygonSet() stones.add(Polygon.square(P(0.6, 0.6), 0.2, 0.1)) stones.add(Polygon.square(P(0.3, 0.6), 0.2, 0.1)) stones.add(Polygon.square(P(0.7, 0.4), 0.2, 0.1)) cheerio = P(0.5, 0.5) g = stones.open_direction_for_circle(cheerio, 0, 1) movie = Movie() movie.background([(s, "red") for s in stones]) movie.background([(S(cheerio, direction + cheerio), "blue")]) movie.background([(g, "black")]) points = [] for i in range(300): rand_dir = g.rand_point_normal(direction, sigma) # rand_dir = direction.rotate(np.random.normal(scale=sigma) * np.pi) points.append(cheerio + rand_dir) movie.background([(Circle(p, 0.0015), "blue") for p in points]) movie.just_draw() exit()
def blit(self, win, path, pt, size): x, y = pt size = P(self.params['fact'], self.params['fact']) * P(size) if self.mode == 'full': win.blit(path[self.mode], (P(x, y) - P(0.5, 0.5) * size).val) elif self.rect_in_view( (x - size.x // 2, y - size.y // 2, size.x, size.y)): new_pt = self.pt(P(x, y)) win.blit(path[self.mode], (new_pt - P(0.5, 0.5) * size).val)
def __init__(self, cfg: Configuration, seed=None, sigma=0, rolling=True, persistence_dist=6, max_steps=10000): super().__init__(cfg, max_steps, seed) self.speed = self.cfg.cheerio_radius * 0.05 # step size self.sigma = sigma # Standard deviation of normal distribution used to draw from a # random direction to update the current target self.rolling = rolling # enable/disable rolling self.persistence_dist = persistence_dist * cfg.cheerio_radius # define persistence # length of the load. This parameter determines the time/distance passed before # re-selecting a new target. self.dist_on_same_target = 0 # initialize distance counter for target self.cheerio = self.cfg.start # initialize load location based on real data/(0,mid_y) self.current_target = self.cfg.nest # initialize nest direction based on real last load # location/(1,mid_y) self.v = P(0, 0) # initialize velocity direction to 0
def __init__(self, cx, cy, mode='default'): ''' Initializes the game camera The game camera has 3 modes: - default: Follows the ball while showing surrounding players - zoomed: Follows the ball closely - full: Displays the entire field Attributes: cx (float): Camera's x coordinate cy (float): Camera's y coordinate mode (str): The camera mode ''' self.c = P(cx, cy) self.set_mode(mode)