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 |