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 "SkPathOpsQuad.h" | 10 #include "SkPathOpsQuad.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 double b = 3 * A.dot(B); | 23 double b = 3 * A.dot(B); |
24 double c = 2 * A.dot(A) + pos.dot(B); | 24 double c = 2 * A.dot(A) + pos.dot(B); |
25 double d = pos.dot(A); | 25 double d = pos.dot(A); |
26 double ts[3]; | 26 double ts[3]; |
27 int roots = SkDCubic::RootsValidT(a, b, c, d, ts); | 27 int roots = SkDCubic::RootsValidT(a, b, c, d, ts); |
28 double d0 = pt.distanceSquared(fPts[0]); | 28 double d0 = pt.distanceSquared(fPts[0]); |
29 double d2 = pt.distanceSquared(fPts[2]); | 29 double d2 = pt.distanceSquared(fPts[2]); |
30 double distMin = SkTMin(d0, d2); | 30 double distMin = SkTMin(d0, d2); |
31 int bestIndex = -1; | 31 int bestIndex = -1; |
32 for (int index = 0; index < roots; ++index) { | 32 for (int index = 0; index < roots; ++index) { |
33 SkDPoint onQuad = xyAtT(ts[index]); | 33 SkDPoint onQuad = ptAtT(ts[index]); |
34 double dist = pt.distanceSquared(onQuad); | 34 double dist = pt.distanceSquared(onQuad); |
35 if (distMin > dist) { | 35 if (distMin > dist) { |
36 distMin = dist; | 36 distMin = dist; |
37 bestIndex = index; | 37 bestIndex = index; |
38 } | 38 } |
39 } | 39 } |
40 if (bestIndex >= 0) { | 40 if (bestIndex >= 0) { |
41 return ts[bestIndex]; | 41 return ts[bestIndex]; |
42 } | 42 } |
43 return d0 < d2 ? 0 : 1; | 43 return d0 < d2 ? 0 : 1; |
44 } | 44 } |
45 | 45 |
46 bool SkDQuad::pointInHull(const SkDPoint& pt) const { | 46 bool SkDQuad::pointInHull(const SkDPoint& pt) const { |
47 return ((const SkDTriangle&) fPts).contains(pt); | 47 return ((const SkDTriangle&) fPts).contains(pt); |
48 } | 48 } |
49 | 49 |
50 SkDPoint SkDQuad::top(double startT, double endT) const { | 50 SkDPoint SkDQuad::top(double startT, double endT) const { |
51 SkDQuad sub = subDivide(startT, endT); | 51 SkDQuad sub = subDivide(startT, endT); |
52 SkDPoint topPt = sub[0]; | 52 SkDPoint topPt = sub[0]; |
53 if (topPt.fY > sub[2].fY || (topPt.fY == sub[2].fY && topPt.fX > sub[2].fX))
{ | 53 if (topPt.fY > sub[2].fY || (topPt.fY == sub[2].fY && topPt.fX > sub[2].fX))
{ |
54 topPt = sub[2]; | 54 topPt = sub[2]; |
55 } | 55 } |
56 if (!between(sub[0].fY, sub[1].fY, sub[2].fY)) { | 56 if (!between(sub[0].fY, sub[1].fY, sub[2].fY)) { |
57 double extremeT; | 57 double extremeT; |
58 if (FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, &extremeT)) { | 58 if (FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, &extremeT)) { |
59 extremeT = startT + (endT - startT) * extremeT; | 59 extremeT = startT + (endT - startT) * extremeT; |
60 SkDPoint test = xyAtT(extremeT); | 60 SkDPoint test = ptAtT(extremeT); |
61 if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX
)) { | 61 if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX
)) { |
62 topPt = test; | 62 topPt = test; |
63 } | 63 } |
64 } | 64 } |
65 } | 65 } |
66 return topPt; | 66 return topPt; |
67 } | 67 } |
68 | 68 |
69 int SkDQuad::AddValidTs(double s[], int realRoots, double* t) { | 69 int SkDQuad::AddValidTs(double s[], int realRoots, double* t) { |
70 int foundRoots = 0; | 70 int foundRoots = 0; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 SkDVector SkDQuad::dxdyAtT(double t) const { | 158 SkDVector SkDQuad::dxdyAtT(double t) const { |
159 double a = t - 1; | 159 double a = t - 1; |
160 double b = 1 - 2 * t; | 160 double b = 1 - 2 * t; |
161 double c = t; | 161 double c = t; |
162 SkDVector result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, | 162 SkDVector result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, |
163 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; | 163 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; |
164 return result; | 164 return result; |
165 } | 165 } |
166 | 166 |
167 // OPTIMIZE: assert if caller passes in t == 0 / t == 1 ? | 167 // OPTIMIZE: assert if caller passes in t == 0 / t == 1 ? |
168 SkDPoint SkDQuad::xyAtT(double t) const { | 168 SkDPoint SkDQuad::ptAtT(double t) const { |
| 169 if (t == 0) { |
| 170 return fPts[0]; |
| 171 } |
| 172 if (t == 1) { |
| 173 return fPts[2]; |
| 174 } |
169 double one_t = 1 - t; | 175 double one_t = 1 - t; |
170 double a = one_t * one_t; | 176 double a = one_t * one_t; |
171 double b = 2 * one_t * t; | 177 double b = 2 * one_t * t; |
172 double c = t * t; | 178 double c = t * t; |
173 SkDPoint result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, | 179 SkDPoint result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, |
174 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; | 180 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; |
175 return result; | 181 return result; |
176 } | 182 } |
177 | 183 |
178 /* | 184 /* |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 * c = C | 333 * c = C |
328 */ | 334 */ |
329 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { | 335 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { |
330 *a = quad[0]; // a = A | 336 *a = quad[0]; // a = A |
331 *b = 2 * quad[2]; // b = 2*B | 337 *b = 2 * quad[2]; // b = 2*B |
332 *c = quad[4]; // c = C | 338 *c = quad[4]; // c = C |
333 *b -= *c; // b = 2*B - C | 339 *b -= *c; // b = 2*B - C |
334 *a -= *b; // a = A - 2*B + C | 340 *a -= *b; // a = A - 2*B + C |
335 *b -= *c; // b = 2*B - 2*C | 341 *b -= *c; // b = 2*B - 2*C |
336 } | 342 } |
OLD | NEW |