convexhull.py 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. # Author: mozman
  2. # Purpose: convex hull algorithm
  3. # Created: 28.02.2010
  4. # License: MIT License
  5. from typing import TYPE_CHECKING, Iterable, List
  6. from ezdxf.math.construct2d import left_of_line
  7. if TYPE_CHECKING:
  8. from ezdxf.eztypes import Vertex
  9. def convex_hull_2d(points: Iterable['Vertex'])->List['Vertex']:
  10. def _convexhull(hull):
  11. while len(hull) > 2:
  12. start_point, check_point, destination_point = hull[-3:] # the last three points
  13. if not left_of_line(check_point, start_point, destination_point): # curve not turns right
  14. del hull[-2] # remove the penultimate point
  15. else:
  16. break
  17. return hull
  18. points = sorted(set(points)) # remove duplicate points
  19. if len(points) < 3:
  20. raise ValueError("ConvexHull(): Less than 3 unique points given!")
  21. upper_hull = points[:2] # first two points
  22. for next_point in points[2:]:
  23. upper_hull.append(next_point)
  24. upper_hull = _convexhull(upper_hull)
  25. lower_hull = [points[-1], points[-2]] # last two points
  26. for next_point in reversed(points[:-2]):
  27. lower_hull.append(next_point)
  28. lower_hull = _convexhull(lower_hull)
  29. upper_hull.extend(lower_hull[1:-1])
  30. return upper_hull