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 "SkPathOpsLine.h" | 8 #include "SkPathOpsLine.h" |
9 | 9 |
10 /* Determine the intersection point of two lines. This assumes the lines are not
parallel, | 10 /* Determine the intersection point of two lines. This assumes the lines are not
parallel, |
(...skipping 16 matching lines...) Expand all Loading... |
27 } | 27 } |
28 | 28 |
29 int SkIntersections::computePoints(const SkDLine& line, int used) { | 29 int SkIntersections::computePoints(const SkDLine& line, int used) { |
30 fPt[0] = line.xyAtT(fT[0][0]); | 30 fPt[0] = line.xyAtT(fT[0][0]); |
31 if ((fUsed = used) == 2) { | 31 if ((fUsed = used) == 2) { |
32 fPt[1] = line.xyAtT(fT[0][1]); | 32 fPt[1] = line.xyAtT(fT[0][1]); |
33 } | 33 } |
34 return fUsed; | 34 return fUsed; |
35 } | 35 } |
36 | 36 |
| 37 int SkIntersections::intersectRay(const SkDLine& a, const SkDLine& b) { |
| 38 double axLen = a[1].fX - a[0].fX; |
| 39 double ayLen = a[1].fY - a[0].fY; |
| 40 double bxLen = b[1].fX - b[0].fX; |
| 41 double byLen = b[1].fY - b[0].fY; |
| 42 /* Slopes match when denom goes to zero: |
| 43 axLen / ayLen == bxLen / byLen |
| 44 (ayLen * byLen) * axLen / ayLen == (ayLen * byLen) * bxLen / byLen |
| 45 byLen * axLen == ayLen * bxLen |
| 46 byLen * axLen - ayLen * bxLen == 0 ( == denom ) |
| 47 */ |
| 48 double denom = byLen * axLen - ayLen * bxLen; |
| 49 double ab0y = a[0].fY - b[0].fY; |
| 50 double ab0x = a[0].fX - b[0].fX; |
| 51 double numerA = ab0y * bxLen - byLen * ab0x; |
| 52 double numerB = ab0y * axLen - ayLen * ab0x; |
| 53 numerA /= denom; |
| 54 numerB /= denom; |
| 55 int used; |
| 56 if (!approximately_zero(denom)) { |
| 57 fT[0][0] = numerA; |
| 58 fT[1][0] = numerB; |
| 59 used = 1; |
| 60 } else { |
| 61 /* See if the axis intercepts match: |
| 62 ay - ax * ayLen / axLen == by - bx * ayLen / axLen |
| 63 axLen * (ay - ax * ayLen / axLen) == axLen * (by - bx * ayLen / axLen) |
| 64 axLen * ay - ax * ayLen == axLen * by - bx * ayLen |
| 65 */ |
| 66 if (!AlmostEqualUlps(axLen * a[0].fY - ayLen * a[0].fX, |
| 67 axLen * b[0].fY - ayLen * b[0].fX)) { |
| 68 return fUsed = 0; |
| 69 } |
| 70 // there's no great answer for intersection points for coincident rays,
but return something |
| 71 fT[0][0] = fT[1][0] = 0; |
| 72 fT[1][0] = fT[1][1] = 1; |
| 73 used = 2; |
| 74 } |
| 75 return computePoints(a, used); |
| 76 } |
| 77 |
37 /* | 78 /* |
38 Determine the intersection point of two line segments | 79 Determine the intersection point of two line segments |
39 Return FALSE if the lines don't intersect | 80 Return FALSE if the lines don't intersect |
40 from: http://paulbourke.net/geometry/lineline2d/ | 81 from: http://paulbourke.net/geometry/lineline2d/ |
41 */ | 82 */ |
42 | 83 |
43 int SkIntersections::intersect(const SkDLine& a, const SkDLine& b) { | 84 int SkIntersections::intersect(const SkDLine& a, const SkDLine& b) { |
44 double axLen = a[1].fX - a[0].fX; | 85 double axLen = a[1].fX - a[0].fX; |
45 double ayLen = a[1].fY - a[0].fY; | 86 double ayLen = a[1].fY - a[0].fY; |
46 double bxLen = b[1].fX - b[0].fX; | 87 double bxLen = b[1].fX - b[0].fX; |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 // 4 subs, 2 muls, 1 cmp | 291 // 4 subs, 2 muls, 1 cmp |
251 static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) { | 292 static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) { |
252 return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX); | 293 return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX); |
253 } | 294 } |
254 | 295 |
255 // 16 subs, 8 muls, 6 cmps | 296 // 16 subs, 8 muls, 6 cmps |
256 bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) { | 297 bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) { |
257 return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1]) | 298 return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1]) |
258 && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]); | 299 && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]); |
259 } | 300 } |
OLD | NEW |