예제 #1
0
 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)
예제 #2
0
 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]
예제 #3
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)
예제 #4
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)
예제 #5
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()
예제 #6
0
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)
예제 #7
0
 def to_segment_list(self):
     segments = []
     last = None
     for p in self.points:
         if last:
             segments.append(S(last, p))
         last = p
     return segments
예제 #8
0
 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)
예제 #9
0
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()
예제 #10
0
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()
예제 #11
0
    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