diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-05-07 15:31:40 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-05-07 15:31:40 +0000 |
commit | 2db7fe7d3b7ee875e1099a22f0af17520696f5d7 (patch) | |
tree | 81988bda1bd4af551230aa03966589f97ebcadbe /tests/PathOpsCubicLineIntersectionTest.cpp | |
parent | 2d91efffdb57646a495de5bf859ff281ef86dd12 (diff) |
When solving the cubic line intersection directly fails, use binary search as a fallback.
The cubic line intersection math empirically works 99.99% of the time (fails 3100 out of 1B random tests) but when it fails, an intersection may be missed altogether.
The binary search is may not find a solution if the cubic line failed to find any solutions at all, but so far that case hasn't arisen.
BUG=skia:2504
TBR=reed@google.com
Author: caryclark@google.com
Review URL: https://codereview.chromium.org/266063003
git-svn-id: http://skia.googlecode.com/svn/trunk@14614 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tests/PathOpsCubicLineIntersectionTest.cpp')
-rw-r--r-- | tests/PathOpsCubicLineIntersectionTest.cpp | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/tests/PathOpsCubicLineIntersectionTest.cpp b/tests/PathOpsCubicLineIntersectionTest.cpp index 1a2e188589..234a53805f 100644 --- a/tests/PathOpsCubicLineIntersectionTest.cpp +++ b/tests/PathOpsCubicLineIntersectionTest.cpp @@ -49,6 +49,13 @@ static void testFail(skiatest::Reporter* reporter, int iIndex) { } static lineCubic lineCubicTests[] = { + {{{{-634.60540771484375, -481.262939453125}, {266.2696533203125, -752.70867919921875}, + {-751.8370361328125, -317.37921142578125}, {-969.7427978515625, 824.7255859375}}}, + {{{-287.9506133720805678, -557.1376476615772617}, + {-285.9506133720805678, -557.1376476615772617}}}}, + + {{{{36.7184372,0.888650894}, {36.7184372,0.888650894}, {35.1233864,0.554015458}, + {34.5114098,-0.115255356}}}, {{{35.4531212,0}, {31.9375,0}}}}, {{{{421, 378}, {421, 380.209137f}, {418.761414f, 382}, {416, 382}}}, {{{320, 378}, {421, 378.000031f}}}}, @@ -83,6 +90,32 @@ static lineCubic lineCubicTests[] = { static const size_t lineCubicTests_count = SK_ARRAY_COUNT(lineCubicTests); +static int doIntersect(SkIntersections& intersections, const SkDCubic& cubic, const SkDLine& line) { + int result; + bool flipped = false; + if (line[0].fX == line[1].fX) { + double top = line[0].fY; + double bottom = line[1].fY; + flipped = top > bottom; + if (flipped) { + SkTSwap<double>(top, bottom); + } + result = intersections.vertical(cubic, top, bottom, line[0].fX, flipped); + } else if (line[0].fY == line[1].fY) { + double left = line[0].fX; + double right = line[1].fX; + flipped = left > right; + if (flipped) { + SkTSwap<double>(left, right); + } + result = intersections.horizontal(cubic, left, right, line[0].fY, flipped); + } else { + intersections.intersect(cubic, line); + result = intersections.used(); + } + return result; +} + static void testOne(skiatest::Reporter* reporter, int iIndex) { const SkDCubic& cubic = lineCubicTests[iIndex].cubic; SkASSERT(ValidCubic(cubic)); @@ -102,7 +135,7 @@ static void testOne(skiatest::Reporter* reporter, int iIndex) { } if (order1 == 4 && order2 == 2) { SkIntersections i; - int roots = i.intersect(cubic, line); + int roots = doIntersect(i, cubic, line); for (int pt = 0; pt < roots; ++pt) { double tt1 = i[0][pt]; SkDPoint xy1 = cubic.ptAtT(tt1); |