Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: src/pathops/SkPathOpsCubic.cpp

Issue 266063003: cubicline intersection binary search (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: typing cleanup Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pathops/SkPathOpsCubic.h ('k') | src/pathops/SkPathOpsDebug.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 #include "SkLineParameters.h" 7 #include "SkLineParameters.h"
8 #include "SkPathOpsCubic.h" 8 #include "SkPathOpsCubic.h"
9 #include "SkPathOpsLine.h" 9 #include "SkPathOpsLine.h"
10 #include "SkPathOpsQuad.h" 10 #include "SkPathOpsQuad.h"
11 #include "SkPathOpsRect.h" 11 #include "SkPathOpsRect.h"
12 #include "SkTSort.h"
12 13
13 const int SkDCubic::gPrecisionUnit = 256; // FIXME: test different values in te st framework 14 const int SkDCubic::gPrecisionUnit = 256; // FIXME: test different values in te st framework
14 15
16 // give up when changing t no longer moves point
17 // also, copy point rather than recompute it when it does change
18 double SkDCubic::binarySearch(double min, double max, double axisIntercept,
19 SearchAxis xAxis) const {
20 double t = (min + max) / 2;
21 double step = (t - min) / 2;
22 SkDPoint cubicAtT = ptAtT(t);
23 double calcPos = (&cubicAtT.fX)[xAxis];
24 double calcDist = calcPos - axisIntercept;
25 do {
26 double priorT = t - step;
27 SkASSERT(priorT >= min);
28 SkDPoint lessPt = ptAtT(priorT);
29 if (approximately_equal(lessPt.fX, cubicAtT.fX)
30 && approximately_equal(lessPt.fY, cubicAtT.fY)) {
31 return -1; // binary search found no point at this axis intercept
32 }
33 double lessDist = (&lessPt.fX)[xAxis] - axisIntercept;
34 #if DEBUG_CUBIC_BINARY_SEARCH
35 SkDebugf("t=%1.9g calc=%1.9g dist=%1.9g step=%1.9g less=%1.9g\n", t, cal cPos, calcDist,
36 step, lessDist);
37 #endif
38 double lastStep = step;
39 step /= 2;
40 if (calcDist > 0 ? calcDist > lessDist : calcDist < lessDist) {
41 t = priorT;
42 } else {
43 double nextT = t + lastStep;
44 SkASSERT(nextT <= max);
45 SkDPoint morePt = ptAtT(nextT);
46 if (approximately_equal(morePt.fX, cubicAtT.fX)
47 && approximately_equal(morePt.fY, cubicAtT.fY)) {
48 return -1; // binary search found no point at this axis interce pt
49 }
50 double moreDist = (&morePt.fX)[xAxis] - axisIntercept;
51 if (calcDist > 0 ? calcDist <= moreDist : calcDist >= moreDist) {
52 continue;
53 }
54 t = nextT;
55 }
56 SkDPoint testAtT = ptAtT(t);
57 cubicAtT = testAtT;
58 calcPos = (&cubicAtT.fX)[xAxis];
59 calcDist = calcPos - axisIntercept;
60 } while (!approximately_equal(calcPos, axisIntercept));
61 return t;
62 }
63
15 // FIXME: cache keep the bounds and/or precision with the caller? 64 // FIXME: cache keep the bounds and/or precision with the caller?
16 double SkDCubic::calcPrecision() const { 65 double SkDCubic::calcPrecision() const {
17 SkDRect dRect; 66 SkDRect dRect;
18 dRect.setBounds(*this); // OPTIMIZATION: just use setRawBounds ? 67 dRect.setBounds(*this); // OPTIMIZATION: just use setRawBounds ?
19 double width = dRect.fRight - dRect.fLeft; 68 double width = dRect.fRight - dRect.fLeft;
20 double height = dRect.fBottom - dRect.fTop; 69 double height = dRect.fBottom - dRect.fTop;
21 return (width > height ? width : height) / gPrecisionUnit; 70 return (width > height ? width : height) / gPrecisionUnit;
22 } 71 }
23 72
24 bool SkDCubic::clockwise() const { 73 bool SkDCubic::clockwise() const {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 } 135 }
87 distance = lineParameters.controlPtDistance(*this, 2); 136 distance = lineParameters.controlPtDistance(*this, 2);
88 return approximately_zero(distance); 137 return approximately_zero(distance);
89 } 138 }
90 139
91 bool SkDCubic::monotonicInY() const { 140 bool SkDCubic::monotonicInY() const {
92 return between(fPts[0].fY, fPts[1].fY, fPts[3].fY) 141 return between(fPts[0].fY, fPts[1].fY, fPts[3].fY)
93 && between(fPts[0].fY, fPts[2].fY, fPts[3].fY); 142 && between(fPts[0].fY, fPts[2].fY, fPts[3].fY);
94 } 143 }
95 144
145 int SkDCubic::searchRoots(double extremeTs[6], int extrema, double axisIntercept ,
146 SearchAxis xAxis, double* validRoots) const {
147 extrema += findInflections(&extremeTs[extrema]);
148 extremeTs[extrema++] = 0;
149 extremeTs[extrema] = 1;
150 SkTQSort(extremeTs, extremeTs + extrema);
151 int validCount = 0;
152 for (int index = 0; index < extrema; ) {
153 double min = extremeTs[index];
154 double max = extremeTs[++index];
155 if (min == max) {
156 continue;
157 }
158 double newT = binarySearch(min, max, axisIntercept, xAxis);
159 if (newT >= 0) {
160 validRoots[validCount++] = newT;
161 }
162 }
163 return validCount;
164 }
165
96 bool SkDCubic::serpentine() const { 166 bool SkDCubic::serpentine() const {
97 #if 0 // FIXME: enabling this fixes cubicOp114 but breaks cubicOp58d and cubicO p53d 167 #if 0 // FIXME: enabling this fixes cubicOp114 but breaks cubicOp58d and cubicO p53d
98 double tValues[2]; 168 double tValues[2];
99 // OPTIMIZATION : another case where caching the present of cubic inflection s would be useful 169 // OPTIMIZATION : another case where caching the present of cubic inflection s would be useful
100 return findInflections(tValues) > 1; 170 return findInflections(tValues) > 1;
101 #endif 171 #endif
102 if (!controlsContainedByEnds()) { 172 if (!controlsContainedByEnds()) {
103 return false; 173 return false;
104 } 174 }
105 double wiggle = (fPts[0].fX - fPts[2].fX) * (fPts[0].fY + fPts[2].fY); 175 double wiggle = (fPts[0].fX - fPts[2].fX) * (fPts[0].fY + fPts[2].fY);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 double A = fabs(R) + sqrtR2MinusQ3; 273 double A = fabs(R) + sqrtR2MinusQ3;
204 A = SkDCubeRoot(A); 274 A = SkDCubeRoot(A);
205 if (R > 0) { 275 if (R > 0) {
206 A = -A; 276 A = -A;
207 } 277 }
208 if (A != 0) { 278 if (A != 0) {
209 A += Q / A; 279 A += Q / A;
210 } 280 }
211 r = A - adiv3; 281 r = A - adiv3;
212 *roots++ = r; 282 *roots++ = r;
213 if (AlmostDequalUlps(R2, Q3)) { 283 if (AlmostDequalUlps((double) R2, (double) Q3)) {
214 r = -A / 2 - adiv3; 284 r = -A / 2 - adiv3;
215 if (!AlmostDequalUlps(s[0], r)) { 285 if (!AlmostDequalUlps(s[0], r)) {
216 *roots++ = r; 286 *roots++ = r;
217 } 287 }
218 } 288 }
219 } 289 }
220 return static_cast<int>(roots - s); 290 return static_cast<int>(roots - s);
221 } 291 }
222 292
223 // from http://www.cs.sunysb.edu/~qin/courses/geometry/4.pdf 293 // from http://www.cs.sunysb.edu/~qin/courses/geometry/4.pdf
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 dst.pts[4].fY = (fPts[1].fY + 2 * fPts[2].fY + fPts[3].fY) / 4; 576 dst.pts[4].fY = (fPts[1].fY + 2 * fPts[2].fY + fPts[3].fY) / 4;
507 dst.pts[5].fX = (fPts[2].fX + fPts[3].fX) / 2; 577 dst.pts[5].fX = (fPts[2].fX + fPts[3].fX) / 2;
508 dst.pts[5].fY = (fPts[2].fY + fPts[3].fY) / 2; 578 dst.pts[5].fY = (fPts[2].fY + fPts[3].fY) / 2;
509 dst.pts[6] = fPts[3]; 579 dst.pts[6] = fPts[3];
510 return dst; 580 return dst;
511 } 581 }
512 interp_cubic_coords(&fPts[0].fX, &dst.pts[0].fX, t); 582 interp_cubic_coords(&fPts[0].fX, &dst.pts[0].fX, t);
513 interp_cubic_coords(&fPts[0].fY, &dst.pts[0].fY, t); 583 interp_cubic_coords(&fPts[0].fY, &dst.pts[0].fY, t);
514 return dst; 584 return dst;
515 } 585 }
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsCubic.h ('k') | src/pathops/SkPathOpsDebug.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698