static ArtSVP * art_svp_merge_perturbed (const ArtSVP *svp1, const ArtSVP *svp2) { ArtVpath *vpath1, *vpath2; ArtVpath *vpath1_p, *vpath2_p; ArtSVP *svp1_p, *svp2_p; ArtSVP *svp_new; vpath1 = art_vpath_from_svp (svp1); vpath1_p = art_vpath_perturb (vpath1); art_free (vpath1); svp1_p = art_svp_from_vpath (vpath1_p); art_free (vpath1_p); vpath2 = art_vpath_from_svp (svp2); vpath2_p = art_vpath_perturb (vpath2); art_free (vpath2); svp2_p = art_svp_from_vpath (vpath2_p); art_free (vpath2_p); svp_new = art_svp_merge (svp1_p, svp2_p); #ifdef VERBOSE print_ps_svp (svp1_p); print_ps_svp (svp2_p); print_ps_svp (svp_new); #endif art_free (svp1_p); art_free (svp2_p); return svp_new; }
ArtSVP * art_svp_minus (const ArtSVP *svp1, const ArtSVP *svp2) { ArtSVP *svp2_mod; ArtSVP *svp3, *svp_new; ArtSvpWriter *swr; int i; svp2_mod = (ArtSVP *) svp2; /* get rid of the const for a while */ /* First invert svp2 to "turn it inside out" */ for (i = 0; i < svp2_mod->n_segs; i++) svp2_mod->segs[i].dir = !svp2_mod->segs[i].dir; svp3 = art_svp_merge (svp1, svp2_mod); swr = art_svp_writer_rewind_new (ART_WIND_RULE_POSITIVE); art_svp_intersector (svp3, swr); svp_new = art_svp_writer_rewind_reap (swr); art_free (svp3); /* shallow free because svp3 contains shared segments */ /* Flip svp2 back to its original state */ for (i = 0; i < svp2_mod->n_segs; i++) svp2_mod->segs[i].dir = !svp2_mod->segs[i].dir; return svp_new; }
/** * art_svp_intersect: Compute the intersection of two sorted vector paths. * @svp1: One sorted vector path. * @svp2: The other sorted vector path. * * Computes the intersection of the two argument svp's. Given two * svp's with winding numbers of 0 and 1 everywhere, the resulting * winding number will be 1 where both of the argument svp's has a * winding number 1, 0 otherwise. The result is newly allocated. * * Currently, this routine has accuracy problems pending the * implementation of the new intersector. * * Return value: The intersection of @svp1 and @svp2. **/ ArtSVP * art_svp_intersect (const ArtSVP *svp1, const ArtSVP *svp2) { #ifdef ART_USE_NEW_INTERSECTOR ArtSVP *svp3, *svp_new; ArtSvpWriter *swr; #ifdef ROBIN_DEBUG dump_svp("art_svp_intersect svp1", svp1); dump_svp("art_svp_intersect svp2", svp2); #endif svp3 = art_svp_merge (svp1, svp2); swr = art_svp_writer_rewind_new (ART_WIND_RULE_INTERSECT); art_svp_intersector (svp3, swr); svp_new = art_svp_writer_rewind_reap (swr); art_free (svp3); /* shallow free because svp3 contains shared segments */ #ifdef ROBIN_DEBUG dump_svp("art_svp_intersect svp_new", svp_new); #endif return svp_new; #else ArtSVP *svp3, *svp4, *svp_new; svp3 = art_svp_merge_perturbed (svp1, svp2); svp4 = art_svp_uncross (svp3); art_svp_free (svp3); svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_INTERSECT); art_svp_free (svp4); return svp_new; #endif }
/** * art_svp_diff: Compute the symmetric difference of two sorted vector paths. * @svp1: One sorted vector path. * @svp2: The other sorted vector path. * * Computes the symmetric of the two argument svp's. Given two svp's * with winding numbers of 0 and 1 everywhere, the resulting winding * number will be 1 where either, but not both, of the argument svp's * has a winding number 1, 0 otherwise. The result is newly allocated. * * Currently, this routine has accuracy problems pending the * implementation of the new intersector. * * Return value: The symmetric difference of @svp1 and @svp2. **/ ArtSVP * art_svp_diff (const ArtSVP *svp1, const ArtSVP *svp2) { #ifdef ART_USE_NEW_INTERSECTOR ArtSVP *svp3, *svp_new; ArtSvpWriter *swr; svp3 = art_svp_merge (svp1, svp2); swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN); art_svp_intersector (svp3, swr); svp_new = art_svp_writer_rewind_reap (swr); art_free (svp3); /* shallow free because svp3 contains shared segments */ return svp_new; #else ArtSVP *svp3, *svp4, *svp_new; svp3 = art_svp_merge_perturbed (svp1, svp2); svp4 = art_svp_uncross (svp3); art_svp_free (svp3); svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_ODDEVEN); art_svp_free (svp4); return svp_new; #endif }
gfxpoly_t* gfxpoly_intersect(gfxpoly_t*poly1, gfxpoly_t*poly2) { ArtSvpWriter *swr; static int counter = 0; ArtSVP* svp1 = (ArtSVP*)poly1; ArtSVP* svp2 = (ArtSVP*)poly2; msg("<verbose> Intersecting two polygons of %d and %d segments", svp1->n_segs, svp2->n_segs); #ifdef DEBUG char filename[80]; sprintf(filename, "isvp%d_src1.ps", counter); write_svp_postscript(filename, svp1); sprintf(filename, "isvp%d_src2.ps", counter); write_svp_postscript(filename, svp2); #endif ArtSVP* svp3 = art_svp_merge (svp1, svp2); #ifdef DEBUG sprintf(filename, "isvp%d_src.ps", counter); write_svp_postscript(filename, svp3); #endif //write_svp_postscript("svp.ps", svp3); ArtSVP*svp_new = run_intersector(svp3, ART_WIND_RULE_INTERSECT); art_free (svp3); /* shallow free because svp3 contains shared segments */ #ifdef DEBUG sprintf(filename, "isvp%d.ps", counter); write_svp_postscript(filename, svp_new); #endif counter++; //write_svp_postscript("svp_new.ps", svp_new); return (gfxpoly_t*)svp_new; }