| 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 |