Пример #1
0
def line_walk_double_edges_e(he, ray, b):
    nxt = he.nxt
    prev = he.prev
    v1 = he.node
    v2 = nxt.node
    v3 = prev.node
    s = Segment(v1.p, v2.p) 
    inter = intersection(s, ray) 

    if inter != [] and is_segment(inter[0]):
        end_node = v1
        if ray.contains(v2.p):
            end_node = v2
        yield from line_walk_double_edges_v(end_node, Ray(end_node.p, b), b)
        raise StopIteration

    e1 = Segment(v1.p, v3.p)
    e2 = Segment(v3.p, v2.p)
    inter1 = intersection(e1, ray)
    inter2 = intersection(e2, ray)

    if inter1 != [] and inter2 != []:       
        yield from line_walk_double_edges_v(v3, Ray(inter1[0], b), b)
        raise StopIteration
    if inter1 != []:
        yield e1
        if (prev.twin != None):
            yield from line_walk_double_edges_e(prev.twin, Ray(inter1[0], b), b)
            raise StopIteration
    if inter2 != []:
        yield e2
        if (nxt.twin != None):
            yield from line_walk_double_edges_e(nxt.twin, Ray(inter2[0], b), b)
            raise StopIteration
    raise StopIteration
Пример #2
0
    def initialize_status(self):
        sweep_ray = Ray(self.origin, self.event_queue[0].p)
        i = 0
        for ep in self.event_queue:
            if ep.type == DEFAULT_VERTEX:
                segment = Segment(ep.p, ep.twin.p)
                intersection_point = sweep_ray.intersection(segment)

                if len(intersection_point) > 0:
                    # If the segments first point is the current event-point
                    if intersection_point[
                            0] == ep.p:  # if the point is on the initial ray
                        if len(
                                Ray(self.origin, self.event_queue[
                                    i + 1].p).intersection(segment)
                        ) > 0:  #if the point was a start point
                            self.initialize_segment(ep, intersection_point)
                        else:
                            self.initialize_segment(ep.twin,
                                                    intersection_point)
                    else:
                        self.initialize_segment(ep.twin, intersection_point)
                else:
                    # Event-points not hit by the ray gets a type
                    ep.type = START_VERTEX
                    ep.twin.type = END_VERTEX
            i += 1
def during_collision(cue_point, radius, stick_point, ball_coord):
    future_point = cue_point
    collision_ball_info = cue_point
    min_distance = 1e9

    temp_ray = Ray(cue_point, stick_point)
    temp_Line = Line(cue_point, stick_point)
    temp_circle = Circle(cue_point, radius)
    temp_collision_points = intersection(temp_Line, temp_circle)

    if temp_ray.contains(temp_collision_points[0]):
        white_ray = Ray(cue_point, temp_collision_points[1])
    else:
        white_ray = Ray(cue_point, temp_collision_points[0])

    for coord in ball_coord:
        enlarged_ball = Circle(Point(coord[0], coord[1]), coord[2] + radius)

        intersect_point = intersection(white_ray, enlarged_ball)

        if len(intersect_point) == 2 and cue_point.distance(
                intersect_point[0]) >= cue_point.distance(intersect_point[1]):
            temp_point = intersect_point[1]
        elif len(intersect_point) == 2 or len(intersect_point) == 1:
            temp_point = intersect_point[0]
        else:
            continue

        dist = cue_point.distance(temp_point)
        if min_distance > dist:
            min_distance = dist
            future_point = temp_point
            collision_ball_info = coord

    return future_point, collision_ball_info
Пример #4
0
 def __init__(self, origin: Point, theta: float, phi: float):
     self.intensity = (abs(math.sin(abs(theta))) +
                       abs(math.sin(abs(phi)))) / 2
     x = math.sin(phi) * math.cos(theta)
     y = math.sin(phi) * math.sin(theta)
     z = math.cos(phi)
     self.ray = Ray(origin, Point(x, -y, z))
     # Array used for storing segments of reflected ray
     self.ray_array = [Ray(origin, Point(x, -y, z))]
     self.road_intersection = []
Пример #5
0
def line_walk_nodes_and_edges_and_triangles_e(v1, v2, ray, b):
    s = Segment(v1.p, v2.p)
    edge = list(set(v1.edges) & set(v2.edges))[0]
    inter = intersection(s, ray)

    if (inter != [] and is_segment(inter[0])):
        end_node1 = edge.nodes[0]
        end_node2 = edge.nodes[1]

        if ray.contains(end_node2.p):
            end_node1 = end_node2
            
        yield from line_walk_nodes_and_edges_and_triangles_v(end_node1, Ray(end_node1.p, b), b)
        raise StopIteration
    s_b = turn(cgPoint(int(b.x), int(b.y)), cgPoint(int(v1.p.x), int(v1.p.y)), cgPoint(int(v2.p.x), int(v2.p.y)))
    se = None
    
    for index, n_triangle in enumerate(edge.triangles):
        mb_e = set(n_triangle.edges)
        mb_e.remove(edge)
        mb_e = list(mb_e)
        o_v = list(set(mb_e[0].nodes) & set(mb_e[1].nodes))[0]
    
        if s_b != turn(cgPoint(int(o_v.p.x), int(o_v.p.y)), cgPoint(int(v1.p.x), int(v1.p.y)),
                       cgPoint(int(v2.p.x), int(v2.p.y))):
            continue
        
        t_e1 = mb_e[0].nodes
        t_e2 = mb_e[1].nodes
        v1 = t_e1[0]
        v1_n = t_e1[1]
        e1 = Segment(v1.p, v1_n.p)
        v2 = t_e2[0]
        v2_n = t_e2[1]
        e2 = Segment(v2.p, v2_n.p)
        inter1 = intersection(e1, ray)
        inter2 = intersection(e2, ray)
        
        if inter1 != [] and inter2 != []:      
            yield from line_walk_nodes_and_edges_and_triangles_v(o_v, Ray(inter1[0], b), b)
            raise StopIteration
        if inter1 != []:
            yield e1
            yield from line_walk_nodes_and_edges_and_triangles_e(v1, v1_n, Ray(inter1[0], b), b)
            raise StopIteration
        if inter2 != []:
            yield e2
            yield from line_walk_nodes_and_edges_and_triangles_e(v2, v2_n, Ray(inter2[0], b), b)
            raise StopIteration
    
    raise StopIteration
Пример #6
0
def line_walk_nodes_and_triangles_e(v1, v2, ray, b):
    s_b = turn(cgPoint(int(b.x), int(b.y)), cgPoint(int(v1.p.x), int(v1.p.y)), cgPoint(int(v2.p.x), int(v2.p.y)))
    s = Segment(v1.p, v2.p) 
    inter = intersection(s, ray) 

    if inter != [] and is_segment(inter[0]):
        end_node = v1
    
        if ray.contains(v2.p):
            end_node = v2
        
        yield from line_walk_nodes_and_triangles_v(end_node, Ray(end_node.p, b), b)

    tp = set(v1.triangles) & set(v2.triangles)
    tp.discard(None)
    vs = list(tp)
    vp = []

    for i in vs:
        ts = set(i.nodes)
        ts.discard(v1)
        ts.discard(v2)
        vp = vp + list(ts)
    
    v3 = [i for i in vp 
          if s_b == turn(cgPoint(int(i.p.x), int(i.p.y)), cgPoint(int(v1.p.x), int(v1.p.y)), cgPoint(int(v2.p.x), int(v2.p.y)))
         ]
    
    if v3 == []:
        raise StopIteration

    e1 = Segment(v1.p, v3[0].p)
    e2 = Segment(v2.p, v3[0].p)
    inter1 = intersection(e1, ray)
    inter2 = intersection(e2, ray)

    if inter1 != [] and inter2 != []:
        yield from line_walk_nodes_and_triangles_v(v3[0], Ray(inter1[0], b), b)
        raise StopIteration
    if inter1 != []:
        yield e1
        yield from line_walk_nodes_and_triangles_e(v1, v3[0], Ray(inter1[0], b), b)
        raise StopIteration
    if inter2 != []:
        yield e2
        yield from line_walk_nodes_and_triangles_e(v2, v3[0], Ray(inter2[0], b), b)
        raise StopIteration
    
    raise StopIteration
def main():
    image_address = str(input('Enter the image name: '))
    image_address = "pool_Images/" + image_address
    print(image_address) 
    ball_coord, cue_coord, stick_coord = detection.detect_coordinates2(image_address)
    #print(cue_coord, ball_coord, stick_coord)
    if len(cue_coord) == 0 or len(stick_coord) == 0:
        print("No point detected")
        return

    cue_point = Point(cue_coord[0], cue_coord[1])
    stick_point = Point(stick_coord[0], stick_coord[1])
    path_of_white_ball(cue_point, stick_coord, cue_coord[2])
    #path_of_white_ball(p1, p2, RADIUS)
    future_point, collision_ball_info  = during_collision(cue_point, cue_coord[2],stick_point,ball_coord)
    if future_point == cue_point:
        print("No collision")
        return 
    else:
        frame = cv.imread(image_address, 1)
        cv.circle(frame, (int(collision_ball_info[0]), int(collision_ball_info[1])), 2*int(collision_ball_info[2]), (0, 255, 255), 2)
        cv.circle(frame, (int(future_point.x), int(future_point.y)), int(cue_coord[2]), (255, 255, 255), -1)
        temp_point = Point(collision_ball_info[0],collision_ball_info[1])
        colored_future_point = intersection(Ray(future_point,temp_point),Circle(temp_point,collision_ball_info[2]*5)) 
        cv.line(frame, (cue_point.x, cue_point.y), (future_point.x, future_point.y), (255, 255, 255), thickness=2)
        cv.line(frame, ((int)(collision_ball_info[0]), (int)(collision_ball_info[1])), ((int)(colored_future_point[0].x), (int)(colored_future_point[0].y)), (0, 255, 0), thickness=2)
        while 1:
            cv.namedWindow('Image',cv.WND_PROP_FULLSCREEN)
            cv.imshow('Image', frame)
            if cv.waitKey(1) & 0xFF == 27:
                break
        cv.destroyAllWindows()
Пример #8
0
 def __init__(self, origin: Point, ray_angle: float, base_angle: int):
     self.ray_length = 1
     # Intensity is calculated according to Lambertian distribution
     self.intensity = abs(math.sin(math.radians(abs(ray_angle - base_angle))))
     self.original_intensity = abs(math.sin(math.radians(abs(ray_angle - base_angle))))
     self.end_intensity = self.intensity * 1 / (self.ray_length * self.ray_length)
     # End coordinates are calculated from ray angle
     x_coordinate = 10000 * math.cos(math.radians(ray_angle)) + origin.x
     y_coordinate = 10000 * math.sin(math.radians(ray_angle)) + origin.y
     # Ray goes from the origin in direction of end coordinates
     self.ray = Ray(origin, Point(x_coordinate, y_coordinate))
     # Array used for storing segments of reflected ray
     self.ray_array = [Ray(origin, Point(x_coordinate, y_coordinate))]
     self.road_intersection = []
     # If the ray is reflected too many time or if it is reflected back into the device, it will be terminated
     self.terminated = False
Пример #9
0
def line_walk_nodes_and_edges_and_triangles_v(node, ray, b):
    for n_triangles in node.triangles:
        for n_edge in n_triangles.edges:
            end_node = None
            
            if n_edge.nodes[0] == node:
                end_node = n_edge.nodes[1]
            elif n_edge.nodes[1] == node:
                end_node = n_edge.nodes[0]
            else:
                continue

            s = Segment(node.p, end_node.p) 
            inter = intersection(s, ray) 

            if inter != [] and is_segment(inter[0]):
                yield s
                yield from line_walk_nodes_and_edges_and_triangles_v(end_node, Ray(end_node.p, b), b)
                raise StopIteration

    for n_triangles in node.triangles:
        for n_edge in n_triangles.edges:
            if n_edge.nodes[0] != node and n_edge.nodes[1] != node:
                node_i = n_edge.nodes[0]
                node_j = n_edge.nodes[1]
                s = Segment(node_i.p, node_j.p)
                inter = intersection(s, ray)
                
                if inter != []:
                    yield s
                    yield from line_walk_nodes_and_edges_and_triangles_e(node_i, node_j, Ray(inter[0], b), b)
                    raise StopIteration
    raise StopIteration
Пример #10
0
def predict_path(circle_coordinates,cue_ball_coordinate,cue_stick_coordinate,frame):
    global prev_stick_point, prev_cue_point

    if len(cue_ball_coordinate) < 3 or len(cue_stick_coordinate) < 2:
        print("No point detected")
        return frame

    cue_point = Point(cue_ball_coordinate[0], cue_ball_coordinate[1])
    stick_point = Point(cue_stick_coordinate[0], cue_stick_coordinate[1])

   
    future_point, collision_ball_info  = during_collision(cue_point, cue_ball_coordinate[2],stick_point,circle_coordinates)
    prev_stick_point = stick_point
    prev_cue_point = cue_point 
    flag = 0
    
    if future_point == cue_point:
        print("No collision")
    else:
        print("Collision")
        cv.circle(frame, (int(collision_ball_info[0]), int(collision_ball_info[1])), 2*int(collision_ball_info[2]), (0, 255, 255), 2)
        cv.circle(frame, (int(future_point.x), int(future_point.y)), int(cue_ball_coordinate[2]), (255, 255, 255), -1)
        temp_point = Point(collision_ball_info[0],collision_ball_info[1])
        colored_future_point = intersection(Ray(future_point,temp_point),Circle(temp_point,collision_ball_info[2]*5)) 
        cv.line(frame, (cue_point.x, cue_point.y), (future_point.x, future_point.y), (255, 255, 255), thickness=2)
        cv.line(frame, ((int)(collision_ball_info[0]), (int)(collision_ball_info[1])), ((int)(colored_future_point[0].x), 
            (int)(colored_future_point[0].y)), (0, 255, 0), thickness=2)
    
    cv.circle(frame, (int(cue_stick_coordinate[0]), int(cue_stick_coordinate[1])), 3, (123, 55, 55), 4)
    cv.circle(frame, (int(cue_ball_coordinate[0]), int(cue_ball_coordinate[1])),int(cue_ball_coordinate[2])*2, (100, 100, 100), 2)
    cv.circle(frame, (int(cue_ball_coordinate[0]), int(cue_ball_coordinate[1])), 1, (255, 100, 100), 2)
    
    return frame
Пример #11
0
def angle_to_next(p, points):
    start_point = p[0]
    end_point = next_point(p, points)[0]

    try:
        return Ray(start_point, end_point).smallest_angle_between(p[1])
    except:
        breakpoint()
Пример #12
0
def line_walk_double_edges_v(node, ray, b):
    
    list_of_n_triangles = node.get_neighbor_triangles()
    
    for t in list_of_n_triangles:
        c_he = t.he
        
        while(c_he.node != node):
            c_he = c_he.nxt
       
        he_prev = c_he.prev
        he_nxt = c_he.nxt
        v1 = c_he.node
        v2 = he_nxt.node
        v3 = he_prev.node
        
        s = Segment(v1.p, v2.p) 
        inter = intersection(s, ray)

        if inter != [] and is_segment(inter[0]):
            yield s
            yield from line_walk_double_edges_v(v2, Ray(v2.p, b), b)
            raise StopIteration

        s = Segment(v1.p, v3.p) 
        inter = intersection(s, ray)
        
        if inter != [] and is_segment(inter[0]):
            yield s
            yield from line_walk_double_edges_v(v3, Ray(v3.p, b), b)
            raise StopIteration
        
        s = Segment(v3.p, v2.p) 
        inter = intersection(s, ray)
        
        if inter != []:
            yield s
            if he_nxt.twin != None:
                yield from line_walk_double_edges_e(he_nxt.twin, Ray(inter[0], b), b)
                raise StopIteration
            else:
                raise StopIteration
    raise StopIteration
Пример #13
0
def line_walk_node_with_neighbours_v(node, ray, b):
    for n_node in node.neigh_nodes:
        p = n_node.p
        s = Segment(node.p, p) 
        inter = intersection(s, ray)
        
        if inter != [] and is_segment(inter[0]):
            yield s
            yield from line_walk_node_with_neighbours_v(n_node, Ray(p, b), b)
            raise StopIteration
            

    for i, j in itertools.combinations(node.neigh_nodes, r=2):
        if i in set(j.neigh_nodes):
            s = Segment(i.p, j.p)
            inter = intersection(s, ray)
            
            if inter != []:
                yield s
                yield from line_walk_node_with_neighbours_e(i, j, Ray(inter[0], b), b) 
                raise StopIteration
Пример #14
0
    def project_on_line(
            line: Line,
            points: Iterable[ProjectedPoint]) -> List[ProjectedPoint]:
        some_line_point = line.p1
        line_points = []

        for current_point in points:

            projection = line.projection(current_point)
            if projection == some_line_point:
                line_coordinate = 0
            else:
                dst_ray = Ray(some_line_point, projection)
                is_inversed = dst_ray.angle_between(line) != 0
                line_coordinate = some_line_point.distance(projection)
                if is_inversed:
                    line_coordinate = -line_coordinate

            line_points.append(
                SegmentsInLineFinder.ProjectedPoint(current_point, projection,
                                                    line_coordinate))

        line_points.sort(key=lambda point: point.line_coordinate)
        return line_points
Пример #15
0
def line_walk_node_with_neighbours_e(v1, v2, ray, b):
    s_b = turn(cgPoint(int(b.x), int(b.y)), cgPoint(int(v1.p.x), int(v1.p.y)), cgPoint(int(v2.p.x), int(v2.p.y)))
    s = Segment(v1.p, v2.p) 
    inter = intersection(s, ray)

    if inter != [] and is_segment(inter[0]):
        end_node = v1
        if ray.contains(v2.p):
            end_node = v2
        yield from line_walk_node_with_neighbours_v(end_node, Ray(end_node.p, b), b)
        raise StopIteration

    vs = list(set(v1.neigh_nodes) & set(v2.neigh_nodes))
    v3 = [i for i in vs 
          if s_b == turn(cgPoint(int(i.p.x), int(i.p.y)), cgPoint(int(v1.p.x), int(v1.p.y)), cgPoint(int(v2.p.x), int(v2.p.y)))
         ]
    
    if v3 == []:
        raise StopIteration
    
    e1 = Segment(v1.p, v3[0].p)
    e2 = Segment(v2.p, v3[0].p)
    inter1 = intersection(e1, ray)
    inter2 = intersection(e2, ray)
    
    if inter1 != [] and inter2 != []:
        yield from line_walk_node_with_neighbours_v(v3[0], Ray(inter1[0], b), b)
        raise StopIteration
    if inter1 != []:
        yield e1
        yield from line_walk_node_with_neighbours_e(v1, v3[0], Ray(inter1[0], b), b)
        raise StopIteration
    if inter2 != []:
        yield e2
        yield from line_walk_node_with_neighbours_e(v2, v3[0], Ray(inter2[0], b), b)
        raise StopIteration
Пример #16
0
def line_walk_nodes_and_triangles_v(node, ray, b):
    for n_triangles in node.triangles:
        if n_triangles == None:
            continue 

        for n_node in n_triangles.nodes:
            if n_node == node:
                continue

            end_node = n_node.p
            s = Segment(node.p, end_node) 
            inter = intersection(s, ray) 
            
            if inter != [] and is_segment(inter[0]):
                yield s
                yield from line_walk_nodes_and_triangles_v(n_node, Ray(end_node, b), b)
                raise StopIteration

    for n_triangles in node.triangles:
        if n_triangles == None:
            continue

        ds = set(n_triangles.nodes)
        ds.remove(node)
        pnts = list(ds)
        node_i = pnts[0]
        node_j = pnts[1]
        s = Segment(node_i.p, node_j.p)
        inter = intersection(s, ray)

        if inter != []: 
            yield s
            yield from line_walk_nodes_and_triangles_e(node_i, node_j, Ray(inter[0], b), b)
            raise StopIteration
    
    raise StopIteration
Пример #17
0
def update_rays(p1, p2, p3, p4, angle):
    p1 = [p1[0], Ray(p1[0], angle=p1[2] - angle), p1[2] - angle, p1[3]]
    p2 = [p2[0], Ray(p2[0], angle=p2[2] - angle), p2[2] - angle, p2[3]]
    p3 = [p3[0], Ray(p3[0], angle=p3[2] - angle), p3[2] - angle, p3[3]]
    p4 = [p4[0], Ray(p4[0], angle=p4[2] - angle), p4[2] - angle, p4[3]]
    return p1, p2, p3, p4
Пример #18
0
def smallest_rectangle(points) -> Polygon:
    points = points[:-1]
    p1 = [None, None, None, None]  # (Point, Ray, angle, index)
    p2 = [None, None, None, None]
    p3 = [None, None, None, None]
    p4 = [None, None, None, None]

    # Get the leftmost, rightmost, top and bottom starting points
    for i, p in enumerate(points):
        # Leftmost point
        if not p1[0] or p.x < p1[0].x:
            p1 = [p, Ray(p, angle=pi / 2), pi / 2, i]

        # Rightmost point
        if not p2[0] or p.x > p2[0].x:
            p2 = [p, Ray(p, angle=3 * pi / 2), 3 * pi / 2, i]

        # Top point
        if not p3[0] or p.y > p3[0].y:
            p3 = [p, Ray(p, angle=pi), pi, i]

        # Bottom point
        if not p4[0] or p.y < p4[0].y:
            p4 = [p, Ray(p, angle=0), 0, i]

    rotated_angle = 0
    polygons = []

    # Do the "walk" around the convex hull
    while rotated_angle < pi / 2:
        p1_delta = angle_to_next(p1, points)
        p2_delta = angle_to_next(p2, points)
        p3_delta = angle_to_next(p3, points)
        p4_delta = angle_to_next(p4, points)

        if p1_delta < min(p2_delta, p3_delta, p4_delta):
            print("p1")
            delta = p1_delta
            p1[0], p1[3] = next_point(p1, points)
        elif p2_delta < min(p3_delta, p4_delta):
            print("p2")
            delta = p2_delta
            p2[0], p2[3] = next_point(p2, points)
        elif p3_delta < p4_delta:
            print("p3")
            delta = p3_delta
            p3[0], p3[3] = next_point(p3, points)
        else:
            print("p4")
            delta = p4_delta
            p4[0], p4[3] = next_point(p4, points)

        p1, p2, p3, p4 = update_rays(p1, p2, p3, p4, delta)
        rotated_angle += delta
        polygons.append(get_polygon(p1[1], p2[1], p3[1], p4[1]))

    polygons.sort(key=lambda x: x.area)
    return polygons[0]


#     lp = points[(leftmost_point[3]+1) % len(points)]
#     rp = points[(p2[3]+1) % len(points)]
#     tp = points[(p3[3]+1) % len(points)]
#     bp = points[(p4[3]+1) % len(points)]

#     leftmost_point_delta = Ray(leftmost_point[0], lp).angle_between(leftmost_point[1]).evalf()
#     p2_delta = Ray(p2[0], rp).angle_between(p2[1]).evalf()
#     p3_delta = Ray(p3[0], tp).angle_between(p3[1]).evalf()
#     p4_delta = Ray(p4[0], bp).angle_between(p4[1]).evalf()

#     delta = min(leftmost_point_delta, p2_delta, p3_delta, p4_delta)

#     lpa = leftmost_point[2]-delta
#     leftmost_point = (lp, Ray(lp, angle=lpa), lpa, (leftmost_point[3]+1) % len(points))

#     rpa = p2[2]-delta
#     p2 = (p2[0], Ray(p2[0], angle=rpa), rpa, (p2[3]+1) % len(points))

#     tpa = p3[2]-delta
#     p3 = (p3[0], Ray(p3[0], angle=tpa), tpa, (p3[3]+1) % len(points))

#     bpa = p4[2]-delta
#     p4 = (p4[0], Ray(p4[0], angle=bpa), bpa, (p4[3]+1) % len(points))

#     return get_polygon(leftmost_point[1], p2[1], p3[1], p4[1])
Пример #19
0
def visibility_polygon(origin, segments, canvas):
    """
    Computes the visibility polygon given a list of segments and
    a reference point (origin).
    """
    (e1, e2, e3, e4, e5, e6, e7,
     e8) = (Point(0, 0), Point(1, 0), Point(500, 0), Point(500, 1),
            Point(500, 500), Point(499, 500), Point(0, 500), Point(0, 499))
    (s1, s2, s3, s4) = (OrderedSegment(Segment(e2, e3), origin),
                        OrderedSegment(Segment(e4, e5), origin),
                        OrderedSegment(Segment(e6, e7), origin),
                        OrderedSegment(Segment(e8, e1), origin))
    endpoints = ([
        EndPoint(e1, origin, s4),
        EndPoint(e2, origin, s1),
        EndPoint(e3, origin, s1),
        EndPoint(e4, origin, s2),
        EndPoint(e5, origin, s2),
        EndPoint(e6, origin, s3),
        EndPoint(e7, origin, s3),
        EndPoint(e8, origin, s4)
    ])

    for s in segments:
        s = OrderedSegment(s, origin)
        endpoints.extend([
            EndPoint(s.segment.p1, origin, s),
            EndPoint(s.segment.p2, origin, s)
        ])
    endpoints.sort()

    # if not endpoints[0].is_starting_point():
    #     twin = endpoints[0].get_twin()
    #     while endpoints[0] != twin:
    #         endpoints = endpoints[-1:] + endpoints[:-1]

    for i, e in enumerate(endpoints):
        canvas.create_text(e.point.x.evalf() + 250,
                           e.point.y.evalf() + 250,
                           fill="blue",
                           text=f"{i}")

    polygon_points = []
    status = AVLTree()

    # Make sure that we know about any segments that intersect
    # the sweep line at t=0.
    for p in endpoints[1:]:
        if Ray(origin, endpoints[0].point).intersection(
                p.segment.segment) != []:
            if p.segment not in status:
                status.insert(p.segment, p.segment)

    #for e in endpoints:
    i = 0
    while len(polygon_points) < 2 or polygon_points[0] != polygon_points[-1]:
        e = endpoints[i % len(endpoints)]

        if e.segment in status:
            if status.min_item()[0] == e.segment:
                polygon_points.append(e.point)
                draw_polygon(canvas, polygon_points)
                if not e.is_starting_point() and len(status) > 1:
                    for above_segment in status:
                        if above_segment == e.segment:
                            continue
                        try:
                            polygon_points.append(
                                Ray(origin, e.point).intersection(
                                    above_segment.segment)[0])
                            draw_polygon(canvas, polygon_points)
                            break
                        except:
                            pass
            if not e.is_starting_point():
                status.remove(e.segment)
        else:
            # if not e.is_starting_point():
            #     raise Exception("What the hell")

            status.insert(e.segment, e.segment)
            if status.min_item()[0] == e.segment:
                if len(status) > 1:
                    for above_segment in status:
                        if above_segment == e.segment:
                            continue
                        try:
                            polygon_points.append(
                                Ray(origin, e.point).intersection(
                                    above_segment.segment)[0])
                            draw_polygon(canvas, polygon_points)
                            break
                        except:
                            pass
                polygon_points.append(e.point)
                draw_polygon(canvas, polygon_points)
        i += 1
        if i > 100:
            break
Пример #20
0
    def perform_sweep(self):
        print("\nStatus at start: " + str(len(self.status)))

        for ep in self.event_queue:
            print("\nStatus: " + str(len(self.status)))

            if ep.type == START_VERTEX:
                print("START_VERTEX")
                status_segment = StatusSegment(ep, ep.twin, self.origin)

                print("current segment: " + str(status_segment.segment) +
                      str(status_segment.current_distance))

                ep.status_segment = status_segment
                ep.twin.status_segment = status_segment
                if self.status.__len__() == 0:
                    self.status.update(
                        {status_segment.current_distance: status_segment})
                    self.visibility_polygon.append(ep.p)
                    print("empty status. Append")
                else:
                    first_in_status = self.status.peekitem(index=0)

                    print("first in status and distance: " +
                          str(first_in_status[1].segment) + ": " +
                          str(first_in_status[1].current_distance))

                    current_ray = Ray(self.origin, ep.p)
                    intersection_point = current_ray.intersection(
                        first_in_status[1].segment)
                    first_in_status[1].current_distance = distance(
                        intersection_point[0], self.origin)
                    print("First in status new distance: " +
                          str(first_in_status[1].current_distance))
                    self.status.update(
                        {status_segment.current_distance:
                         status_segment})  # insert the new segment to status
                    self.status.__delitem__(first_in_status[0])
                    self.status.update({
                        first_in_status[1].current_distance:
                        first_in_status[1]
                    })  #update the key distance to the origin
                    new_first_in_status = self.status.peekitem(index=0)
                    if new_first_in_status[1] != first_in_status[1]:
                        self.visibility_polygon.append(intersection_point[0])
                        self.visibility_polygon.append(ep.p)
                        print("normal status. Append")

            elif ep.type == END_VERTEX:
                print("END_VERTEX")
                first_in_status = self.status.peekitem(index=0)
                print("first in status and distance: " +
                      str(first_in_status[1].segment) + ": " +
                      str(first_in_status[1].current_distance))
                self.status.__delitem__(ep.status_segment.current_distance)
                print("ep status segment and distance: " +
                      str(ep.status_segment.segment) + ": " +
                      str(ep.status_segment.current_distance))
                if self.status.__len__() == 0:
                    self.visibility_polygon.append(ep.p)
                    print("empty status. Append")
                else:
                    new_first_in_status = self.status.peekitem(index=0)
                    if new_first_in_status[1] != first_in_status[1]:
                        current_ray = Ray(self.origin, ep.p)
                        intersection_point = current_ray.intersection(
                            new_first_in_status[1].segment)
                        self.visibility_polygon.append(ep.p)
                        self.visibility_polygon.append(intersection_point[0])
                        print("normal status. Append")
from typing import List, Tuple

import pytest
from sympy import Rational, Ray, Segment, Point, cos, pi

from custom_geometry import compute_reflection, prepare_intersections, compute_intersections, rotate_segment, \
    change_size_segment
from custom_ray import MyRay


@pytest.mark.parametrize(
    ['ray', 'surface', 'intensity', 'r_factor', 'expected'],
    [
        [Ray(Point(0, 0), Point(1, 1)), Segment(Point(2, 0), Point(2, 4)), 1, 1, (Ray(Point(2, 2), Point(0, 4)), 1)],
        [Ray(Point(0, 0), Point(1, 0)), Segment(Point(2, 0), Point(2, 4)), 0.5, 0.98,
         (Ray(Point(2, 0), Point(0, 0)), 0.49)],
        [Ray(Point(0, 0), Point(1, 0)), Segment(Point(1, 1), Point(3, 3)), 1, 0.9, None],
        [Ray(Point(2, 4), Point(4, 0)), Segment(Point(2, 2), Point(3, 0)), 0.78, 0.5, None],
    ]
)
def test_compute_reflection(ray: Ray, surface: Segment, intensity: float, r_factor: float, expected: (Ray, float)):
    actual = compute_reflection(ray=ray, surface=surface, intensity=intensity, reflective_factor=r_factor)
    assert actual == expected


@pytest.mark.parametrize(
    ['rays', 'road', 'cosine_error', 'expected'],
    [
        [[MyRay(Point(0, 0), 270+45, 45)], Segment(Point(0, -4000), Point(8000, -4000)), "No", [(Rational(4000), 1.0)]],
        [[MyRay(Point(0, 0), 270+45, 45)], Segment(Point(0, -4000), Point(8000, -4000)), "Yes",
         [(Rational(4000), cos(pi/4))]],
Пример #22
0
def smallest_rectangle(p):
    # mp.dps = 10
    ch = convex_hull(p)
    print(ch)
    # Find extreme points
    x_min_index = 0
    y_max_index = uppermost_point_index(ch)
    x_max_index = rightmost_point_index(ch)
    y_min_index = lowermost_point_index(ch)

    # Create vertical and horizontal Rays
    ray_1 = Ray(ch[x_min_index], angle=pi / 2)
    ray_2 = Ray(ch[y_min_index], angle=0)
    ray_3 = Ray(ch[x_max_index], angle=pi / 2)
    ray_4 = Ray(ch[y_max_index], angle=0)

    min_rectangle = Polygon((0, 0), (99999999, 0), (99999999, 99999999),
                            (0, 99999999))

    rotated_angle = 0
    while rotated_angle <= pi / 2:
        # Convert Rays to lines
        line_1 = Line(ray_1)
        line_2 = Line(ray_2)
        line_3 = Line(ray_3)
        line_4 = Line(ray_4)

        # Find the intersections of the lines
        p1 = line_1.intersection(line_2)[0].evalf()
        p2 = line_2.intersection(line_3)[0].evalf()
        p3 = line_3.intersection(line_4)[0].evalf()
        p4 = line_4.intersection(line_1)[0].evalf()
        current_rectangle = Polygon(p1, p2, p3, p4)

        # Calculate the area of the rectangle
        try:
            if current_rectangle.area < min_rectangle.area:
                min_rectangle = current_rectangle
        except AttributeError:
            min_rectangle = current_rectangle

        # Find the next Ray on the convex hull for each Ray in counter clockwise direction
        next_ray_1 = Ray(ch[x_min_index], ch[get_prev_index(ch, x_min_index)])
        next_ray_2 = Ray(ch[y_min_index], ch[get_prev_index(ch, y_min_index)])
        next_ray_3 = Ray(ch[x_max_index], ch[get_prev_index(ch, x_max_index)])
        next_ray_4 = Ray(ch[y_max_index], ch[get_prev_index(ch, y_max_index)])
        #print(ray_1)
        #print(next_ray_1)

        # Find the minimal angle to rotate each Ray until one aligns with the convex hull
        angle_1 = float(positive_angle(next_ray_1.closing_angle(ray_1)))
        angle_2 = float(positive_angle(next_ray_2.closing_angle(ray_2)))
        angle_3 = float(positive_angle(next_ray_3.closing_angle(ray_3)))
        angle_4 = float(positive_angle(next_ray_4.closing_angle(ray_4)))
        #print(angle_1, angle_2, angle_3, angle_4)
        min_angle = min(angle_1, angle_2, angle_3, angle_4)

        # Rotate all Rays around its origin with the angle calculated
        """ray_1 = ray_1.rotate(min_angle)
        ray_2 = ray_2.rotate(min_angle)
        ray_3 = ray_3.rotate(min_angle)
        ray_4 = ray_4.rotate(min_angle)"""

        ray_1 = Ray(ray_1.p1, angle=atan(ray_1.slope) + min_angle)
        ray_2 = Ray(ray_2.p1, angle=atan(ray_2.slope) + min_angle)
        ray_3 = Ray(ray_3.p1, angle=atan(ray_3.slope) + min_angle)
        ray_4 = Ray(ray_4.p1, angle=atan(ray_4.slope) + min_angle)

        # Set the next point in the convex hull as the origin of the Ray that alligned
        # and decrement the index

        slope_1 = next_ray_1.slope
        slope_2 = next_ray_2.slope
        slope_3 = next_ray_3.slope
        slope_4 = next_ray_4.slope

        if min_angle == angle_1:
            if slope_1 == oo:
                slope_1 = pi / 2
            ray_1 = Ray(next_ray_1.p2, angle=atan(slope_1))
            x_min_index = get_prev_index(ch, x_min_index)
        elif min_angle == angle_2:
            if slope_2 == oo:
                slope_2 = pi / 2
            ray_2 = Ray(next_ray_2.p2, angle=atan(slope_2))
            y_min_index = get_prev_index(ch, y_min_index)
        elif min_angle == angle_3:
            if slope_3 == oo:
                slope_3 = pi / 2
            ray_3 = Ray(next_ray_3.p2, angle=atan(slope_3))
            x_max_index = get_prev_index(ch, x_max_index)
        elif min_angle == angle_4:
            if slope_4 == oo:
                slope_4 = pi / 2
            ray_4 = Ray(next_ray_4.p2, angle=atan(slope_4))
            y_max_index = get_prev_index(ch, y_max_index)
        else:
            print("fail")

        rotated_angle += min_angle

    return min_rectangle
Пример #23
0
def repeat():

    global waypoint_pointer
    global in_pivot_mode
    stopping_flag = False
    msg = package_msg(0, 0, 0, 0)
    #get latest available data
    bot_x, bot_y, bot_front_x, bot_front_y = get_db_data()

    #deal with goal changes
    goal_x, goal_y, wp_count, loop_on = get_goal(waypoint_pointer)

    Bot_Loc = Point2D(bot_x, bot_y)
    Goal_Loc = Point2D(goal_x, goal_y)

    #distance between goal and present loc
    eucledian_dist_error = (Bot_Loc.distance(Goal_Loc)).evalf()

    #angle to move so that vehicle heading is correct
    r1 = Ray((bot_x, bot_y), (goal_x, goal_y))
    r2 = Ray((bot_x, bot_y), (bot_front_x, bot_front_y))
    angle_error = math.degrees(r1.closing_angle(r2).evalf())

    #redundant check, do not remove.
    if angle_error < -180:
        angle_error = angle_error + 360
    if angle_error > 180:
        angle_error = angle_error - 360

    #####################################UNCOMMENT THESE FOR DEBUGGING######################################
    # print("angle error")
    # print(angle_error)

    # print("distance error")
    # print(eucledian_dist_error)

    # print("Steer PID")
    # print(BOT_1.Steer)

    # print("Throt PID")
    # print(BOT_1.Thr)
    # print("LEFT WHEEL")
    # print(out_left_wheel)

    # print("RIGHT WHEEL")
    # print(out_right_wheel)

    # print("Goal")
    # print(get_goal(waypoint_pointer))
    #######################################################################################################

    # pivot if angle_error is too big
    #TO-DO: change hard coded values into parameter's. Maybe a class that can be accessed from command line
    if abs(angle_error) > 60 or in_pivot_mode:
        in_pivot_mode = True
        if abs(angle_error) >= 35:
            pivot_speed = int(
                np.interp(abs(angle_error), [35, 180], [400, 500]))
            print("pivoting")
            if angle_error > 0:
                #pivot anti-cws
                msg = package_msg(0, pivot_speed, 1, pivot_speed)
            else:
                #pivot cws
                msg = package_msg(1, pivot_speed, 0, pivot_speed)
        else:
            in_pivot_mode = False

    if in_pivot_mode == False:

        #what to do when approaching goal, i.e run precision controller
        if (eucledian_dist_error <= 100 and eucledian_dist_error > 40):
            left_direction = 1
            left_speed = 600 + 3 * angle_error
            right_direction = 1
            right_speed = 600 - 3 * angle_error
            msg = package_msg(1, left_speed, 1, right_speed)

        elif (eucledian_dist_error <= 40):
            if stopping_flag == False:
                waypoint_pointer = waypoint_pointer + 1
                if waypoint_pointer == wp_count:
                    if loop_on:
                        waypoint_pointer = 0
                    else:
                        msg = package_msg(0, 0, 0, 0)
            else:
                #stop
                msg = package_msg(0, 0, 0, 0)

        #convert PID value into motor driver understandable value
        #xyz_direction = 1 for forward

        else:

            #calculate PID values based on error obtained
            BOT_1.Steer = BOT_1.pid_steering_controller(angle_error)
            BOT_1.Thr = BOT_1.pid_throttle_controller(-eucledian_dist_error)

            #get computed values from PID
            out_left_wheel = BOT_1.Output_left_wheel()
            out_right_wheel = BOT_1.Output_right_wheel()

            if (out_left_wheel >= 0):
                left_direction = 1
                left_speed = out_left_wheel
            else:
                left_direction = 0
                left_speed = -out_left_wheel

            if (out_right_wheel >= 0):
                right_direction = 1
                right_speed = out_right_wheel
            else:
                right_direction = 0
                right_speed = -out_right_wheel

            msg = package_msg(left_direction, left_speed, right_direction,
                              right_speed)

    #pack the message and send
    sock.sendto(msg.encode(), (udp_host, udp_port))
    #repeat every x seconds
    threading.Timer(0.3, repeat).start()