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
def test_find_segments_in_polylines_two_lines(self): top = [Point2D(x, 0) for x in range(0, 5)] bottom = [Point2D(x, 4) for x in range(0, 5)] points = top + bottom originating_point = Point2D(0, 0) points_rotated = [] for point in points: points_rotated.append(point.rotate(pi / 4, originating_point)) segments_reference = { Segment(points_rotated[0], points_rotated[4]), Segment(points_rotated[5], points_rotated[9]) } finder = RansacSegmentsFinder(0.001, 1.1) segments = finder.find_segments_in_points(points_rotated) for segment_real in segments: found_similarities = 0 similar = None for segment_reference in segments_reference: if self.are_segments_close(segment_real, segment_reference): similar = segment_reference found_similarities += 1 self.assertEqual(1, found_similarities) segments_reference.remove(similar)
def eyes_add_highlight(image, face_landmarks): """Add highlight in eyes This function can uses for many people """ highlight = cv2.imread( CURRENT_DIRNAME + '/eyes_highlight.png', cv2.IMREAD_UNCHANGED) line1 = Segment(Point(landmark[134]), Point(landmark[145])) line2 = Segment(Point(landmark[139]), Point(landmark[150])) ls = intersection(line1, line2) dx, dy = (landmark[150] - landmark[139]) / 5 x, y = int(ls[0].x) - dx, int(ls[0].y) - dy w = np.linalg.norm(landmark[150] - landmark[139]) ratio = w / highlight.shape[1] * 100 x = int(x - highlight.shape[0] * (ratio / 100) / 2) y = int(y - highlight.shape[1] * (ratio / 100) / 2) image = merge(image, highlight, x, y, ratio) line1 = Segment(Point(landmark[114]), Point(landmark[124])) line2 = Segment(Point(landmark[120]), Point(landmark[129])) ls = intersection(line1, line2) dx, dy = (landmark[129] - landmark[120]) / 5 x, y = int(ls[0].x) - dx, int(ls[0].y) - dy w = np.linalg.norm(landmark[129] - landmark[120]) ratio = w / highlight.shape[1] * 100 x = int(x - highlight.shape[0] * (ratio / 100) / 2) y = int(y - highlight.shape[1] * (ratio / 100) / 2) image = merge(image, highlight, x, y, ratio) return image
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
def shift_one_segment(reflective_segments: List[Segment], axis: str) -> List[Segment]: """ Shift one segment from list of reflective segments of an individual :param reflective_segments: List of all reflective segments of one individual :param axis: Indicator whether to use X-axis or Y-axis :return: List of all reflective segments with one shifted """ chosen_segment_index = random.randint(0, len(reflective_segments) - 1) chosen_segment = reflective_segments[chosen_segment_index] shift_amount = random.randint(-100, 100) if axis == "x": shifted_segment = Segment( Point(chosen_segment.p1.x + shift_amount, chosen_segment.p1.y), Point(chosen_segment.p2.x + shift_amount, chosen_segment.p2.y)) else: shifted_segment = Segment( Point(chosen_segment.p1.x, chosen_segment.p1.y + shift_amount), Point(chosen_segment.p2.x, chosen_segment.p2.y + shift_amount)) modified_segments = reflective_segments[:chosen_segment_index] modified_segments.append(shifted_segment) modified_segments = modified_segments + reflective_segments[ chosen_segment_index + 1:] return modified_segments
def get_intersection_points2D_with_img(intersection_points: list, plane_range: np.ndarray) -> tuple: x, y = intersection_points p1 = Point(x[0], y[0]) p2 = Point(x[1], y[1]) intersection_line = Line(p1, p2) points1 = Point(plane_range[0, 1], plane_range[0, 0]), Point(plane_range[0, 1], plane_range[1, 0]) points2 = Point(plane_range[0, 1], plane_range[1, 0]), Point(plane_range[1, 1], plane_range[1, 0]) points3 = Point(plane_range[1, 1], plane_range[1, 0]), Point(plane_range[1, 1], plane_range[0, 0]) points4 = Point(plane_range[1, 1], plane_range[0, 0]), Point(plane_range[0, 1], plane_range[0, 0]) line1 = Segment(*points1) line2 = Segment(*points2) line3 = Segment(*points3) line4 = Segment(*points4) result = tuple( filter( lambda x: x != [], intersection_line.intersection(line1) + intersection_line.intersection(line2) + intersection_line.intersection(line3) + intersection_line.intersection(line4))) return (float(result[0].x), float(result[0].y)), (float(result[1].x), float(result[1].y))
def generate_segments(self, points): segments = [] for i in range(1, len(points)): if i != len(points) - 1: segments.append(Segment(points[i - 1], points[i])) else: segments.append(Segment(points[i - 1], points[0])) self.segments = segments
def crash(self, other): seg1_1 = Point(self.x_position, self.y_position) seg1_2 = Point(self.new_x_position, self.new_y_position) seg2_1 = Point(other.x_position, other.y_position) seg2_2 = Point(other.new_x_position, other.new_y_position) seg1 = Segment(seg1_1, seg1_2) seg2 = Segment(seg2_1, seg2_2) return len(seg1.intersection(seg2))
def crossing(p1: Point, p2: Point, p3: Point, p4: Point): line1, seg1 = Line(p1, p2), Segment(p1, p2) line2, seg2 = Line(p3, p4), Segment(p3, p4) intersect = line1.intersection(line2) if intersect: seg1 = Segment(p1, p2) seg2 = Segment(p3, p4) pi = intersect[0] return seg1.contains(pi) and seg2.contains(pi)
def separaArestas(p1, p2, p3, p4=None): """.""" arestas_separadas = [] if p1 != p2: arestas_separadas.append(Segment(Point(p1.x, p1.y), Point(p2.x, p2.y))) if p2 != p3: arestas_separadas.append(Segment(Point(p2.x, p2.y), Point(p3.x, p3.y))) if p3 != p4 and not (p4 is None): arestas_separadas.append(Segment(Point(p3.x, p3.y), Point(p4.x, p4.y))) return arestas_separadas
def intersection_of_segments(p1_x, p1_y, p2_x, p2_y): """Координаты точки пересечения двух отрезков""" s1 = Segment(p1_y, p1_x) s2 = Segment(p2_y, p2_x) intersection = s1.intersection(s2) if len(intersection) != 0: intersection = intersection[0] return float(intersection.y), float(intersection.x) else: return 0, 0
def crash( self, other ): # Функция для определения столкновения двух самолётов. Мы создаём для каждого самолёта по отрезку от старого положения до нового. Функция возвращает список точек пересечения двух отрезков. Если длина списка нулевая, пересечения нет. Если больше 0, значит пересечение есть и самолёты столкнулись. seg1_1 = Point(self.old_x, self.old_y) seg1_2 = Point(self.x_position, self.y_position) seg2_1 = Point(other.old_x, other.old_y) seg2_2 = Point(other.x_position, other.y_position) seg1 = Segment(seg1_1, seg1_2) seg2 = Segment(seg2_1, seg2_2) return len(seg1.intersection(seg2))
def test_get_segments_simple(self): t = Polyline() points = [Point2D(0, 0), Point2D(1, 1), Point2D(2, 2)] for point in points: t.add(point) self.assertListEqual( t.get_segments(), [Segment(points[0], points[1]), Segment(points[1], points[2])])
def CalcShotAngle(self): shifted_pckt = self.pocket.center - self.target.loc self.ghostball = (self.target.loc + self.cue.Diameter * (self.target.loc - self.pocket.center) / self.pocket.center.distance(self.target.loc)) self.aiming_vec = Segment(self.cue.loc, self.ghostball) self.target_vec = Segment(self.pocket.center, self.ghostball) self.shotangle = self.aiming_vec.angle_between(self.target_vec).evalf() shifted_ghost = self.ghostball - self.cue.loc self.aiming_vec_ag = math.atan(shifted_ghost.y / shifted_ghost.x) if shifted_ghost.x < 0: self.aiming_vec_ag = math.pi + self.aiming_vec_ag
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
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 add_bounding_box(self): # Find extreme points margin = 40 top_y = 400 + margin #uppermost_point_index(self.event_queue) bottom_y = 130 - margin #lowermost_point_index(self.event_queue) right_x = 600 + margin #rightmost_point_index(self.event_queue) left_x = 200 - margin #leftmost_point_index(self.event_queue) # Create the bounding box and add it to event queue s1 = Segment(Point(right_x, top_y), Point(right_x, bottom_y)) s2 = Segment(Point(right_x - 5, bottom_y), Point(left_x, bottom_y)) s3 = Segment(Point(left_x, bottom_y + 5), Point(left_x, top_y)) s4 = Segment(Point(left_x + 5, top_y), Point(right_x, top_y + 5)) p = [s1, s2, s3, s4] self.segments.extend(p)
def paralline(nl=2, x0=0, y0=100, x1=33, y1=66): p1, p2 = Point(x0, y0), Point(x1, y1) s1 = Segment(p1, p2) # Create a new Line perpendicular to s1 passing through the point p1 l1 = s1.perpendicular_line(p1) l2 = s1.perpendicular_line(p2) p1 in l1 p2 in l2 s1.is_perpendicular(l2) s1.is_perpendicular(l1) #p11 = subs_point(l1, s1.length) # find coords of parallel nl segments from each side of the transect x11, y11 = zeros(2*nl+1), zeros(2*nl+1) x22, y22 = zeros(2*nl+1), zeros(2*nl+1) j=0 for i in range(-nl,nl+1): p11 = subs_point(l1, 1*i/s1.length) # divide unit segment on its length x111, y111 = p11.args x11[j], y11[j] = float64(x111), float64(y111) p22 = subs_point(l2, 1*i/s1.length) # divide unit segment on its length x222, y222 = p22.args x22[j], y22[j] = float64(x222), float64(y222) j+=1 # # Checking that segments are parallel and same length # s2 = Segment(p11,p22) # s2.is_parallel(s1) # s1.length - s2.length # plt.plot([x0, x1], [y0, y1]) # plt.plot([x11, x22],[y11, y22], 'k') return x11, y11, x22, y22
def line_walk_nodes_and_edges_and_triangles(triang, a, v1, v2, b): b, ray = inf_ray(a, b, 1000) e = Segment(v1, v2) node_a = None node_v1 = None node_v2 = None count = 0 for idr, node in triang[0].items(): if count == 3: break if node.p.equals(a): node_a = node count = count + 1 if node.p.equals(v1): node_v1 = node count = count + 1 if node.p.equals(v2): node_v2 = node count = count + 1 if is_vertex_of_segment(a, e): yield from line_walk_nodes_and_edges_and_triangles_v(node_a, ray, b) raise StopIteration else: yield e yield from line_walk_nodes_and_edges_and_triangles_e(node_v1, node_v2, ray, b) raise StopIteration
def find_segments_with_density(line: Line, points: Iterable[Point2D], epsilon: float) -> List[FoundSegment]: line_points = SegmentsInLineFinder.project_on_line(line, points) segments = [] current_start_point = None current_segment_points_number = 0 for i, current_point in enumerate(line_points): if current_start_point is None: current_start_point = current_point current_segment_points_number = 0 current_segment_points_number += 1 if i == len(line_points) - 1 \ or abs(current_point.line_coordinate - line_points[i + 1].line_coordinate) > epsilon: if current_point != current_start_point: segment = Segment(current_start_point.projection, current_point.projection) density = current_segment_points_number / segment.length segments.append( SegmentsInLineFinder.FoundSegment( segment, current_segment_points_number, density)) current_start_point = None return segments
def get_line_segments(line_data): def adjust_pos(point, cmd): direction = cmd[0] distance = int(cmd[1:]) x = point[0] y = point[1] if direction == 'R': return x + distance, y elif direction == 'L': return x - distance, y elif direction == 'U': return x, y + distance elif direction == 'D': return x, y - distance line_segments = [] p1 = (0, 0) p2 = (0, 0) for index, cmd in enumerate(line_data): p2 = adjust_pos(p2, cmd) seg = Segment(Point(p1[0], p1[1]), Point(p2[0], p2[1])) line_segments.append((seg, cmd)) p1 = p2 return line_segments
def line_walk_node_with_neighbours(triang, a, v1, v2, b): b, ray = inf_ray(a, b, 1000) e = Segment(v1, v2) node_a = None node_v1 = None node_v2 = None count = 0 for idr, node in triang.items(): if count == 3: break if node.p.equals(a): node_a = node count = count + 1 if node.p.equals(v1): node_v1 = node count = count + 1 if node.p.equals(v2): node_v2 = node count = count + 1 if is_vertex_of_segment(a, e): yield from line_walk_node_with_neighbours_v(node_a, ray, b) else: yield e yield from line_walk_node_with_neighbours_e(node_v1, node_v2, ray, b)
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 partir(ent, mostra=True): """.""" n = int(ent[0][0]) ent.pop(0) arestas = [] for i in range(n): a = ent[i] arestas.append(Segment(Point(a[0], a[1]), Point(a[2], a[3]))) arestas_teste = list(arestas) arestas_final = [] i, j = 0, 0 while i < len(arestas_teste): l1 = arestas_teste[i] j = 1 add_final = True while j < len(arestas_teste): l2 = arestas_teste[j] if l1.contains(l2) or l2.contains(l1): ordenado = separaArestas(*sorted([l1.p1, l1.p2, l2.p1, l2.p2], key=lambda a: (a.x, a.y))) [arestas_teste.append(k) for k in ordenado] arestas_teste.pop(j) add_final = False break elif len(intersection(l1, l2)) > 0: ponto_intersecao = intersection(l1, l2)[0] # Entra aqui se o ponto estiver no meio do segmento if not (ponto_intersecao in [l1.p1, l1.p2] and ponto_intersecao in [l2.p1, l2.p2]): if ponto_intersecao in [l1.p1, l1.p2]: add_final = False ordenado = separaArestas(l2.p1, ponto_intersecao, l2.p2) ordenado += [l1] [arestas_teste.append(k) for k in ordenado] arestas_teste.pop(j) continue elif ponto_intersecao in [l2.p1, l2.p2]: add_final = False ordenado = separaArestas(l1.p1, ponto_intersecao, l1.p2) [arestas_teste.append(k) for k in ordenado] break j += 1 if add_final: arestas_final.append(l1) arestas_teste.pop(0) i = 0 out = str(len(arestas_final)) if mostra: print(len(arestas_final)) for i in arestas_final: out += f'\n{i.p1.x} {i.p1.y} {i.p2.x} {i.p2.y}' if mostra: print(float(i.p1.x), float(i.p1.y), float(i.p2.x), float(i.p2.y)) # plt.xlim(-1000, 50000) # plt.ylim(-1000, 50000) # j = 1 # for i in arestas_final: # plt.plot([i.p1.x, i.p2.x], [i.p1.y, i.p2.y]) # plt.savefig(f'img/{j}.png') # j += 1 return out
def test_find_segments_two_segments(self): line = Line(Point2D(0, 0), Point2D(10, 0)) points_coords = ( (-10, 5), (-5, -5), (0, 5), (5, -5), (15, 10), (18, 5) ) points = [Point2D(coord[0], coord[1]) for coord in points_coords] segments_reference = [Segment(Point2D(-10, 0), Point2D(5, 0)), Segment(Point2D(15, 0), Point2D(18, 0))] segments_test = SegmentsInLineFinder.find_segments(line, points, 6) self.assertListEqual(segments_reference, segments_test)
def test_get_objects_separate_lists(self): a = Area() point = Point2D(1, 1) segment = Segment(Point2D(3, 3), Point2D(4, 4)) a.add_object(Point2D, point) a.add_object(Segment, segment) self.assertListEqual(a.get_objects(Point2D), [point]) self.assertListEqual(a.get_objects(Segment), [segment])
def intersect_segment_polyline(segment, x, y): c_s = 0 # current segment m_s = min(len(x), len(y)) - 1 # last segment point = [] while len(point) < 1 and c_s < m_s: point = segment.intersection( Segment(Point(x[c_s], y[c_s]), Point(x[c_s + 1], y[c_s + 1]))) c_s += 1 return point
def intersection_of_segments(p1_x: Point, p1_y: Point, p2_x: Point, p2_y: Point) -> tuple: """ Координаты точки пересечения двух отрезков :param p1_x: Первая точка первого отрезка :param p1_y: Вторая точка первого отрезка :param p2_x: Первая точка второго отрезка :param p2_y: Вторая точка второго отрезка :return: Кортеж координат точки пересечения отрезков """ s1 = Segment(p1_x, p1_y) s2 = Segment(p2_x, p2_y) intersection = s1.intersection(s2) if len(intersection) != 0: intersection = intersection[0] return float(intersection.x), float(intersection.y) else: return None, None
def control(data): msg = drive_param() global prev_error global velocity global kp global kd global flag global length global path_y global path_x myrobot = robot() myrobot.set(data.pose.position.x, data.pose.position.y) #update current pose ''' flag is set when path arrives from planner node''' if flag == 1: '''find distance from robot and the desired track (cross track error)''' for index in range(0, ((length / 2) - 1)): myrobot.set(data.pose.position.x, data.pose.position.y) #update current pose print("curr_y = ", myrobot.y, "curr_x = ", myrobot.x) print("path_y = ", path_y[index], "path_x = ", path_x[index]) p1 = Point(path_y[index], path_x[index]) # points from desired path p2 = Point(path_y[index + 1], path_x[index + 1]) s = Segment(p1, p2) error = -float(s.distance( myrobot.curr_pose)) # x in the equation --> -x-Lsin(theta) if (myrobot.y < path_y[index]): error = -error #-error = left turn, +ve error = right turn print("error = ", error) '''calculate steering angle using pid controller''' #int_error += error # integral not used diff_error = error - prev_error # differential angle = -(kp * error) - (kd * diff_error) # - (ki * int_CTE) if angle < -100: angle = -100 elif angle > 100: angle = 100 prev_error = error msg.angle = angle velocity = 10.0 msg.velocity = velocity #print("flag = 1, vel = " , msg.velocity, ", angle = " , msg.angle) pub.publish(msg) flag = 0 ''' keep vel and steering to 0 if no plan arrives and flag is not set''' angle = 0 velocity = 0.0 msg.angle = angle msg.velocity = velocity # constant velocity print("flag = 0, vel = ", msg.velocity, ", angle = ", msg.angle) pub.publish(msg)
def load(self, file_name): f = open(file_name, "r") for l in f: coords = l.split(" ") x1 = int(coords[0]) y1 = int(coords[1]) x2 = int(coords[2]) y2 = int(coords[3]) self.segments.append(Segment(Point(x1, y1), Point(x2, y2))) f.close()