GNOME Bugzilla – Bug 91191
The new intersector fails
Last modified: 2006-11-01 14:21:11 UTC
I'm using the latest CVS version which I think is marked 2.3.10 embedded in a python extension. The problem I'm having is numerical instability in intersecting thin horizontal strips and a triangle. In renderPM we use intersection to provide clipping path capabilities. To avoid possible problems of interpretation etc I made a small addition to testart.c and the output is shown below. The resultant SVP intersects have very different sizes when they should be similar. Using my debugger I trace this to different behaviour near the lines in art_svp_intersect.c if (y == left_seg->y0) { if (y != right_seg->y0) { #ifdef VERBOSE art_dprint ("art_svp_intersect_test_cross: intersection (%g, %g) matches former y0 of %lx, %lx\n", x, y, (unsigned long)left_seg, (unsigned long)right_seg); #endif in the 'bad' case y-right_seg->y0==7.10543e-015 in the ok case this is zero. This is clearly a numerical problem in that the original data was manipulated using transforms before we got to this condition, but surely a production library should not rely on exactness of floating point arithmetic to such an extent. ################################################################## # test function static void test_intersect(void) { ArtVpath vp0[] = { { ART_MOVETO, 10, 10}, { ART_LINETO, 60, 60}, { ART_LINETO, 110, 10}, { ART_LINETO, 10, 10}, { ART_END, 0, 0} }, vp1[]= { {ART_MOVETO, 110,34.999999999999993}, {ART_LINETO, 10,35}, {ART_LINETO, 10,36}, {ART_LINETO, 110,35.999999999999993}, {ART_LINETO, 110,34.999999999999993}, {ART_END, 0,0} }, vp2[]={ {ART_MOVETO, 110,35.999999999999993}, {ART_LINETO, 10,36}, {ART_LINETO, 10,37}, {ART_LINETO, 110,36.999999999999993}, {ART_LINETO, 110,35.999999999999993}, {ART_END, 0,0} }, *vp[] = {vp0, vp1, vp2}; ArtSVP *svp[3], *svpi; int i; for(i=0;i<3;i++){ svp[i]=art_svp_from_vpath(vp[i]); printf("vpath[%d]\n", i); print_vpath(vp[i]); printf("svp[%d]\n", i); print_svp(svp[i]); } for(i=1;i<3;i++){ svpi = art_svp_intersect(svp[i],svp[0]); printf("svp[%d] & svp[0]\n", i); print_svp(svpi); art_svp_free(svpi); } for(i=0;i<3;i++){ art_svp_free(svp[i]); } } ############################################################################### # test output vpath[0] 10 10 moveto 60 60 lineto 110 10 lineto 10 10 lineto stroke svp[0] segment 0, dir = down (10.000000, 10.000000) - (60.000000, 60.000000) (10, 10) (60, 60) segment 1, dir = up (10.000000, 10.000000) - (110.000000, 60.000000) (10, 10) (110, 10) (60, 60) vpath[1] 110 35 moveto 10 35 lineto 10 36 lineto 110 36 lineto 110 35 lineto stroke svp[1] segment 0, dir = down (10.000000, 35.000000) - (110.000000, 36.000000) (110, 35) (10, 35) (10, 36) segment 1, dir = up (10.000000, 35.000000) - (110.000000, 36.000000) (110, 35) (110, 36) (10, 36) vpath[2] 110 36 moveto 10 36 lineto 10 37 lineto 110 37 lineto 110 36 lineto stroke svp[2] segment 0, dir = down (10.000000, 36.000000) - (110.000000, 37.000000) (110, 36) (10, 36) (10, 37) segment 1, dir = up (10.000000, 36.000000) - (110.000000, 37.000000) (110, 36) (110, 37) (10, 37) svp[1] & svp[0] segment 0, dir = down (35.000000, 35.000000) - (85.000000, 35.000000) (85, 35) (35, 35) segment 1, dir = up (84.000000, 35.000000) - (85.000000, 36.000000) (85, 35) (84, 36) segment 2, dir = down (10.000000, 35.000000) - (35.000000, 36.000000) (35, 35) (10, 36) segment 3, dir = down (10.000000, 36.000000) - (84.000000, 36.000000) (10, 36) (84, 36) svp[2] & svp[0] segment 0, dir = down (10.000000, 36.000000) - (37.000000, 37.000000) (10, 36) (37, 37) segment 1, dir = up (10.000000, 36.000000) - (84.000000, 36.000000) (10, 36) (84, 36) segment 2, dir = up (84.000000, 36.000000) - (110.000000, 37.000000) (84, 36) (110, 37) segment 3, dir = up (37.000000, 37.000000) - (110.000000, 37.000000) (110, 37) (37, 37)
Created attachment 10582 [details] Where the bug data came from showing the real problem
Assuming that this is obsolete nowadays, please reopen if still happening. Thanks.