Esempio n. 1
0
    def find_hull(self, points):
        # Get the length of the list of points
        num_points = len(points)

        # Base case
        # If there is only 1 point, make a node for that point, make a hull using that node, and return the hull
        if num_points == 1:
            node = Node(points[0], None, None)
            node.next_node = node
            node.previous_node = node

            hull = Hull(node, node)

            return hull

        # Otherwise, if there is more than 1 point, split the list of points in half and find hulls for the left half
        # and the right half.  Once both hulls have been found, merge them
        # The time complexity is O(nlog(n)) because the points are split in half at each iteration, so there are log(n)
        # recursive calls, and merge_hulls is called at each recursive level, which runs in O(n) time.  So the
        # complexity is O(n) * O(log(n)), or O(nlog(n))
        # The space complexity is also O(nlog(n)), since there are log(n) recursive calls, and merge_hulls is called at
        # each recursive level, which has a space complexity of O(n).  So the complexity is O(n) * O(log(n)), or
        # O(nlog(n))
        else:
            mid = num_points // 2

            left_hull = self.find_hull(points[:mid])
            right_hull = self.find_hull(points[mid:])

            hull = self.merge_hulls(left_hull, right_hull)

            return hull
Esempio n. 2
0
    def merge_hulls(self, left_hull, right_hull):
        # Find the upper and lower tangents (the tangents are tuples containing the 2 nodes the tangent goes through)
        upper_tangent = self.find_upper_tangent(left_hull.right_node,
                                                right_hull.left_node)
        lower_tangent = self.find_lower_tangent(left_hull.right_node,
                                                right_hull.left_node)

        # Set the upper tangent's left node's next node to the upper tangent's right node.  Then set the upper tangent's
        # right node's previous node to the upper tangent's left node
        upper_tangent[0].next_node = upper_tangent[1]
        upper_tangent[1].previous_node = upper_tangent[0]

        # Set the lower tangent's right node's next node to the lower tangent's left node.  Then set the lower tangent's
        # left node's previous node to the lower tangent's right node
        lower_tangent[1].next_node = lower_tangent[0]
        lower_tangent[0].previous_node = lower_tangent[1]

        # Once the proper node changes have been made, any other unimportant nodes will be garbage collected
        # We can now merge the hulls by creating a new hull that uses the left hull's left node and the right hull's
        # right node
        merged_hull = Hull(left_hull.left_node, right_hull.right_node)

        # Return the merged hull
        return merged_hull