@@ -872,6 +872,66 @@ bool path_intersects_path(PathIterator1 &p1, PathIterator2 &p2)
872872 return false ;
873873}
874874
875+ // returns whether the segment from (x1,y1) to (x2,y2)
876+ // intersects the rectangle centered at (cx,cy) with size (w,h)
877+ // see doc/segment_intersects_rectangle.svg for a more detailed explanation
878+ inline bool segment_intersects_rectangle (double x1, double y1,
879+ double x2, double y2,
880+ double cx, double cy,
881+ double w, double h)
882+ {
883+ return fabs (x1 + x2 - 2.0 * cx) < fabs (x1 - x2) + w &&
884+ fabs (y1 + y2 - 2.0 * cy) < fabs (y1 - y2) + h &&
885+ 2.0 * fabs ((x1 - cx) * (y1 - y2) - (y1 - cy) * (x1 - x2)) <
886+ w * fabs (y1 - y2) + h * fabs (x1 - x2);
887+ }
888+
889+ template <class PathIterator >
890+ bool path_intersects_rectangle (PathIterator &path,
891+ double rect_x1, double rect_y1,
892+ double rect_x2, double rect_y2,
893+ bool filled)
894+ {
895+ typedef PathNanRemover<py::PathIterator> no_nans_t ;
896+ typedef agg::conv_curve<no_nans_t > curve_t ;
897+
898+ if (path.total_vertices () == 0 ) {
899+ return false ;
900+ }
901+
902+ no_nans_t no_nans (path, true , path.has_curves ());
903+ curve_t curve (no_nans);
904+
905+ double cx = (rect_x1 + rect_x2) * 0.5 , cy = (rect_y1 + rect_y2) * 0.5 ;
906+ double w = fabs (rect_x1 - rect_x2), h = fabs (rect_y1 - rect_y2);
907+ double xmin = std::min (rect_x1, rect_x2), xmax = std::max (rect_x1, rect_x2);
908+ double ymin = std::min (rect_x1, rect_x2), ymax = std::max (rect_x1, rect_x2);
909+
910+ double x1, y1, x2, y2;
911+
912+ curve.vertex (&x1, &y1);
913+ if (2.0 * fabs (x1 - cx) <= w && 2.0 * fabs (y1 - cy) <= h) {
914+ return true ;
915+ }
916+
917+ while (curve.vertex (&x2, &y2) != agg::path_cmd_stop) {
918+ if (segment_intersects_rectangle (x1, y1, x2, y2, cx, cy, w, h)) {
919+ return true ;
920+ }
921+ x1 = x2;
922+ y1 = y2;
923+ }
924+
925+ if (filled) {
926+ agg::trans_affine trans;
927+ if (point_in_path (cx, cy, 0.0 , path, trans)) {
928+ return true ;
929+ }
930+ }
931+
932+ return false ;
933+ }
934+
875935template <class PathIterator >
876936void convert_path_to_polygons (PathIterator &path,
877937 agg::trans_affine &trans,
0 commit comments