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 "SkPathOpsQuad.h" | 11 #include "SkPathOpsQuad.h" |
11 | 12 |
12 /* started with at_most_end_pts_in_common from SkDQuadIntersection.cpp */ | 13 /* started with at_most_end_pts_in_common from SkDQuadIntersection.cpp */ |
13 // Do a quick reject by rotating all points relative to a line formed by | 14 // Do a quick reject by rotating all points relative to a line formed by |
14 // a pair of one quad's points. If the 2nd quad's points | 15 // a pair of one quad's points. If the 2nd quad's points |
15 // are on the line or on the opposite side from the 1st quad's 'odd man', the | 16 // are on the line or on the opposite side from the 1st quad's 'odd man', the |
16 // curves at most intersect at the endpoints. | 17 // curves at most intersect at the endpoints. |
17 /* if returning true, check contains true if quad's hull collapsed, making the c
ubic linear | 18 /* if returning true, check contains true if quad's hull collapsed, making the c
ubic linear |
18 if returning false, check contains true if the the quad pair have only the en
d point in common | 19 if returning false, check contains true if the the quad pair have only the en
d point in common |
19 */ | 20 */ |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 distMin = dist; | 99 distMin = dist; |
99 bestIndex = index; | 100 bestIndex = index; |
100 } | 101 } |
101 } | 102 } |
102 if (bestIndex >= 0) { | 103 if (bestIndex >= 0) { |
103 return ts[bestIndex]; | 104 return ts[bestIndex]; |
104 } | 105 } |
105 return d0 < d2 ? 0 : 1; | 106 return d0 < d2 ? 0 : 1; |
106 } | 107 } |
107 | 108 |
108 SkDPoint SkDQuad::top(double startT, double endT) const { | |
109 SkDQuad sub = subDivide(startT, endT); | |
110 SkDPoint topPt = sub[0]; | |
111 if (topPt.fY > sub[2].fY || (topPt.fY == sub[2].fY && topPt.fX > sub[2].fX))
{ | |
112 topPt = sub[2]; | |
113 } | |
114 if (!between(sub[0].fY, sub[1].fY, sub[2].fY)) { | |
115 double extremeT; | |
116 if (FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, &extremeT)) { | |
117 extremeT = startT + (endT - startT) * extremeT; | |
118 SkDPoint test = ptAtT(extremeT); | |
119 if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX
)) { | |
120 topPt = test; | |
121 } | |
122 } | |
123 } | |
124 return topPt; | |
125 } | |
126 | |
127 int SkDQuad::AddValidTs(double s[], int realRoots, double* t) { | 109 int SkDQuad::AddValidTs(double s[], int realRoots, double* t) { |
128 int foundRoots = 0; | 110 int foundRoots = 0; |
129 for (int index = 0; index < realRoots; ++index) { | 111 for (int index = 0; index < realRoots; ++index) { |
130 double tValue = s[index]; | 112 double tValue = s[index]; |
131 if (approximately_zero_or_more(tValue) && approximately_one_or_less(tVal
ue)) { | 113 if (approximately_zero_or_more(tValue) && approximately_one_or_less(tVal
ue)) { |
132 if (approximately_less_than_zero(tValue)) { | 114 if (approximately_less_than_zero(tValue)) { |
133 tValue = 0; | 115 tValue = 0; |
134 } else if (approximately_greater_than_one(tValue)) { | 116 } else if (approximately_greater_than_one(tValue)) { |
135 tValue = 1; | 117 tValue = 1; |
136 } | 118 } |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 b.fX = c.fX; | 316 b.fX = c.fX; |
335 } | 317 } |
336 if (AlmostBequalUlps(b.fY, a.fY)) { | 318 if (AlmostBequalUlps(b.fY, a.fY)) { |
337 b.fY = a.fY; | 319 b.fY = a.fY; |
338 } else if (AlmostBequalUlps(b.fY, c.fY)) { | 320 } else if (AlmostBequalUlps(b.fY, c.fY)) { |
339 b.fY = c.fY; | 321 b.fY = c.fY; |
340 } | 322 } |
341 return b; | 323 return b; |
342 } | 324 } |
343 | 325 |
| 326 SkDPoint SkDQuad::top(double startT, double endT, double* topT) const { |
| 327 SkDQuad sub = subDivide(startT, endT); |
| 328 SkDPoint topPt = sub[0]; |
| 329 *topT = startT; |
| 330 if (topPt.fY > sub[2].fY || (topPt.fY == sub[2].fY && topPt.fX > sub[2].fX))
{ |
| 331 *topT = endT; |
| 332 topPt = sub[2]; |
| 333 } |
| 334 if (!between(sub[0].fY, sub[1].fY, sub[2].fY)) { |
| 335 double extremeT; |
| 336 if (FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, &extremeT)) { |
| 337 extremeT = startT + (endT - startT) * extremeT; |
| 338 SkDPoint test = ptAtT(extremeT); |
| 339 if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX
)) { |
| 340 *topT = extremeT; |
| 341 topPt = test; |
| 342 } |
| 343 } |
| 344 } |
| 345 return topPt; |
| 346 } |
| 347 |
344 /* classic one t subdivision */ | 348 /* classic one t subdivision */ |
345 static void interp_quad_coords(const double* src, double* dst, double t) { | 349 static void interp_quad_coords(const double* src, double* dst, double t) { |
346 double ab = SkDInterp(src[0], src[2], t); | 350 double ab = SkDInterp(src[0], src[2], t); |
347 double bc = SkDInterp(src[2], src[4], t); | 351 double bc = SkDInterp(src[2], src[4], t); |
348 dst[0] = src[0]; | 352 dst[0] = src[0]; |
349 dst[2] = ab; | 353 dst[2] = ab; |
350 dst[4] = SkDInterp(ab, bc, t); | 354 dst[4] = SkDInterp(ab, bc, t); |
351 dst[6] = bc; | 355 dst[6] = bc; |
352 dst[8] = src[4]; | 356 dst[8] = src[4]; |
353 } | 357 } |
354 | 358 |
355 SkDQuadPair SkDQuad::chopAt(double t) const | 359 SkDQuadPair SkDQuad::chopAt(double t) const |
356 { | 360 { |
357 SkDQuadPair dst; | 361 SkDQuadPair dst; |
358 interp_quad_coords(&fPts[0].fX, &dst.pts[0].fX, t); | 362 interp_quad_coords(&fPts[0].fX, &dst.pts[0].fX, t); |
359 interp_quad_coords(&fPts[0].fY, &dst.pts[0].fY, t); | 363 interp_quad_coords(&fPts[0].fY, &dst.pts[0].fY, t); |
360 return dst; | 364 return dst; |
361 } | 365 } |
362 | 366 |
| 367 bool SkDQuad::Clockwise(const SkOpCurve& edge, bool* swap) { |
| 368 SkDQuad temp; |
| 369 double sum = (edge[0].fX - edge[kPointLast].fX) * (edge[0].fY + edge[kPointL
ast].fY); |
| 370 for (int idx = 0; idx < kPointLast; ++idx){ |
| 371 sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx]
.fY); |
| 372 } |
| 373 temp.set(edge.fPts); |
| 374 *swap = sum > 0 && !temp.monotonicInY(); |
| 375 return sum <= 0; |
| 376 } |
| 377 |
363 static int valid_unit_divide(double numer, double denom, double* ratio) | 378 static int valid_unit_divide(double numer, double denom, double* ratio) |
364 { | 379 { |
365 if (numer < 0) { | 380 if (numer < 0) { |
366 numer = -numer; | 381 numer = -numer; |
367 denom = -denom; | 382 denom = -denom; |
368 } | 383 } |
369 if (denom == 0 || numer == 0 || numer >= denom) { | 384 if (denom == 0 || numer == 0 || numer >= denom) { |
370 return 0; | 385 return 0; |
371 } | 386 } |
372 double r = numer / denom; | 387 double r = numer / denom; |
(...skipping 23 matching lines...) Expand all Loading... |
396 * c = C | 411 * c = C |
397 */ | 412 */ |
398 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { | 413 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { |
399 *a = quad[0]; // a = A | 414 *a = quad[0]; // a = A |
400 *b = 2 * quad[2]; // b = 2*B | 415 *b = 2 * quad[2]; // b = 2*B |
401 *c = quad[4]; // c = C | 416 *c = quad[4]; // c = C |
402 *b -= *c; // b = 2*B - C | 417 *b -= *c; // b = 2*B - C |
403 *a -= *b; // a = A - 2*B + C | 418 *a -= *b; // a = A - 2*B + C |
404 *b -= *c; // b = 2*B - 2*C | 419 *b -= *c; // b = 2*B - 2*C |
405 } | 420 } |
OLD | NEW |