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

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

Issue 15338003: path ops -- rewrite angle sort (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/pathops/SkDLineIntersection.cpp ('k') | src/pathops/SkIntersections.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 // Another approach is to start with the implicit form of one curve and solve 1 // Another approach is to start with the implicit form of one curve and solve
2 // (seek implicit coefficients in QuadraticParameter.cpp 2 // (seek implicit coefficients in QuadraticParameter.cpp
3 // by substituting in the parametric form of the other. 3 // by substituting in the parametric form of the other.
4 // The downside of this approach is that early rejects are difficult to come by. 4 // The downside of this approach is that early rejects are difficult to come by.
5 // http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormu la.html#step 5 // http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormu la.html#step
6 6
7 7
8 #include "SkDQuadImplicit.h" 8 #include "SkDQuadImplicit.h"
9 #include "SkIntersections.h" 9 #include "SkIntersections.h"
10 #include "SkPathOpsLine.h" 10 #include "SkPathOpsLine.h"
11 #include "SkQuarticRoot.h" 11 #include "SkQuarticRoot.h"
12 #include "SkTDArray.h" 12 #include "SkTDArray.h"
13 #include "SkTSort.h" 13 #include "SkTSort.h"
14 14
15 /* given the implicit form 0 = Ax^2 + Bxy + Cy^2 + Dx + Ey + F 15 /* given the implicit form 0 = Ax^2 + Bxy + Cy^2 + Dx + Ey + F
16 * and given x = at^2 + bt + c (the parameterized form) 16 * and given x = at^2 + bt + c (the parameterized form)
17 * y = dt^2 + et + f 17 * y = dt^2 + et + f
18 * then 18 * then
19 * 0 = A(at^2+bt+c)(at^2+bt+c)+B(at^2+bt+c)(dt^2+et+f)+C(dt^2+et+f)(dt^2+et+f)+D (at^2+bt+c)+E(dt^2+et+f)+F 19 * 0 = A(at^2+bt+c)(at^2+bt+c)+B(at^2+bt+c)(dt^2+et+f)+C(dt^2+et+f)(dt^2+et+f)+D (at^2+bt+c)+E(dt^2+et+f)+F
20 */ 20 */
21 21
22 static int findRoots(const SkDQuadImplicit& i, const SkDQuad& q2, double roots[4 ], 22 static int findRoots(const SkDQuadImplicit& i, const SkDQuad& quad, double roots [4],
23 bool oneHint, int firstCubicRoot) { 23 bool oneHint, bool flip, int firstCubicRoot) {
24 SkDQuad flipped;
25 const SkDQuad& q = flip ? (flipped = quad.flip()) : quad;
24 double a, b, c; 26 double a, b, c;
25 SkDQuad::SetABC(&q2[0].fX, &a, &b, &c); 27 SkDQuad::SetABC(&q[0].fX, &a, &b, &c);
26 double d, e, f; 28 double d, e, f;
27 SkDQuad::SetABC(&q2[0].fY, &d, &e, &f); 29 SkDQuad::SetABC(&q[0].fY, &d, &e, &f);
28 const double t4 = i.x2() * a * a 30 const double t4 = i.x2() * a * a
29 + i.xy() * a * d 31 + i.xy() * a * d
30 + i.y2() * d * d; 32 + i.y2() * d * d;
31 const double t3 = 2 * i.x2() * a * b 33 const double t3 = 2 * i.x2() * a * b
32 + i.xy() * (a * e + b * d) 34 + i.xy() * (a * e + b * d)
33 + 2 * i.y2() * d * e; 35 + 2 * i.y2() * d * e;
34 const double t2 = i.x2() * (b * b + 2 * a * c) 36 const double t2 = i.x2() * (b * b + 2 * a * c)
35 + i.xy() * (c * d + b * e + a * f) 37 + i.xy() * (c * d + b * e + a * f)
36 + i.y2() * (e * e + 2 * d * f) 38 + i.y2() * (e * e + 2 * d * f)
37 + i.x() * a 39 + i.x() * a
38 + i.y() * d; 40 + i.y() * d;
39 const double t1 = 2 * i.x2() * b * c 41 const double t1 = 2 * i.x2() * b * c
40 + i.xy() * (c * e + b * f) 42 + i.xy() * (c * e + b * f)
41 + 2 * i.y2() * e * f 43 + 2 * i.y2() * e * f
42 + i.x() * b 44 + i.x() * b
43 + i.y() * e; 45 + i.y() * e;
44 const double t0 = i.x2() * c * c 46 const double t0 = i.x2() * c * c
45 + i.xy() * c * f 47 + i.xy() * c * f
46 + i.y2() * f * f 48 + i.y2() * f * f
47 + i.x() * c 49 + i.x() * c
48 + i.y() * f 50 + i.y() * f
49 + i.c(); 51 + i.c();
50 int rootCount = SkReducedQuarticRoots(t4, t3, t2, t1, t0, oneHint, roots); 52 int rootCount = SkReducedQuarticRoots(t4, t3, t2, t1, t0, oneHint, roots);
51 if (rootCount >= 0) { 53 if (rootCount < 0) {
52 return rootCount; 54 rootCount = SkQuarticRootsReal(firstCubicRoot, t4, t3, t2, t1, t0, roots );
53 } 55 }
54 return SkQuarticRootsReal(firstCubicRoot, t4, t3, t2, t1, t0, roots); 56 if (flip) {
57 for (int index = 0; index < rootCount; ++index) {
58 roots[index] = 1 - roots[index];
59 }
60 }
61 return rootCount;
55 } 62 }
56 63
57 static int addValidRoots(const double roots[4], const int count, double valid[4] ) { 64 static int addValidRoots(const double roots[4], const int count, double valid[4] ) {
58 int result = 0; 65 int result = 0;
59 int index; 66 int index;
60 for (index = 0; index < count; ++index) { 67 for (index = 0; index < count; ++index) {
61 if (!approximately_zero_or_more(roots[index]) || !approximately_one_or_l ess(roots[index])) { 68 if (!approximately_zero_or_more(roots[index]) || !approximately_one_or_l ess(roots[index])) {
62 continue; 69 continue;
63 } 70 }
64 double t = 1 - roots[index]; 71 double t = 1 - roots[index];
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 if ((t = SkIntersections::Axial(q2, q1[0], useVertical)) >= 0) { 403 if ((t = SkIntersections::Axial(q2, q1[0], useVertical)) >= 0) {
397 insertCoincident(0, t, q1[0]); 404 insertCoincident(0, t, q1[0]);
398 } 405 }
399 if ((t = SkIntersections::Axial(q2, q1[2], useVertical)) >= 0) { 406 if ((t = SkIntersections::Axial(q2, q1[2], useVertical)) >= 0) {
400 insertCoincident(1, t, q1[2]); 407 insertCoincident(1, t, q1[2]);
401 } 408 }
402 SkASSERT(coincidentUsed() <= 2); 409 SkASSERT(coincidentUsed() <= 2);
403 return fUsed; 410 return fUsed;
404 } 411 }
405 int index; 412 int index;
406 bool useCubic = q1[0] == q2[0] || q1[0] == q2[2] || q1[2] == q2[0]; 413 bool flip1 = q1[2] == q2[0];
414 bool flip2 = q1[0] == q2[2];
415 bool useCubic = q1[0] == q2[0];
407 double roots1[4]; 416 double roots1[4];
408 int rootCount = findRoots(i2, q1, roots1, useCubic, 0); 417 int rootCount = findRoots(i2, q1, roots1, useCubic, flip1, 0);
409 // OPTIMIZATION: could short circuit here if all roots are < 0 or > 1 418 // OPTIMIZATION: could short circuit here if all roots are < 0 or > 1
410 double roots1Copy[4]; 419 double roots1Copy[4];
411 int r1Count = addValidRoots(roots1, rootCount, roots1Copy); 420 int r1Count = addValidRoots(roots1, rootCount, roots1Copy);
412 SkDPoint pts1[4]; 421 SkDPoint pts1[4];
413 for (index = 0; index < r1Count; ++index) { 422 for (index = 0; index < r1Count; ++index) {
414 pts1[index] = q1.xyAtT(roots1Copy[index]); 423 pts1[index] = q1.xyAtT(roots1Copy[index]);
415 } 424 }
416 double roots2[4]; 425 double roots2[4];
417 int rootCount2 = findRoots(i1, q2, roots2, useCubic, 0); 426 int rootCount2 = findRoots(i1, q2, roots2, useCubic, flip2, 0);
418 double roots2Copy[4]; 427 double roots2Copy[4];
419 int r2Count = addValidRoots(roots2, rootCount2, roots2Copy); 428 int r2Count = addValidRoots(roots2, rootCount2, roots2Copy);
420 SkDPoint pts2[4]; 429 SkDPoint pts2[4];
421 for (index = 0; index < r2Count; ++index) { 430 for (index = 0; index < r2Count; ++index) {
422 pts2[index] = q2.xyAtT(roots2Copy[index]); 431 pts2[index] = q2.xyAtT(roots2Copy[index]);
423 } 432 }
424 if (r1Count == r2Count && r1Count <= 1) { 433 if (r1Count == r2Count && r1Count <= 1) {
425 if (r1Count == 1) { 434 if (r1Count == 1) {
426 if (pts1[0].approximatelyEqualHalf(pts2[0])) { 435 if (pts1[0].approximatelyEqualHalf(pts2[0])) {
427 insert(roots1Copy[0], roots2Copy[0], pts1[0]); 436 insert(roots1Copy[0], roots2Copy[0], pts1[0]);
428 } else if (pts1[0].moreRoughlyEqual(pts2[0])) { 437 } else if (pts1[0].moreRoughlyEqual(pts2[0])) {
429 // experiment: try to find intersection by chasing t 438 // experiment: try to find intersection by chasing t
430 rootCount = findRoots(i2, q1, roots1, useCubic, 0); 439 rootCount = findRoots(i2, q1, roots1, useCubic, flip1, 0);
431 (void) addValidRoots(roots1, rootCount, roots1Copy); 440 (void) addValidRoots(roots1, rootCount, roots1Copy);
432 rootCount2 = findRoots(i1, q2, roots2, useCubic, 0); 441 rootCount2 = findRoots(i1, q2, roots2, useCubic, flip2, 0);
433 (void) addValidRoots(roots2, rootCount2, roots2Copy); 442 (void) addValidRoots(roots2, rootCount2, roots2Copy);
434 if (binary_search(q1, q2, roots1Copy, roots2Copy, pts1)) { 443 if (binary_search(q1, q2, roots1Copy, roots2Copy, pts1)) {
435 insert(roots1Copy[0], roots2Copy[0], pts1[0]); 444 insert(roots1Copy[0], roots2Copy[0], pts1[0]);
436 } 445 }
437 } 446 }
438 } 447 }
439 return fUsed; 448 return fUsed;
440 } 449 }
441 int closest[4]; 450 int closest[4];
442 double dist[4]; 451 double dist[4];
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 } 498 }
490 if (lowestIndex < 0) { 499 if (lowestIndex < 0) {
491 break; 500 break;
492 } 501 }
493 insert(roots1Copy[lowestIndex], roots2Copy[closest[lowestIndex]], 502 insert(roots1Copy[lowestIndex], roots2Copy[closest[lowestIndex]],
494 pts1[lowestIndex]); 503 pts1[lowestIndex]);
495 closest[lowestIndex] = -1; 504 closest[lowestIndex] = -1;
496 } while (++used < r1Count); 505 } while (++used < r1Count);
497 return fUsed; 506 return fUsed;
498 } 507 }
OLDNEW
« no previous file with comments | « src/pathops/SkDLineIntersection.cpp ('k') | src/pathops/SkIntersections.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698