// Finds the point with minimum x coordinate. private Point2D.Double findMinX(LinkedList points) { Point2D.Double minXPoint = null; LinkedListNode node = points.getHead(); while (node != null) { Point2D.Double point = node.getPoint(); if (minXPoint == null || point.getX() < minXPoint.getX()) { minXPoint = point; } node = node.getNext(); } return minXPoint; }
/** * Processes point set using Gift Wrapping algorithm and returns the points of the convex hull of * the input set. * * @param points set of points to run the algorithm on * @return convex hull points */ @Override public LinkedList useAlgorithm(LinkedList points) { if (points.getLength() < 4) { return points; } // Find the point with minimum x coordinate: O(n). Point2D.Double minXPoint = findMinX(points); LinkedList hullPoints = new LinkedList(); hullPoints.insert(minXPoint); Point2D.Double endPoint = minXPoint; Point2D.Double newEndPoint = null; // Do until hull closes, that is, for all hull points: O(h). // Inner loop checks every point of the set: O(n). // Run time is O(n*h). while (true) { // initial candidate for new end point LinkedListNode current = points.getHead(); newEndPoint = current.getPoint(); current = current.getNext(); double totalArea = 0.0; while (current != null) { Point2D.Double temp = current.getPoint(); // ignore if temp is the current end point if (!temp.equals(endPoint)) { double triangleArea = triangleArea(endPoint, newEndPoint, temp); // If temp is left of line from endpoint to candidate // (area positive), update candidate. totalArea += triangleArea; if (triangleArea >= 0) { newEndPoint = temp; } if (totalArea == 0.0 && current.getNext() == null) { // all collinear so return all return points; } } current = current.getNext(); } // if the new end point candidate is the same as the starting point // hull is closed and we can exit the loop if (newEndPoint.equals(minXPoint)) { break; } // Add to hull points and update end point. hullPoints.insert(newEndPoint); endPoint = newEndPoint; } return hullPoints; }