def test_lower_tangent_case3(self): point_list_a = [(0, 1), (0, -1), (1, 0), (-1, 0)] polygon_a = Polygon(point_list_a) point_list_b = [(4, 1), (3, 3), (5, 2), (4, 4)] polygon_b = Polygon(point_list_b) # After polygons are created mock_tangent_polygon_calculator = TangentPolygonCalculator() mock_tangent_polygon_calculator['a'] = polygon_a mock_tangent_polygon_calculator['b'] = polygon_b expected = [Point(0, -1), Point(4, 1)] self.assertCountEqual( expected, mock_tangent_polygon_calculator.lower_tangent('a', 'b'))
def test_upper_tangent_case2(self): point_list_a = [(3, 1), (4, 2), (3, 3), (2, 2)] polygon_a = Polygon(point_list_a) point_list_b = [(0, 1), (0, 2), (-1, 1), (-1, 2)] polygon_b = Polygon(point_list_b) # After polygons are created mock_tangent_polygon_calculator = TangentPolygonCalculator() mock_tangent_polygon_calculator['a'] = polygon_a mock_tangent_polygon_calculator['b'] = polygon_b expected = [Point(-1, 2), Point(3, 3)] self.assertCountEqual( expected, mock_tangent_polygon_calculator.upper_tangent('a', 'b'))
def convex_hull(self): # Find midpoint self.set_midpoint() left = [ point for point in self.point_list if point.x <= self.midpoint.x ] right = [ point for point in self.point_list if point.x > self.midpoint.x ] # Divide and conquer # Left and right convex hull can be recursively found # Here Jarvis Algorithm is directly applied left_convex_hull = ConvexHullJarvis(left).convex_hull() right_convex_hull = ConvexHullJarvis(right).convex_hull() # Find tangents by using tangent polygon calculator left_polygon = Polygon(left_convex_hull) right_polygon = Polygon(right_convex_hull) tangent_finder = TangentPolygonCalculator() tangent_finder[1] = left_polygon tangent_finder[2] = right_polygon left_upper_idx, right_upper_idx = tangent_finder.upper_tangent( 1, 2, idx=True) left_lower_idx, right_lower_idx = tangent_finder.lower_tangent( 1, 2, idx=True) # Need to do a collinear check else the convex hull will have extra collinear points left_upper_idx, right_upper_idx, left_lower_idx, right_lower_idx = self.collinear_check( left_polygon, right_polygon, left_upper_idx, right_upper_idx, left_lower_idx, right_lower_idx) # Merge res = [] left_idx = left_upper_idx # Turn counterclockwise to include the left outer convex hull points until the lower index is reached while left_idx != left_lower_idx: res.append(left_polygon.point_list[left_idx]) left_idx = (left_idx + 1) % len(left_polygon) res.append(left_polygon.point_list[left_idx]) right_idx = right_upper_idx # Turn clockwise to include the right outer convex hull points until the lower index is reached while right_idx != right_lower_idx: res.append(right_polygon.point_list[right_idx]) right_idx = (len(right_polygon) + right_idx - 1) % len(right_polygon) res.append(right_polygon.point_list[right_idx]) # Use polygon to sort sort_poly = Polygon(res) sort_poly.sort() return sort_poly.point_list