def test_point_creation(self): # Test rounding function actually being applied self.assertTrue(3.3333 == Point(3.33333, 1).x) self.assertTrue(3.3333 == Point(1, 3.3333333).y) self.assertTrue(10 == Point((10, 20, 30)).x) self.assertTrue(20 == Point((10, 20, 30)).y)
def test_segment_to_from_serializable(self): s = Segment.from_tuples( (1,2), (3, 4) ) data = s.to_serializable() self.assertEqual(data[0], Point(1, 2).to_serializable()) self.assertEqual(data[1], Point(3, 4).to_serializable()) s2 = Segment.from_serializable(data) self.assertEqual(s, s2)
def test_segment_equality(self): s = Segment.from_tuples( (1,2), (3, 4) ) s2 = Segment.from_coordinates( 1, 2, 3, 4 ) self.assertEqual(s, s2) self.assertEqual(s2, s) self.assertEqual(s, (Point(1, 2), Point(3, 4.0009)) ) self.assertNotEqual(s, (Point(1, 2), Point(3, 4.0011)) )
def test_point_reflect_y(self): p = Point(3, 4) p2 = p.reflect_y() self.assertEqual(p, Point(3, -4)) self.assertTrue(p is p2) p2 = p.reflected_y() self.assertEqual(p2, Point(3, 4)) self.assertTrue(p is not p2)
def test_point_traslation(self): p = Point(3, 4) p.traslate(10, 20) self.assertTrue(p.x == 13) self.assertTrue(p.y == 24) p.traslate(-33, -44) self.assertTrue(p.x == -20) self.assertTrue(p.y == -20)
def test_calculate_bounding_box(self): self.assertEqual(self.polygon1.bounding_box, (Point(0, 0), Point(10, 10))) self.assertEqual(self.polygon2.bounding_box, (Point(0, 0), Point(60, 60))) self.polygon1._calculate_bounding_box = MagicMock() self.polygon1.traslate(10, 10) self.polygon1.scale(4) self.assertEqual(self.polygon1._calculate_bounding_box.call_count, 0) self.polygon1.reflect_y() self.polygon1.rotate(90) self.assertEqual(self.polygon1._calculate_bounding_box.call_count, 2)
def test_text_equality(self): t = Text("ABC", Point(20, 20)) t2 = Text("ABC", Point(20, 20)) d1 = Text("ABc", Point(20, 20)) d2 = Text("ABC", Point(20, 21)) d3 = Text("ABC", Point(21, 20)) self.assertEqual(t, t2) self.assertNotEqual(t, d1) self.assertNotEqual(t, d2) self.assertNotEqual(t, d3)
def test_traslated_points(self): p = Point(3, 4) p2 = p.traslated(10, 20) self.assertTrue(p.x + 10 == p2.x) self.assertTrue(p.y + 20 == p2.y) self.assertTrue(p2 is not p) p2 = p.traslated(-33, -44) self.assertTrue(p.x - 33 == p2.x) self.assertTrue(p.y - 44 == p2.y)
def test_lines_intersection(self): s1 = Segment.from_coordinates(0, 0, 1, 1) s2 = Segment.from_coordinates(0, 0, -1, 1) s3 = Segment.from_coordinates(0, 0, 1, -1) s4 = Segment.from_coordinates(0, 0, -1, -1) self.assertEqual(s1._lines_intersection(s2), Point(0, 0)) self.assertTrue(s2._lines_intersection(s3) ) self.assertEqual(s3._lines_intersection(s4), Point(0, 0)) self.assertTrue(s4._lines_intersection(s1) ) # More parallel lines p1 = Segment.from_coordinates(-20, -20, 5, 5) p2 = Segment.from_coordinates(40, 40, 41, 41) self.assertTrue( s1._lines_intersection(p1) is True ) self.assertTrue( s1._lines_intersection(p2) is True ) self.assertTrue( p2._lines_intersection(p1) is True ) # specific intersections # y = mx e y = -mx + 2 devono interseccarsi in y = 1, x = 1 i1 = Segment.from_coordinates(0, 2, 2, 0) self.assertEqual( s1._lines_intersection(i1), Point(1, 1)) # vertical lines v1 = Segment.from_coordinates(0, 0, 0, 2) v2 = Segment.from_coordinates(2, 0, 2, 3) self.assertFalse( v1._lines_intersection(v2) ) self.assertEqual( v1._lines_intersection(s1), Point(0,0) ) self.assertEqual( v1._lines_intersection(s2), Point(0,0) ) self.assertEqual( v1._lines_intersection(s3), Point(0,0) ) self.assertEqual( v1._lines_intersection(s4), Point(0,0) ) self.assertEqual( v1._lines_intersection(s1), Point(0,0) ) self.assertEqual( v1._lines_intersection(i1), Point(0,2) ) self.assertEqual( i1._lines_intersection(v1), Point(0,2) ) def test_line_intersection( r1_x1, r1_y1, r1_x2, r1_y2, r2_x1, r2_y1, r2_x2, r2_y2, resx, resy ): s1 = Segment.from_coordinates(r1_x1, r1_y1, r1_x2, r1_y2) s2 = Segment.from_coordinates(r2_x1, r2_y1, r2_x2, r2_y2) self.assertEqual(s1._lines_intersection(s2), Point(resx, resy) ) # We love wolframalpha test_line_intersection(1, 2, 2, 1, 2, 0, 4, 3, 2.4, 0.6) test_line_intersection(-91,22, 60, -53, -90, 88, -17, -71, -50.4514, 1.85999) test_line_intersection(-74,-1, 78, -47, -3, 75, -76, -51, -51.0548, -7.94394) test_line_intersection(83,-25, 60, 57, 34, 47, -58, -38, 56.8765, 68.1359)
def test_associate_text_to_rooms(self): p2 = Polygon.from_absolute_coordinates([(12,0),(22,0),(22,10),(12,10)]) r2 = Room(p2) t1 = Text("Text room 1", Point(5,5)) t2 = Text("Text room 2", Point(15,8)) t3 = Text("Text outside",Point(11,5)) floor = Floor("Building 1", "Floor1",[self.room1, r2]) floor.associate_room_texts([t1,t2,t3]) self.assertEqual( len(self.room1.texts), 1 ) self.assertTrue( len(r2.texts) == 1 ) self.assertTrue( t1 in self.room1.texts ) self.assertTrue( t2 in r2.texts )
def test_line_intersection( r1_x1, r1_y1, r1_x2, r1_y2, r2_x1, r2_y1, r2_x2, r2_y2, resx, resy ): s1 = Segment.from_coordinates(r1_x1, r1_y1, r1_x2, r1_y2) s2 = Segment.from_coordinates(r2_x1, r2_y1, r2_x2, r2_y2) self.assertEqual(s1._lines_intersection(s2), Point(resx, resy) )
def test_text_cloning(self): t = Text("ABC", Point(20, 20)) t2 = t.clone() self.assertTrue(t is not t2) self.assertTrue(t.anchor_point == t2.anchor_point) self.assertTrue(t.text == t2.text)
def test_point_scaling(self): p = Point(10, 20) p1 = p.scale(.2) self.assertEqual(p.x, 2) self.assertEqual(p.y, 4) self.assertTrue(p1 is p) p.scale(2) self.assertEqual(p.x, 4) self.assertEqual(p.y, 8) p2 = p.scaled(2, 3) self.assertEqual(p2.x, 8) self.assertEqual(p2.y, 24) self.assertTrue(p2 is not p)
def test_polygon_creation(self): # Absolute coordinates self.assertEqual(self.polygon2.anchor_point, Point(-20, -30)) self.assertEqual( self.polygon2.points, [Point(0, 60), Point(20, 20), Point(40, 0), Point(60, 20)]) # Relative coordinates self.assertEqual(self.polygon1.anchor_point, Point(100, 200)) self.assertEqual( self.polygon1.points, [Point(0, 0), Point(10, 0), Point(10, 10), Point(0, 10)])
def test_point_rotation(self): p = Point(10, 20) p1 = p.rotate(90) self.assertEqual(p.x, -20) self.assertEqual(p.y, 10) self.assertTrue(p1 is p) p.rotate(90) self.assertEqual(p.x, -10) self.assertEqual(p.y, -20) p2 = p.rotated(-180) self.assertEqual(p2.x, 10) self.assertEqual(p2.y, 20) self.assertTrue(p2 is not p)
def test_simplify_close_points(self): p1 = Polygon.from_relative_coordinates(Point( 0, 0), [(-20, 30), (-20.35, 30.25), (0, -10), (-0.3, -10.36), (40, -10)]).simplify_close_points() self.assertEqual(p1.points, [(-20, 30), (0, -10), (40, -10)]) p2 = Polygon.from_relative_coordinates(Point( 0, 0), [(-20, 30), (-20.25, 30.15), (0, -10), (-0.13, -10.16), (15, 15), (-20, 30)]).simplify_close_points() self.assertEqual(p2.points, [(0, -10), (15, 15), (-20, 30), (0, -10)]) p3 = Polygon.from_relative_coordinates(Point( 0, 0), [(0, 0), (0, 0.49), (0, 0.495), (0, 0.396), (0, 0.9), (0, 1.3), (0, 1.41)]).simplify_close_points() self.assertEqual(p3.points, [(0, 0), (0, 0.9), (0, 1.41)])
def _extract_entities(self): self._rooms = [] self._texts = [] self._wall_lines = [] self._window_lines = [] for ent in self._grabber.entities: if self._is_valid_room(ent): points = [(p[0], -p[1]) for p in ent.points] polygon = Polygon.from_absolute_coordinates(points) polygon.ensure_is_closed(tollerance=0.8) polygon.simplify_close_points(tollerance=0.8) if polygon.is_self_crossing(): Logger.warning("Self crossing room is not valid: " + str(polygon)) continue self._rooms.append(Room(polygon)) elif self._is_valid_text(ent): self._texts.append( Text(ent.plain_text().strip(), Point(ent.insert[0], -ent.insert[1]))) elif self._is_valid_wall_line(ent): start = Point(ent.start[0], -ent.start[1]) end = Point(ent.end[0], -ent.end[1]) line = Segment(start, end) self._wall_lines.append(line) elif self._is_valid_wall_polyline(ent): points = [(p[0], -p[1]) for p in ent.points] polygon = Polygon.from_relative_coordinates((0, 0), points) polygon.ensure_is_closed(tollerance=1) polygon.simplify_close_points(tollerance=1) self._wall_lines.extend(polygon.as_segment_list()) elif self._is_valid_window_line(ent): start = Point(ent.start[0], -ent.start[1]) end = Point(ent.end[0], -ent.end[1]) line = Segment(start, end) self._window_lines.append(line)
def test_room_reflection(self): self.room1.reflect_y() self.assertEqual( self.room1.polygon.points, [Point(0, 0), Point(10, 0), Point(10, -10), Point(0, -10)]) self.polygon1.anchor_point.reflect_y = MagicMock() self.polygon1.reflect_y = MagicMock() for t in self.room1.texts: t.anchor_point.reflect_y = MagicMock() self.room1.reflect_y() self.polygon1.anchor_point.reflect_y.assert_called_once_with() self.polygon1.reflect_y.assert_called_once_with() for t in self.room1.texts: t.anchor_point.reflect_y.assert_called_once_with()
def setUp(self): # 10x10 square beginning on origin self.polygon1 = Polygon.from_absolute_coordinates([(0, 0), (10, 0), (10, 10), (0, 10)]) self.room1 = Room(self.polygon1, [ Text("1234", Point(3, 3)), Text("Super Cool", Point(4, 7)), Text("Corner Text!", Point(1, 10)) ]) # 10x10 diamond shape centered at origin self.polygon2 = Polygon.from_absolute_coordinates([(10, 0), (0, 10), (-10, 0), (0, -10)]) self.room2 = Room(self.polygon2) # L-shaped room self.polygon3 = Polygon.from_absolute_coordinates([(0, 0), (10, 0), (10, 5), (5, 5), (5, 10), (0, 10)]) self.room3 = Room(self.polygon3)
def test_associate_text_to_rooms2(self): p2 = Polygon.from_absolute_coordinates([(6,0),(12,0),(12,10),(11,10),(11,4),(6,4)]) r2 = Room(p2) t1_1 = Text("Text room 1",Point(2,2)) t1_2 = Text("Text room 1",Point(8,8)) t2_1 = Text("Text room 2",Point(7,2)) t2_2 = Text("Text room 2",Point(11,8)) t_none = Text("Text none",Point(5,12)) floor = Floor("Building 1", "Floor1",[ self.room1,r2]) floor.associate_room_texts([t1_1,t1_2,t2_1,t2_2,t_none]) self.assertTrue( len(self.room1.texts) == 2 ) self.assertTrue( len(r2.texts) == 2 ) self.assertTrue( t1_1 in self.room1.texts ) self.assertTrue( t1_2 in self.room1.texts ) self.assertTrue( t2_1 in r2.texts ) self.assertTrue( t2_2 in r2.texts ) self.assertTrue( t1_1 in self.room1.texts ) self.assertTrue( t_none not in self.room1.texts )
def test_polygon_translation(self): #[ (0, 0), (10, 0), (10, 10), (0, 10) ] anchor_point = self.polygon1.anchor_point.clone() self.polygon1.traslate(30, 40) self.assertTrue(Point(30, 40) in self.polygon1.points) self.polygon1.traslate(-230, 0) self.assertTrue(Point(40 - 230, 40) in self.polygon1.points) p2 = self.polygon1.traslate(0, -340) self.assertTrue( Point(10 + 30 - 230, 10 + 40 - 340) in self.polygon1.points) self.assertTrue(p2 is self.polygon1) # Immutable version p3 = self.polygon1.traslated(100, 100) self.assertTrue(Point(30 - 230, 10 + 40 - 340) in self.polygon1.points) self.assertFalse(p3 is self.polygon1) # After all translations, make sure the anchor point didn't change self.assertEqual(self.polygon1.anchor_point, anchor_point)
def test_contains_point(self): s = Segment.from_coordinates(0, 0, 0, 2) self.assertFalse(s.contains_point(1, 2)) self.assertFalse(s.contains_point(Point(1, 2))) self.assertFalse(s.contains_point(Point(3, 4))) self.assertFalse(s.contains_point(0, 2.001)) self.assertFalse(s.contains_point(0, -0.05)) self.assertTrue(s.contains_point(0, 1)) self.assertTrue(s.contains_point(0, 1.9)) self.assertTrue(s.contains_point(Point(0, 0.1))) s = Segment.from_coordinates(3, 0, 3, 2) self.assertFalse(s.contains_point(1, 2)) self.assertFalse(s.contains_point(Point(1, 2))) self.assertFalse(s.contains_point(3, 2.1)) self.assertFalse(s.contains_point(3, -0.1)) self.assertTrue(s.contains_point(3, 2)) self.assertTrue(s.contains_point(3, 0)) self.assertTrue(s.contains_point(3, 1)) s = Segment.from_coordinates(0, 0, 1, 1) self.assertFalse(s.contains_point(1, 2)) self.assertFalse(s.contains_point(Point(1, 3))) self.assertFalse(s.contains_point(Point(-3, 3))) self.assertTrue(s.contains_point(0.999, 0.999)) self.assertTrue(s.contains_point(0.001, 0.001)) self.assertTrue(s.contains_point(0.5, 0.5))
def test_polygon_reflection(self): p1 = self.polygon1.reflect_y() self.assertEqual(self.polygon1.anchor_point, Point(100, 200)) self.assertEqual( self.polygon1.points, [Point(0, 0), Point(10, 0), Point(10, -10), Point(0, -10)]) self.assertTrue(p1 is self.polygon1) p2 = self.polygon1.reflected_y() self.assertTrue(self.polygon1 is not p2) self.assertEqual( p2.points, [Point(0, 0), Point(10, 0), Point(10, 10), Point(0, 10)])
def test_room_encoding_and_decoding(self): r = Room([(1,2), (3, 4), (5, 6)]) self.room1.add_text(Text("Encoded cool text", Point([1,1]))) s1 = json.dumps(self.room1.to_serializable(), indent = 3) d1 = json.loads(s1) r2 = Room.from_serializable(d1) self.assertEqual(self.room1.polygon.points, r2.polygon.points) self.assertEqual(self.room1.texts, r2.texts) s2 = json.dumps(self.room1.to_serializable(), indent = 4) d2 = json.loads(s2) self.assertEqual(d1, d2)
def _extract_texts_from_cartiglio(self, grabber): """ Returns text from the layers who contain the cartiglio. Arguments: - grabber: instance of dxfgrabber result of the dxf parsing. Returns: a list of texts. Auxiliary method for inference from cartiglio """ def get_text(p): return self.sanitize_layer_name( (hasattr(p, "text") and p.text or p.plain_text()) or (hasattr(p, "rawtext") and p.rawtext) or "") return [ Text(get_text(p), Point(p.insert)) for p in grabber.entities if re.match("CARTIGLIO", p.layer, re.I) and ( p.dxftype == "MTEXT" or p.dxftype == "TEXT") ]
def test_segment_intersection(self): def test_segment_intersection( r1_x1, r1_y1, r1_x2, r1_y2, r2_x1, r2_y1, r2_x2, r2_y2, res ): s1 = Segment.from_coordinates(r1_x1, r1_y1, r1_x2, r1_y2) s2 = Segment.from_coordinates(r2_x1, r2_y1, r2_x2, r2_y2) self.assertEqual(s1.intersect_with(s2), res) self.assertEqual(s2.intersect_with(s1), res) test_segment_intersection(0, 0, 1, 1, 0, 0, -1, 1, Point(0, 0)) test_segment_intersection(0, 0, 1, 1, 1.1, 1.1, 2, 2, False) test_segment_intersection(0, 0, 1, 1, 0.9, 0.9, 2, 2, True) test_segment_intersection(0, 0, 1, 1, 1, 1, 2, -2, Point(1, 1)) test_segment_intersection(0, 0, 1, 1, 0.5, 0.5, 1.5, -1.5, Point(0.5, 0.5)) test_segment_intersection(0, 0, 1, 7, -1, 6, 1, 1, Point(0.3684, 2.578)) test_segment_intersection(0, 0, 1, 1, 0.5, 0.5, 1.5, -1.5, Point(0.5, 0.5)) test_segment_intersection(0, 0, 1, 1, 0.5, 0.5, 1.5, -1.5, Point(0.5, 0.5))
def test_is_point_on_same_line(self): s = Segment.from_coordinates(0, 0, 0, 2) self.assertFalse(s.is_point_on_same_line(1, 2)) self.assertFalse(s.is_point_on_same_line(Point(1, 2))) self.assertFalse(s.is_point_on_same_line(Point(3, 4))) self.assertTrue(s.is_point_on_same_line(0, 99)) self.assertTrue(s.is_point_on_same_line(0, -999)) self.assertTrue(s.is_point_on_same_line(Point(0, 4))) s = Segment.from_coordinates(3, 0, 3, 2) self.assertFalse(s.is_point_on_same_line(1, 2)) self.assertFalse(s.is_point_on_same_line(Point(1, 2))) self.assertTrue(s.is_point_on_same_line(3, 72)) self.assertTrue(s.is_point_on_same_line(3, 0)) s = Segment.from_coordinates(0, 0, 1, 1) self.assertFalse(s.is_point_on_same_line(1, 2)) self.assertFalse(s.is_point_on_same_line(Point(1, 3))) self.assertFalse(s.is_point_on_same_line(Point(-3, 3))) self.assertTrue(s.is_point_on_same_line(3, 3)) self.assertTrue(s.is_point_on_same_line(-3, -3)) self.assertTrue(s.is_point_on_same_line(0, 0))
def test_distance_to(self): p1 = Point(0, 0) self.assertEqual(p1.distance_to(0, 10), 10) self.assertEqual(p1.distance_to(p1.x, p1.y), 0)
def test_point_cloning(self): p = Point(3, 4) p2 = p.clone() self.assertTrue(p == p2) self.assertTrue(p is not p2)
def test_point_equality(self): p1 = Point(1.0, 1.0) self.assertEqual(p1, (1.00, 1.00)) self.assertEqual(p1, (1.0001, 1.0005)) self.assertNotEqual(p1, (1.0011, 1.0005)) self.assertNotEqual(p1, (1.0, 1.0011))
def test_point_serializable(self): p = Point([1, 2]) self.assertEqual(p.to_serializable(), {"x": p.x, "y": p.y}) p2 = Point.from_serializable(p.to_serializable()) self.assertEqual(p, p2)