def __init__(self, points): Polygon.counter_clockwise(points) self.points = points self.segments = [S(points[len(points)-1], points[0])] for i in range(len(points)-1): self.segments.append(S(points[i], points[i+1])) self.bounding = Rectangle.bounding(points)
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_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_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_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 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 to_segment_list(self): segments = [] last = None for p in self.points: if last: segments.append(S(last, p)) last = p return segments
def remove_cycles(self): segments = self.to_segment_list() new_segments = segments[0:2] for i in range(2, len(segments)): current = segments[i] truncate = False for j in range(len(new_segments) - 1): checked = new_segments[j] if current.intersects(checked): middle = current.intersection(checked) new_segments[j] = S(checked.p, middle) del new_segments[j + 1:] new_segments.append(S(middle, current.q)) truncate = True break if not truncate: new_segments.append(current) self.from_segment_list(new_segments)
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 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 open_directions_for_circle_avoiding_segment(circ: Circle, seg: S, step): """ Find which motion directions are allowed for a circle (simulating load) which is near a segment (an edge of a cube). """ center = circ.center radius = circ.radius closest, dist = seg.closest_point(center) open_region = GRegion(center=center) if dist <= radius: # segment is inside load radius direction = center - closest # away from obstacle r = Region(-direction.perp(), direction.perp()) # half plane perpendicular to # direction - defines allowed open region for further motion open_region.intersect_with(r) else: # segment is outside load radius - we want to check if there can be an intersection # between load and the cube segment if the load moves with speed "step" towards the # segment, and restrict possible direction of motions accordingly. shift = seg.dir.perp().resize( radius) # Shift in the direction toward the segment for sign in -1, 1: # Check for which shift there is an intersection with the load seg2 = S(seg.q + shift * sign, seg.p + shift * sign) cut = seg2.intersect_with_circle( center, step) # Returns intersected segment # with a circle of radius step if one exists, to determine the maximal angle the # load can move without encroaching on the segment. if cut: v1, v2 = cut.p - center, cut.q - center x = v1.alt_angle(v2) # This is a little strange but needed.... if x < 0.00000000001 or x > 3.9999999999: # case where the cut segment is almost a point within the load, # accept this inaccuracy and move on (?), allow motion continue # Determine if open region is from v2 to v1 or the other way. Regions are # defined from the first argument to the second argument counterclockwise. if x <= 2: r = Region( v2, v1) # r is the allowed open region. v2 is further # counterclockwise compared to v1 else: r = Region( v1, v2) # r is the allowed open region. v1 is further # counterclockwise compared to v2 open_region.intersect_with( r) # add to original fully open GRegion for p in seg: # Making sure the load avoids the endpoints of the segment (segment avoidance # calculation does not hold, another method is needed). r = GRegion.open_directions_for_circle_avoiding_point( circ, p, step) if r: # pass open_region.intersect_with(r) return open_region