_geometry.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. __all__ = ['polygon_clip', 'polygon_area']
  2. import numpy as np
  3. from .version_requirements import require
  4. @require("matplotlib", ">=3.3")
  5. def polygon_clip(rp, cp, r0, c0, r1, c1):
  6. """Clip a polygon to the given bounding box.
  7. Parameters
  8. ----------
  9. rp, cp : (K,) ndarray of double
  10. Row and column coordinates of the polygon.
  11. (r0, c0), (r1, c1) : double
  12. Top-left and bottom-right coordinates of the bounding box.
  13. Returns
  14. -------
  15. r_clipped, c_clipped : (L,) ndarray of double
  16. Coordinates of clipped polygon.
  17. Notes
  18. -----
  19. This makes use of Sutherland-Hodgman clipping as implemented in
  20. AGG 2.4 and exposed in Matplotlib.
  21. """
  22. from matplotlib import path, transforms
  23. poly = path.Path(np.vstack((rp, cp)).T, closed=True)
  24. clip_rect = transforms.Bbox([[r0, c0], [r1, c1]])
  25. poly_clipped = poly.clip_to_bbox(clip_rect).to_polygons()[0]
  26. return poly_clipped[:, 0], poly_clipped[:, 1]
  27. def polygon_area(pr, pc):
  28. """Compute the area of a polygon.
  29. Parameters
  30. ----------
  31. pr, pc : (K,) array of float
  32. Polygon row and column coordinates.
  33. Returns
  34. -------
  35. a : float
  36. Area of the polygon.
  37. """
  38. pr = np.asarray(pr)
  39. pc = np.asarray(pc)
  40. return 0.5 * np.abs(np.sum((pc[:-1] * pr[1:]) - (pc[1:] * pr[:-1])))