def test_sub(self): a = Vector(0, 0) b = Vector(-1, 0) c = a - b self.assertEqual(c.x, 1) self.assertEqual(c.y, 0)
def test_point_prependicular_to_end(self): p = Vector(10, 10) p1 = Vector(0, 0) p2 = Vector(0, 10) dist = path.pointlinedist(p, p1, p2) self.assertAlmostEqual(dist, 10)
def add_segment(self, p1: List[float], p2: List[float]): self.add_to_segment_queue( (Vector.from_array(p1), Vector.from_array(p2))) while len(self._segment_queue) > 0: _p1, _p2 = self._segment_queue.pop() self.add_edge(_p1, _p2)
def test_lerp(self): v1 = Vector(0, 10) v2 = Vector(0, -10) v3 = v1.lerp(v2, .5) self.assertAlmostEqual(v3.x, 0) self.assertAlmostEqual(v3.y, 0)
def test_point_on_line(self): p = Vector(10, 10) p1 = Vector(0, 0) p2 = Vector(20, 20) dist = path.pointlinedist(p, p1, p2) self.assertAlmostEqual(dist, 0)
def test_repr(self): p = Vector(0.0, 0.0) self.assertEqual(repr(p), "Vector(0.0, 0.0, 0.0)") p = Vector(-4.0, 3.0) self.assertEqual(repr(p), "Vector(-4.0, 3.0, 0.0)") p = Vector([-4.0, 3.0]) self.assertEqual(repr(p), "Vector(-4.0, 3.0, 0.0)")
def test_two_crossing(self): n = WireNetwork() n.add_segment([2, 2], [2, -2]) n.add_segment([4, 2], [4, -2]) n.add_segment([0, 0], [10, 0]) self.assertEqual(len(n.vertices), 8) self.assertEqual(len(n.edges), 7) for pair in zip( sorted(n.vertices), sorted([ Vector([2, -2]), Vector([2, 2]), Vector([4, -2]), Vector([4, 2]), Vector([0, 0]), Vector([10, 0]), Vector([2, 0]), Vector([4, 0]) ])): self.assertAlmostEqual(pair[0].dist(pair[1]), 0, msg=n.vertices) self.assertListEqual(n.edges, [ Edge(0, 6), Edge(1, 6), Edge(2, 7), Edge(3, 7), Edge(4, 6), Edge(6, 7), Edge(7, 5) ])
def test_init(self): p = Vector(0, 1) self.assertEqual(p.x, 0) self.assertEqual(p.y, 1) self.assertEqual(p.z, 0) self.assertTrue(np.array_equal(p.v, np.array([0, 1, 0])))
def test_flip(): line = Line.from_points(Vector(0, 0), Vector(0, 10)) assert line.origin.x == 0 assert line.origin.y == 0 assert line.direction.x == 0 assert line.direction.y == 1 line.flip() assert line.origin.x == 0 assert line.origin.y == 0 assert line.direction.x == 0 assert line.direction.y == -1
def line_intersection(a: Vector, b: Vector, c: Vector, d: Vector) -> Union[SegmentType, Vector, None]: if (not line_intersect_1d(a.x, b.x, c.x, d.x) or not line_intersect_1d(a.y, b.y, c.y, d.y)): return None m = Line(a, b) n = Line(c, d) zn = det(m.a, m.b, n.a, n.b) if (abs(zn) < EPSILON): if (abs(m.dist(c)) > EPSILON or abs(n.dist(a)) > EPSILON): return None if (b < a): a, b = b, a if (d < c): c, d = d, c left = max(a, c) right = min(b, d) return (left, right) else: x = -det(m.c, m.b, n.c, n.b) / zn y = -det(m.a, m.c, n.a, n.c) / zn if (betw(a.x, b.x, x) and betw(a.y, b.y, y) and betw(c.x, d.x, x) and betw(c.y, d.y, y)): return Vector([x, y]) return None
def test_split_segment_4(): segments = [ Segment([Vector(10, 10), Vector(0, 0)]) ] line = segments[0].line.clone() right = [] left = [] seg = [] for segment in segments: line.split_segment(segment, seg, seg, right, left) assert len(seg) == 1, seg assert len(right) == 0, right assert len(left) == 0, left
def test_properties(self): a = random.random() b = random.random() p = Vector(a, b) self.assertAlmostEqual(p.x, a) self.assertAlmostEqual(p.y, b)
def test_split_segment(): s = Segment([Vector(-10, 0), Vector(10, 0)]) line = Line.from_points(Vector(0, 0), Vector(0, 10)) coright = [] coleft = [] right = [] left = [] line.split_segment(s, coright, coleft, right, left) assert not coright assert not coleft assert right assert left assert len(right) == 1 assert len(left) == 1 assert right[0].vertices[0].x == -10.0 assert right[0].vertices[0].y == 0.0 assert right[0].vertices[1].x == 0.0 assert right[0].vertices[1].y == 0.0 assert left[0].vertices[0].x == 0.0 assert left[0].vertices[0].y == 0.0 assert left[0].vertices[1].x == 10.0 assert left[0].vertices[1].y == 0.0 s = Segment([Vector(5, 0), Vector(10, 0)]) line = Line.from_points(Vector(0, 0), Vector(0, 10)) coright = [] coleft = [] right = [] left = [] line.split_segment(s, coright, coleft, right, left) assert not coright assert not coleft assert not right assert left assert len(right) == 0 assert len(left) == 1
def test_intersection_reversal(self): i = line_intersection(Vector([-10, 10]), Vector([10, -10]), Vector([10, -10]), Vector([-10, 10])) self.assertIsNotNone(i) self.assertIsInstance(i, Tuple) if isinstance(i, Tuple): self.assertEqual(2, len(i)) i = line_intersection(Vector([10, 10]), Vector([-10, -10]), Vector([-10, -10]), Vector([10, 10])) self.assertIsNotNone(i) self.assertIsInstance(i, Tuple) if isinstance(i, Tuple): self.assertEqual(2, len(i))
def test_split_segments(): right = [] left = [] seg = [] segments = [ Segment([Vector(0, 0), Vector(0, 10)]), Segment([Vector(0, 10), Vector(10, 10)]), Segment([Vector(10, 10), Vector(0, 0)]), ] line = segments[0].line.clone() for segment in segments: line.split_segment(segment, seg, seg, right, left)
def test_reduce_points_off_line(self): points = [Vector(0, 0), Vector(10, 11), Vector(20, 20)] reduced = path.reduce_points(points, 2) self.assertEqual(len(reduced), 2)
def from_dict(self, data: NetworkData): if 'edges' in data: self._edges = [Edge(e[0], e[1]) for e in data['edges']] if 'vertices' in data: self._vertices = [Vector(v) for v in data['vertices']]
def test_lt(self): a = Vector(0, 0) b = Vector(-1, 0) self.assertTrue(b < a) self.assertFalse(a < b)
def add_edge(self, p1: Vector, p2: Vector): # Loop through all existing Vectors, checking # if new Vectors already exists close # Then return indices or add new if p2 < p1: p1, p2 = p2, p1 intersections: List[Tuple[Edge, Vector]] = [] new_edges: List[Any] = [] clear = True for other in self._edges: p3, p4 = self._vertices[other.a], self._vertices[other.b] if p4 < p3: p3, p4 = p4, p3 i = line_intersection(p1, p2, p3, p4) if i is not None: clear = False if isinstance(i, Vector): intersections.append((other, i)) elif len(i) == 2: new_edge_length = p1.dist(p2) prev_edge_length = p3.dist(p4) if i[0].dist(i[1]) < self.tolerance: # Most likely end-to-end intersections.append((other, i[0])) elif ((p1.dist(i[0]) < self.tolerance and p2.dist(i[1]) < self.tolerance) or (p3.dist(i[0]) < self.tolerance and p4.dist(i[1]) < self.tolerance)): # This is one contained inside the other if new_edge_length > prev_edge_length: p3 = self._vertices[other.a] p4 = self._vertices[other.b] if p4 < p3: p3, p4 = p4, p3 if p2 < p1: p1, p2 = p2, p1 self.add_to_segment_queue((p1, p3)) self.add_to_segment_queue((p4, p2)) else: # Overlap if p1.x < p3.x: self._edges.remove(other) self.add_to_segment_queue( (p1, self._vertices[other.a])) self.add_to_segment_queue( (self._vertices[other.a], p2)) self.add_to_segment_queue( (p2, self._vertices[other.b])) else: self._edges.remove(other) self.add_to_segment_queue( (self._vertices[other.a], p1)) self.add_to_segment_queue( (p1, self._vertices[other.b])) self.add_to_segment_queue( (self._vertices[other.b], p2)) else: raise Exception("WTF") if len(new_edges) > 0: for e in new_edges: self._add_edge(e) if len(intersections) > 0: p1_i = self.add_vertex(p1) p2_i = self.add_vertex(p2) if p1_i is None or p2_i is None: return edge = Edge(p1_i, p2_i) px_i: List[int] = [] for other, p0 in intersections: self._edges.remove(other) p3_i = other.a p4_i = other.b p0_i = self.add_vertex(p0) if p0_i is not None: px_i.append(p0_i) if p3_i != p0_i and p0_i is not None: self._add_edge(Edge(p3_i, p0_i)) if p4_i != p0_i and p0_i is not None: self._add_edge(Edge(p4_i, p0_i)) sort_key: Callable[[int], float] = lambda x: self._vertices[ x].dist(self.vertices[p1_i if p1_i is not None else x]) px_sorted = sorted(px_i, key=sort_key) prev_x = p1_i for px in px_sorted: if prev_x != px: self._add_edge(Edge(prev_x, px)) prev_x = px if prev_x != p2_i: self._add_edge(Edge(prev_x, p2_i)) if clear: p1_i = self.add_vertex(p1) p2_i = self.add_vertex(p2) if p2_i is None or p1_i is None: return edge = Edge(p1_i, p2_i) self._add_edge(edge)
def test_dist(self): a = Vector(0, 0) b = Vector(3, 4) self.assertEqual(a.dist(b), 5)
def test_repr(): line = Line(Vector(0.0, 5.0), Vector(1.0, 0.0)) assert repr(line) == "<Line(Vector(0.0, 5.0, 0.0), Vector(1.0, 0.0, 0.0)>"
def test_translate(self): v1 = Vector(0, 0) v1.translate(3, 5) self.assertEqual(v1.x, 3) self.assertEqual(v1.y, 5)
def test_clone(): line = Line(Vector(0, 0), Vector(1, 0)) line2 = line.clone() assert line == line2 assert line is not line2
def test_rotate(self): v1 = Vector(10, 0) v1.rotate(3.1415926) self.assertAlmostEqual(v1.x, -10, places=5) self.assertAlmostEqual(v1.y, 0, places=5)
def test_copy(self): v1 = Vector(0, 0) v2 = v1.copy() self.assertEqual(v2, v1) self.assertIsNot(v1, v2)
def test_intersection(self): i = line_intersection(Vector([10, 10]), Vector([-10, -10]), Vector([10, -10]), Vector([-10, 10])) self.assertIsNotNone(i) self.assertIsInstance(i, Vector) if isinstance(i, Vector): self.assertAlmostEqual(i.x, 0) self.assertAlmostEqual(i.y, 0) i = line_intersection(Vector([0, 2]), Vector( [4, 2]), Vector([2, 0]), Vector([2, 4])) if isinstance(i, Vector): self.assertAlmostEqual(i.x, 2) self.assertAlmostEqual(i.y, 2) i = line_intersection(Vector([0, 0]), Vector( [10, 10]), Vector([0, 2]), Vector([10, 12])) self.assertIsNone(i)