@@ -36,13 +36,15 @@ class _path_module : public Py::ExtensionModule<_path_module>
3636 add_varargs_method (" point_in_path_collection" , &_path_module::point_in_path_collection,
3737 " point_in_path_collection(x, y, r, trans, paths, transforms, offsets, offsetTrans, filled)" );
3838 add_varargs_method (" path_in_path" , &_path_module::path_in_path,
39- " point_in_path_collection (a, atrans, b, btrans)" );
39+ " path_in_path (a, atrans, b, btrans)" );
4040 add_varargs_method (" clip_path_to_rect" , &_path_module::clip_path_to_rect,
4141 " clip_path_to_rect(path, bbox, inside)" );
4242 add_varargs_method (" affine_transform" , &_path_module::affine_transform,
4343 " affine_transform(vertices, transform)" );
4444 add_varargs_method (" count_bboxes_overlapping_bbox" , &_path_module::count_bboxes_overlapping_bbox,
4545 " count_bboxes_overlapping_bbox(bbox, bboxes)" );
46+ add_varargs_method (" path_intersects_path" , &_path_module::path_intersects_path,
47+ " path_intersects_path(p1, p2)" );
4648
4749 initialize (" Helper functions for paths" );
4850 }
@@ -60,6 +62,7 @@ class _path_module : public Py::ExtensionModule<_path_module>
6062 Py::Object clip_path_to_rect (const Py::Tuple& args);
6163 Py::Object affine_transform (const Py::Tuple& args);
6264 Py::Object count_bboxes_overlapping_bbox (const Py::Tuple& args);
65+ Py::Object path_intersects_path (const Py::Tuple& args);
6366};
6467
6568//
@@ -673,7 +676,8 @@ Py::Object _path_module::affine_transform(const Py::Tuple& args) {
673676
674677 transform = (PyArrayObject*) PyArray_FromObject
675678 (transform_obj.ptr (), PyArray_DOUBLE, 2 , 2 );
676- if (!transform || PyArray_NDIM (transform) != 2 || PyArray_DIM (transform, 0 ) != 3 || PyArray_DIM (transform, 1 ) != 3 )
679+ if (!transform || PyArray_NDIM (transform) != 2 ||
680+ PyArray_DIM (transform, 0 ) != 3 || PyArray_DIM (transform, 1 ) != 3 )
677681 throw Py::ValueError (" Invalid transform." );
678682
679683 double a, b, c, d, e, f;
@@ -783,6 +787,70 @@ Py::Object _path_module::count_bboxes_overlapping_bbox(const Py::Tuple& args) {
783787 return Py::Int (count);
784788}
785789
790+ bool segments_intersect (const double & x1, const double &y1,
791+ const double & x2, const double &y2,
792+ const double & x3, const double &y3,
793+ const double & x4, const double &y4) {
794+ double den = ((y4-y3) * (x2-x1)) - ((x4-x3)*(y2-y1));
795+ if (den == 0.0 )
796+ return false ;
797+
798+ double n1 = ((x4-x3) * (y1-y3)) - ((y4-y3)*(x1-x3));
799+ double n2 = ((x2-x1) * (y1-y3)) - ((y2-y1)*(x1-x3));
800+
801+ double u1 = n1/den;
802+ double u2 = n2/den;
803+
804+ return (u1 >= 0.0 && u1 <= 1.0 &&
805+ u2 >= 0.0 && u2 <= 1.0 );
806+ }
807+
808+ bool path_intersects_path (PathIterator& p1, PathIterator& p2) {
809+ typedef agg::conv_curve<PathIterator> curve_t ;
810+
811+ if (p1.total_vertices () < 2 || p2.total_vertices () < 2 )
812+ return false ;
813+
814+ curve_t c1 (p1);
815+ curve_t c2 (p2);
816+
817+ double x11, y11, x12, y12;
818+ double x21, y21, x22, y22;
819+
820+ c1.vertex (&x11, &y11);
821+ while (c1.vertex (&x12, &y12) != agg::path_cmd_stop) {
822+ c2.rewind (0 );
823+ c2.vertex (&x21, &y21);
824+ while (c2.vertex (&x22, &y22) != agg::path_cmd_stop) {
825+ if (segments_intersect (x11, y11, x12, y12, x21, y21, x22, y22))
826+ return true ;
827+ x21 = x22; y21 = y22;
828+ }
829+ x11 = x12; y11 = y12;
830+ }
831+
832+ return false ;
833+ }
834+
835+ Py::Object _path_module::path_intersects_path (const Py::Tuple& args) {
836+ args.verify_length (2 );
837+
838+ PathIterator p1 (args[0 ]);
839+ PathIterator p2 (args[1 ]);
840+
841+ bool intersects = ::path_intersects_path (p1, p2);
842+ if (!intersects) {
843+ intersects = ::path_in_path (p1, agg::trans_affine (), p2, agg::trans_affine ());
844+ if (!intersects) {
845+ intersects = ::path_in_path (p2, agg::trans_affine (), p1, agg::trans_affine ());
846+ if (!intersects) {
847+ return Py::Int (0 );
848+ }
849+ }
850+ }
851+ return Py::Int (1 );
852+ }
853+
786854extern " C"
787855DL_EXPORT (void )
788856 init_path(void )
0 commit comments