def cross_segment(self, segment): result = [] y = lambda x: segment.k * x + segment.b cache = { "{}-{}".format(p.x, p.y): Segment(p, Point(p.x, y(p.x))).len for p in self.points } def min_p(points, prev=None, delta=1): r = [] if not prev: dists = [cache["{}-{}".format(p.x, p.y)] for p in points] else: dists = [ cache["{}-{}".format(p.x, p.y)] / Segment(p, prev).len for p in points ] m_v = min(dists) if m_v < delta: r.append(points[dists.index(m_v)]) return r result += min_p(self.points) if result: index = self.points.index(result[0]) points = self.points[:index] + self.points[index + 1:] result += min_p(points, prev=result[-1]) return list( sorted(result, key=lambda item: Segment(item, segment.p1).len))
class SegmentTestCase(unittest.TestCase): def setUp(self): self.a = (0,0) self.b = (4,0) self.s = Segment(self.a,self.b) def test_init(self): s = self.s self.assertIsInstance(s.a, Vec) self.assertIsInstance(s.b, Vec) self.assertEqual(s.a, self.a) self.assertEqual(s.b, self.b) def test_equal(self): self.assertEqual(self.s, (self.a, self.b)) def test_getitem(self): self.assertEqual(self.s[0], self.a) self.assertEqual(self.s[1], self.b) def test_iter(self): t = tuple(p for p in self.s) self.assertEqual(t, self.s) self.assertEqual(self.s, t) def test_pos_point(self): self.assertEqual(self.s.pos_point((2,0)),0) self.assertTrue(self.s.pos_point((2,2)) > 0) self.assertTrue(self.s.pos_point((2,-2)) < 0)
def defineCrossSections(self): """ Define cross-sections as two lists of segments, one for each side of the road returns ("segment list side1","segment list side 2") """ cs1 = [] cs2 = [] for i in range(1, self.nPoints): x1 = self.points[i - 1][0] y1 = self.points[i - 1][1] x2 = self.points[i][0] y2 = self.points[i][1] roadSegLen = np.sqrt((x2 - x1)**2 + (y2 - y1)**2) nCS = int(np.ceil(roadSegLen / float(CSDIST))) segFrac = 1 / float(nCS) P0 = self.points[i - 1] P1 = self.points[i] U = P1 - P0 roadDir = U / roadSegLen roadNormal1 = np.array([-1 * roadDir[1], roadDir[0]]) roadNormal2 = np.array([roadDir[1], -1 * roadDir[0]]) for csInd in range(0, nCS): Pi = P0 + U * (csInd + 0.5) * segFrac cs1.append(Segment(Pi, Pi + roadNormal1 * MAXDIST)) cs2.append(Segment(Pi, Pi + roadNormal2 * MAXDIST)) return (cs1, cs2)
def add_point_to_segments(point, segments): if not segments: # First point: start a segment. segments.append(Segment(point, point)) elif segments[-1].point1 is segments[ -1].point2: # Second point: finish the first segment. segments[-1].point2 = point else: # We're off and running: validate segments. previous_point = segments[-1].point2 segments.append(Segment(previous_point, point))
def __get_closest(self, p1, list_of_pt): closest = list_of_pt[0] closest_dist = Segment(p1, list_of_pt[0]).norm2() for pt in list_of_pt: dist = Segment(p1, pt).norm2() if dist < closest_dist: closest_dist = dist closest = pt return closest
def filter_nearest(self, points, delta): l_2 = int(len(points) / 2) r1, r2 = [points[0]], [points[-1]] for i in range(1, l_2): c1, c2 = points[i], points[len(points) - i] l1, l2 = r1[-1], r2[-1] if Segment(c1, l1).len**2 > delta and Segment(c2, l2).len**2 > delta: r1.append(c1) r2.append(c2) return r1 + r2[::-1]
def plotCell(self, ax, row, col, color="grey", style="--", width=0.5): # plot index grid cell # indexing clockwise from lower left corner x1 = x2 = x5 = self.xmin + col * self.cellsize x3 = x4 = self.xmin + (col + 1) * self.cellsize y1 = y4 = y5 = self.ymax - (row + 1) * self.cellsize y2 = y3 = self.ymax - row * self.cellsize S1 = Segment(np.array([x1, y1]), (np.array([x2, y2]))) S2 = Segment(np.array([x2, y2]), (np.array([x3, y3]))) S3 = Segment(np.array([x3, y3]), (np.array([x4, y4]))) S4 = Segment(np.array([x4, y4]), (np.array([x5, y5]))) gridSegments = [S1, S2, S3, S4] plotSegments(ax, gridSegments, color=color, style=style, width=width)
def to_segment(s): if isinstance(s, Segment): return s points = s.db_id.points if s.db_id else s.points width = s.db_id.width if s.db_id else s.width start, end = (Point(x, y) for x, y in points) return Segment.from_start_end(start, end, width, layer_of(s))
def visibility_graph_brute(collection: Collection) -> Collection: """ Generates visibility graph in O(n^3) """ # create graph graph = Collection(points=collection.all_points) # get all segments segments = collection.all_segments # get polygons for each point polygons = defaultdict(list) for poly in collection.polygons: for p in poly.points: polygons[p].append(poly) # for each pair of points for p1, p2 in combinations(collection.all_points, 2): s = Segment(p1, p2) # if this segment is a diagonal of polygon ignore it # if is_diagonal(s, polygons): # continue # if segment intersects with any other segment if any( intersection(*s, *seg, restriction_1='segment', restriction_2='segment') for seg in segments if (p1 not in seg) and (p2 not in seg) ): continue # add to graph graph.segments.add(s) return graph
def generate_triangle(plot_side): min_segment = plot_side / 10 point_1 = Point(uniform(0, plot_side), uniform(0, plot_side)) while True: point_2 = Point(uniform(0, plot_side), uniform(0, plot_side)) if Point.distance_between(point_1, point_2) > min_segment: break while True: point_3 = Point(uniform(0, plot_side), uniform(0, plot_side)) if min(Point.distance_between(point_1, point_3), Point.distance_between(point_2, point_3)) > min_segment: break segment_1 = Segment(point_1, point_2) segment_2 = Segment(point_1, point_3) segment_3 = Segment(point_2, point_3) return segment_1, segment_2, segment_3
def last_changes(final_list_of_segments, final_list_of_circles): new_segments = [] for Seg in final_list_of_segments: P1 = Seg.point_1 P2 = Seg.point_2 EPSSS = 10 p1x = P1.x p1y = P1.y p2x = P2.x p2y = P2.y P1_new = Point(p1x, p1y) P2_new = Point(p2x, p2y) k1 = False k2 = False for circle in final_list_of_circles: radius_ = circle.radius center_ = circle.center distt1 = Point.distance_between(P1, center_) if abs(distt1 - radius_) < EPSSS: P1_new = circle.project_point_seg(Seg, P1) k1 = True distt2 = Point.distance_between(P2, center_) if abs(distt2 - radius_) < EPSSS: P2_new = circle.project_point_seg(Seg, P2) k2 = True if k1 and k2: break new_segments.append(Segment(P1_new, P2_new)) return new_segments
def tangent(a1, a2, current, c1, c2): try: k = Curve.derivative(a1, a2, c1, c2) except ZeroDivisionError: return None else: b = current.y - k * current.x return Segment.from_line_and_point(k, b, current)
def generate_segment(plot_side): min_segment = plot_side / 10 point_1 = Point(uniform(0, plot_side), uniform(0, plot_side)) while True: point_2 = Point(uniform(0, plot_side), uniform(0, plot_side)) if Point.distance_between(point_1, point_2) > min_segment: break return Segment(point_1, point_2)
def get_p3(p1, p2): cross = oval.cross_segment(Segment(p1, p2)) w = WURF.last_point(cross[0], cross_point, cross[1], wurf) if not w: # print('getting wurf: D < 0') return None raise Exception('getting wurf: D < 0') return w.p3
class TestSegment(unittest.TestCase): def setUp(self): self.segment1 = Segment(Point((0.0, 1.0)), Point((2.0, 1.0))) self.segment2 = Segment(Point((2.0, 0.0)), Point((2.0, 2.0))) def test_intersection_on_border(self): self.assertTrue(self.segment1.intersection(self.segment2) is not None)
def test_create_segment(ws, canvas, cleanup): layer = Layer('M2', 'pin') s = Segment.from_start_end(Point(0, 1), Point(10, 1), 2, layer) canvas.append(s) rod, = canvas.draw() assert rod.valid assert segment_equal(s, rod.db)
def draw(self): # draw active polygon if self.active and self.points: for i in range(1, len(self.points)): draw_segment( Segment(self.points[i - 1], self.points[i]), color=arcade.color.ANDROID_GREEN )
def main(oval, subplot=None): if subplot: plt.subplot(subplot) oval.draw() points = Helper.find_conjugation_points(oval.points, Helper.calculate(oval.points)) cross_point = Segment.cross(Segment(points[0], points[2]), Segment(points[1], points[3])) print(cross_point) x, y = Helper.points_to_x_y(points + [cross_point]) # x, y = Helper.points_to_x_y(points) plt.scatter(x, y) curve = Helper.get_inner_curve(oval, cross_point, 2, 1) first = Curve.from_points(tuple(curve), step) x, y = Helper.points_to_x_y(curve) plt.scatter(x, y, [2]) curve = curve = Helper.get_inner_curve(oval, cross_point, 1.5, 1) second = Curve.from_points(tuple(curve), step) x, y = Helper.points_to_x_y(curve) plt.scatter(x, y, [2]) wurf_map = Helper.wurf_mapping(first, second, oval) result = [] for i in range(len(wurf_map)): nearest, dist = FLANN().nn( np.asarray([(item.x, item.y) for item in wurf_map if item != wurf_map[i]]), np.asarray([(item.x, item.y) for item in wurf_map if item == wurf_map[i]]), 1, algorithm="kmeans", ) # print(dist) if dist[0] < 0.01: result.append(wurf_map[i]) # else: # print('here') return result
def segments_error(predictx, answerx, max_penalty): predict = list(filter(lambda x: isinstance(x, Segment), predictx)) answer = list(filter(lambda x: isinstance(x, Segment), answerx)) res = abs(len(predict) - len(answer)) * max_penalty for p in predict: best = np.inf for a in answer: dist = Segment.difference(p, a) best = min(best, dist) res += min(best, max_penalty) for p in answer: best = np.inf for a in predict: dist = Segment.difference(p, a) best = min(best, dist) res += min(best, max_penalty) return res
def add_points(self, p1, p2): if (Segment(p1, p2).len > self.step and p1.parent is not None and p1.parent == p2.parent): x = (p1.x + p2.x) / 2 y = p1.parent.y(x) y = y[0] if abs(y[0] - p1.y) < abs(y[1] - p1.y) else y[1] point = Point(x, y, self) for p in self.add_points(p1, point): yield p yield point for p in self.add_points(point, p2): yield p
def visible_vertices(point: Point, points: Iterable[Point], segments: Dict[Point, List[Segment]]) -> Iterator[Point]: """ Yields points from given points that can be seen from given start point. """ # remove point from points points = filter(lambda x: x != point, points) # sort points first by angle and then by distance from point points = sorted(points, key=lambda x: (angle_to_xaxis(point, x), dist(point, x))) # create sorted list from segments that cross starting ray # list is sorted using ray that has to be updated ray = Segment(point, Point(point.x + 1, point.y)) status = SortedList( iterable=(seg for seg in set(chain(*segments.values())) if intersection( *ray, *seg, restriction_1='ray', restriction_2='segment') and point not in seg), key=status_key(lambda: ray)) # for each point (they are sorted by angle) for p in points: # update ray ray = Segment(point, p) # if p is visible yield it if status.bisect_left(p) == 0: yield p # remove segments from this point for seg in segments[p]: if orient(point, p, seg.p1 if seg.p2 == p else seg.p2) < 0: status.remove(seg) # add segments to this point for seg in segments[p]: if orient(point, p, seg.p1 if seg.p2 == p else seg.p2) > 0: status.add(seg)
def on_mouse_release(self, x: float, y: float, button: int, modifiers: int): if not self.active: return if button != arcade.MOUSE_BUTTON_LEFT: return if self.points: self.collection.segments.add(Segment(*self.points)) self.points = None else: point = self.snap_point(x, y) self.points = [point, point]
def min_p(points, prev=None, delta=1): r = [] if not prev: dists = [cache["{}-{}".format(p.x, p.y)] for p in points] else: dists = [ cache["{}-{}".format(p.x, p.y)] / Segment(p, prev).len for p in points ] m_v = min(dists) if m_v < delta: r.append(points[dists.index(m_v)]) return r
def last_point(p1, p2, p4, wurf_value): main = Segment(p1, p4) y = lambda x: main.k * x + main.b a = Segment(p1, p2) b_c = Segment(p2, p4) l = a.len / (((wurf_value * (a.len + b_c.len)) / b_c.len) - 1) l = l**2 ua = 1 + (main.k**2) ub = 2 * (main.k * main.b - p2.x - p2.y * main.k) uc = (p2.x**2) + (p2.y**2) + (main.b**2) - 2*p2.y*main.b - l D = (ub ** 2) - (4 * ua * uc) if D < 0: return None x1 = (-ub + D ** 0.5) / (2 * ua) x2 = (-ub - D ** 0.5) / (2 * ua) w1, w2 = WURF(p1, p2, Point(x1, y(x1)), p4), WURF(p1, p2, Point(x2, y(x2)), p4) result = w1 if ( (abs(w2.value - wurf_value) < abs(w1.value - wurf_value)) ): result = w2 return result
def set_points(self, points): if len(points) < 2: raise InvalidStreetException("Street must have atleast 2 points") self.points = [] for (x, y) in points: self.points.append(Vec(x, y)) self.segments = [] for i in range(len(self.points) - 1): a = self.points[i] b = self.points[i + 1] self.segments.append(Segment(a, b))
def test_create_group(ws, canvas, cleanup): r = Rect[0:0.1, 0.2:0.3, Layer('M1', 'drawing')] s = Segment.from_start_end(Point(1, 1), Point(2, 1), 0.1, Layer('M2', 'pin')) g = Group([r, s]) canvas.append(g) db, = canvas.draw() assert db.valid assert rect_equal(g.bbox, db.db) assert rect_equal(db.db.figs[0], r) assert segment_equal(db.db.figs[1], s)
def last_point_1(p1, p2, p4, wurf_value, delta=0.1**3): main = Segment(p1, p4) y = lambda x: main.k * x + main.b if p2.x > p4.x: delta *= -1 current_x = p2.x wurfs = [] while np.sign(delta)*current_x < p4.x: current_x += delta w = WURF(p1, p2, Point(current_x, y(current_x)), p4) # print(w.value) wurfs.append(w) tmp = [abs(item.value - wurf_value) for item in wurfs] return wurfs[tmp.index(min(tmp))]
def next_(P, sibling): if not P.pairs: return None # root case s, r = P.pairs[-1] P.shape_pool.add(s) P.resource_pool.add(r) _old = P.r2p[P.resources[r]] old_pathway = sibling[_old] old_segments = P.segments[_old] try: s, r = next(P.siblings[-1]) except StopIteration: return None # base case P.shape_pool.remove(s) P.resource_pool.remove(r) P.pairs[-1] = (s, r) shape_id, resource_id = P.shapes[s], P.resources[r] center = get_center(resource_id, P.s2shape[shape_id]) _new = P.latest_pathway_assignment = P.r2p[resource_id] new_pathway = sibling[_new] new_segments = P.segments[_new] if new_pathway is old_pathway: # Same pathway, overwrite. new_pathway[-1] = (shape_id, resource_id) assert new_segments is old_segments if new_segments: new_segments[-1].point2 = center else: new_segments.append(Segment(center, center)) else: # Different pathway, remove there and add here. # Remove old ... old_pathway.pop() if not old_segments: pass elif len(old_segments) == 1 and not (old_segments[0].point2 is old_segments[0].point1): old_segments[0].point2 = old_segments[0].point1 else: old_segments.pop() # Add new ... new_pathway.append((shape_id, resource_id)) add_point_to_segments(center, new_segments) return sibling
def load_figure_list(filepath): f = open(filepath, "r") res = [] for s in f.readlines(): words = s.split() nums = list(map(float, words[1:])) t = words[0] if t == 'segment': res.append( Segment(Point(nums[0], nums[1]), Point(nums[2], nums[3]))) elif t == 'circle': res.append(Circle(Point(nums[1], nums[2]), nums[0])) else: raise RuntimeError("Can't load figure named {}".format(t)) f.close() return res
def getBuildingSegments(building): """ Return list of segments in building contour @param building: ogr geometry reference for building contour """ nPoints = building.GetPointCount() segments = [] for i in range(1, nPoints): x1 = building.GetX(i - 1) y1 = building.GetY(i - 1) z1 = building.GetZ(i - 1) x2 = building.GetX(i) y2 = building.GetY(i) z2 = building.GetZ(i) P1 = np.array([x1, y1, z1]) P2 = np.array([x2, y2, z2]) segments.append(Segment(P1, P2)) return segments
class SegmentProjectionTest(unittest.TestCase): def setUp(self): self.s1 = Segment((0,0), (4,0)) self.s2 = Segment((0,0),(0,-5)) def test_dist_from_point(self): self.assertEqual(self.s1.dist_from_point((0,2)), 2) self.assertEqual(self.s1.dist_from_point((2,0)), 0) self.assertEqual(self.s1.dist_from_point((300,-5)), 5) self.assertEqual(self.s2.dist_from_point((0,2)), 0) self.assertEqual(self.s2.dist_from_point((2,0)), 2) self.assertEqual(self.s2.dist_from_point((-300,-5)), 300) def test_orthogonal_projection(self): self.assertEqual(self.s1.orthogonal_projection((0,2)), (0,0)) self.assertEqual(self.s1.orthogonal_projection((2,0)), (2,0)) self.assertEqual(self.s1.orthogonal_projection((-5,3)), (-5,0)) self.assertEqual(self.s2.orthogonal_projection((0,2)), (0,2)) self.assertEqual(self.s2.orthogonal_projection((2,0)), (0,0)) self.assertEqual(self.s2.orthogonal_projection((-5,3)), (0,3))
def visibility_graph(collection: Collection) -> Collection: """ Generates visibility graph from in O(n^2 log n). """ # create dict that maps point to segments that it belongs to segments = defaultdict(list) for seg in collection.all_segments: segments[seg.p1].append(seg) segments[seg.p2].append(seg) # output graph graph = Collection(points=collection.all_points) # for each point for point in graph.points: # for each point visible from point for visible_point in visible_vertices(point, graph.points, segments): # create edge in graph graph.segments.add(Segment(point, visible_point)) return graph
def plot_component(cls, polygons, used, start_ind): yield polygons[0][start_ind].x, polygons[0][start_ind].y, False prev_point = polygons[0][start_ind] cur_polygon = 0 next_point_ind = (start_ind + 1) % len(polygons[0]) finished = False used[start_ind] = True while True: next_point = polygons[cur_polygon][next_point_ind] intersection = None seg = Segment(prev_point, next_point) for other_point_ind in range(len(polygons[1 - cur_polygon])): other_next_point_ind = (other_point_ind + 1) % len( polygons[1 - cur_polygon]) other_seg = Segment( polygons[1 - cur_polygon][other_point_ind], polygons[1 - cur_polygon][other_next_point_ind]) if seg.does_intersect( other_seg) and not other_seg.contains(prev_point): intersection_point = seg.get_intersection_point(other_seg) if intersection is None or ( prev_point - intersection[0]).len2() > ( prev_point - intersection_point).len2(): intersection = (intersection_point, other_next_point_ind) if intersection is not None: prev_point = intersection[0] yield Point(*prev_point.as_tuple()) next_point_ind = intersection[1] cur_polygon = 1 - cur_polygon else: if cur_polygon == 0: used[next_point_ind] = True prev_point = polygons[cur_polygon][next_point_ind] yield Point(*prev_point.as_tuple()) next_point_ind = (next_point_ind + 1) % len( polygons[cur_polygon]) if next_point_ind == start_ind and cur_polygon == 0 and not finished: finished = True continue if finished: return
import >>> from geometry import Segment init >>> a = (0,0) >>> b = (4,0) >>> s = Segment(a,b) equal >>> s == (a,b) True access >>> s[0] == a True >>> s[1] == b True iter >>> tuple( p for p in s) == (a,b) True position d'un point >>> s.pos_point((2,0)) == 0 True >>> s.pos_point((2,2)) > 0 True >>> s.pos_point((2,-2)) < 0
def test_intersect3(self): s1 = Segment((2, 2), (0, 0)) s2 = Segment((-1, -1), (-3, -3)) self.assertFalse(s1.intersect(s2))
def setUp(self): self.segment1 = Segment(Point((0.0, 1.0)), Point((2.0, 1.0))) self.segment2 = Segment(Point((2.0, 0.0)), Point((2.0, 2.0)))
def test_intersect2(self): s1 = Segment((0,0), (4,0)) s2 = Segment((-1,-1),(5,0)) self.assertFalse(s1.intersect(s2))
def test_intersect1(self): s1 = Segment((0,0), (4,0)) s2 = Segment((-1,-1),(5,1)) self.assertTrue(s1.intersect(s2))
def setUp(self): self.s1 = Segment((0,0), (4,0)) self.s2 = Segment((0,0),(0,-5))
def funnel(p_depart, p_arrive, portal_edges): smooth_path = [p_depart] segDroit = Segment(p_depart, portal_edges[0][0]) segGauche = Segment(p_depart, portal_edges[0][1]) i_gauche = i_droit = i = 0 portal_edges.append((p_arrive,p_arrive)) while smooth_path[-1] != p_arrive: i += 1 if i >= len(portal_edges): smooth_path.append(p_arrive) break #print (smooth_path) #print(i, i_droit, i_gauche) #print(segDroit.b, segGauche.b) droit = portal_edges[i][0] gauche = portal_edges[i][1] #print(droit, gauche) if segGauche.pos_point(droit) > 0: # croise #print("cgauche") smooth_path.append(segGauche.b) i_gauche += 1 i = i_droit = i_gauche segDroit = Segment(smooth_path[-1], portal_edges[i][0]) segGauche = Segment(smooth_path[-1], portal_edges[i][1]) continue if segDroit.pos_point(gauche) < 0: # croise #print("cdroit") smooth_path.append(segDroit.b) i_droit += 1 i = i_gauche = i_droit segDroit = Segment(smooth_path[-1], portal_edges[i][0]) segGauche = Segment(smooth_path[-1], portal_edges[i][1]) continue if segGauche.pos_point(gauche) <= 0: #print("thingauche") segGauche.b = gauche i_gauche = i if gauche == p_arrive: smooth_path.append(p_arrive) break if segDroit.pos_point(droit) >= 0: #print("thindroit") segDroit.b = droit i_droit = i if droit == p_arrive: smooth_path.append(p_arrive) break return smooth_path
def setUp(self): self.a = (0,0) self.b = (4,0) self.s = Segment(self.a,self.b)