| OLD | NEW |
| 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 "SkIntersections.h" | 7 #include "SkIntersections.h" |
| 8 #include "SkLineParameters.h" | 8 #include "SkLineParameters.h" |
| 9 #include "SkPathOpsCubic.h" | 9 #include "SkPathOpsCubic.h" |
| 10 #include "SkPathOpsCurve.h" | 10 #include "SkPathOpsCurve.h" |
| 11 #include "SkPathOpsQuad.h" | 11 #include "SkPathOpsQuad.h" |
| 12 | 12 |
| 13 // from blackpawn.com/texts/pointinpoly |
| 14 static bool pointInTriangle(const SkDPoint fPts[3], const SkDPoint& test) { |
| 15 SkDVector v0 = fPts[2] - fPts[0]; |
| 16 SkDVector v1 = fPts[1] - fPts[0]; |
| 17 SkDVector v2 = test - fPts[0]; |
| 18 double dot00 = v0.dot(v0); |
| 19 double dot01 = v0.dot(v1); |
| 20 double dot02 = v0.dot(v2); |
| 21 double dot11 = v1.dot(v1); |
| 22 double dot12 = v1.dot(v2); |
| 23 // Compute barycentric coordinates |
| 24 double invDenom = 1 / (dot00 * dot11 - dot01 * dot01); |
| 25 double u = (dot11 * dot02 - dot01 * dot12) * invDenom; |
| 26 double v = (dot00 * dot12 - dot01 * dot02) * invDenom; |
| 27 // Check if point is in triangle |
| 28 return u >= 0 && v >= 0 && u + v < 1; |
| 29 } |
| 30 |
| 31 static bool matchesEnd(const SkDPoint fPts[3], const SkDPoint& test) { |
| 32 return fPts[0] == test || fPts[2] == test; |
| 33 } |
| 34 |
| 13 /* started with at_most_end_pts_in_common from SkDQuadIntersection.cpp */ | 35 /* started with at_most_end_pts_in_common from SkDQuadIntersection.cpp */ |
| 14 // Do a quick reject by rotating all points relative to a line formed by | 36 // Do a quick reject by rotating all points relative to a line formed by |
| 15 // a pair of one quad's points. If the 2nd quad's points | 37 // a pair of one quad's points. If the 2nd quad's points |
| 16 // are on the line or on the opposite side from the 1st quad's 'odd man', the | 38 // are on the line or on the opposite side from the 1st quad's 'odd man', the |
| 17 // curves at most intersect at the endpoints. | 39 // curves at most intersect at the endpoints. |
| 18 /* if returning true, check contains true if quad's hull collapsed, making the c
ubic linear | 40 /* if returning true, check contains true if quad's hull collapsed, making the c
ubic linear |
| 19 if returning false, check contains true if the the quad pair have only the en
d point in common | 41 if returning false, check contains true if the the quad pair have only the en
d point in common |
| 20 */ | 42 */ |
| 21 bool SkDQuad::hullIntersects(const SkDQuad& q2, bool* isLinear) const { | 43 bool SkDQuad::hullIntersects(const SkDQuad& q2, bool* isLinear) const { |
| 22 bool linear = true; | 44 bool linear = true; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 37 double test = (q2[n].fY - origY) * adj - (q2[n].fX - origX) * opp; | 59 double test = (q2[n].fY - origY) * adj - (q2[n].fX - origX) * opp; |
| 38 if (test * sign > 0 && !precisely_zero(test)) { | 60 if (test * sign > 0 && !precisely_zero(test)) { |
| 39 foundOutlier = true; | 61 foundOutlier = true; |
| 40 break; | 62 break; |
| 41 } | 63 } |
| 42 } | 64 } |
| 43 if (!foundOutlier) { | 65 if (!foundOutlier) { |
| 44 return false; | 66 return false; |
| 45 } | 67 } |
| 46 } | 68 } |
| 69 if (linear && !matchesEnd(fPts, q2.fPts[0]) && !matchesEnd(fPts, q2.fPts[2])
) { |
| 70 // if the end point of the opposite quad is inside the hull that is near
ly a line, |
| 71 // then representing the quad as a line may cause the intersection to be
missed. |
| 72 // Check to see if the endpoint is in the triangle. |
| 73 if (pointInTriangle(fPts, q2.fPts[0]) || pointInTriangle(fPts, q2.fPts[2
])) { |
| 74 linear = false; |
| 75 } |
| 76 } |
| 47 *isLinear = linear; | 77 *isLinear = linear; |
| 48 return true; | 78 return true; |
| 49 } | 79 } |
| 50 | 80 |
| 51 bool SkDQuad::hullIntersects(const SkDConic& conic, bool* isLinear) const { | 81 bool SkDQuad::hullIntersects(const SkDConic& conic, bool* isLinear) const { |
| 52 return conic.hullIntersects(*this, isLinear); | 82 return conic.hullIntersects(*this, isLinear); |
| 53 } | 83 } |
| 54 | 84 |
| 55 bool SkDQuad::hullIntersects(const SkDCubic& cubic, bool* isLinear) const { | 85 bool SkDQuad::hullIntersects(const SkDCubic& cubic, bool* isLinear) const { |
| 56 return cubic.hullIntersects(*this, isLinear); | 86 return cubic.hullIntersects(*this, isLinear); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 * c = C | 381 * c = C |
| 352 */ | 382 */ |
| 353 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { | 383 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { |
| 354 *a = quad[0]; // a = A | 384 *a = quad[0]; // a = A |
| 355 *b = 2 * quad[2]; // b = 2*B | 385 *b = 2 * quad[2]; // b = 2*B |
| 356 *c = quad[4]; // c = C | 386 *c = quad[4]; // c = C |
| 357 *b -= *c; // b = 2*B - C | 387 *b -= *c; // b = 2*B - C |
| 358 *a -= *b; // a = A - 2*B + C | 388 *a -= *b; // a = A - 2*B + C |
| 359 *b -= *c; // b = 2*B - 2*C | 389 *b -= *c; // b = 2*B - 2*C |
| 360 } | 390 } |
| OLD | NEW |