Chromium Code Reviews| 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 "SkPathOpsCurve.h" | |
| 8 #include "SkPathOpsLine.h" | 9 #include "SkPathOpsLine.h" |
| 9 #include "SkPathOpsQuad.h" | 10 #include "SkPathOpsQuad.h" |
| 10 | 11 |
| 11 /* | 12 /* |
| 12 Find the interection of a line and quadratic by solving for valid t values. | 13 Find the interection of a line and quadratic by solving for valid t values. |
| 13 | 14 |
| 14 From http://stackoverflow.com/questions/1853637/how-to-find-the-mathematical-fun ction-defining-a-bezier-curve | 15 From http://stackoverflow.com/questions/1853637/how-to-find-the-mathematical-fun ction-defining-a-bezier-curve |
| 15 | 16 |
| 16 "A Bezier curve is a parametric function. A quadratic Bezier curve (i.e. three | 17 "A Bezier curve is a parametric function. A quadratic Bezier curve (i.e. three |
| 17 control points) can be expressed as: F(t) = A(1 - t)^2 + B(1 - t)t + Ct^2 where | 18 control points) can be expressed as: F(t) = A(1 - t)^2 + B(1 - t)t + Ct^2 where |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 enum PinTPoint { | 92 enum PinTPoint { |
| 92 kPointUninitialized, | 93 kPointUninitialized, |
| 93 kPointInitialized | 94 kPointInitialized |
| 94 }; | 95 }; |
| 95 | 96 |
| 96 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio ns* i) | 97 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio ns* i) |
| 97 : fQuad(q) | 98 : fQuad(q) |
| 98 , fLine(&l) | 99 , fLine(&l) |
| 99 , fIntersections(i) | 100 , fIntersections(i) |
| 100 , fAllowNear(true) { | 101 , fAllowNear(true) { |
| 101 i->setMax(3); // allow short partial coincidence plus discrete intersec tion | 102 i->setMax(4); // allow short partial coincidence plus discrete intersec tions |
| 102 } | 103 } |
| 103 | 104 |
| 104 LineQuadraticIntersections(const SkDQuad& q) | 105 LineQuadraticIntersections(const SkDQuad& q) |
| 105 : fQuad(q) | 106 : fQuad(q) |
| 106 SkDEBUGPARAMS(fLine(nullptr)) | 107 SkDEBUGPARAMS(fLine(nullptr)) |
| 107 SkDEBUGPARAMS(fIntersections(nullptr)) | 108 SkDEBUGPARAMS(fIntersections(nullptr)) |
| 108 SkDEBUGPARAMS(fAllowNear(false)) { | 109 SkDEBUGPARAMS(fAllowNear(false)) { |
| 109 } | 110 } |
| 110 | 111 |
| 111 void allowNear(bool allow) { | 112 void allowNear(bool allow) { |
| 112 fAllowNear = allow; | 113 fAllowNear = allow; |
| 113 } | 114 } |
| 114 | 115 |
| 115 void checkCoincident() { | 116 void checkCoincident() { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 double quadT = (double) (qIndex >> 1); | 291 double quadT = (double) (qIndex >> 1); |
| 291 if (fIntersections->hasT(quadT)) { | 292 if (fIntersections->hasT(quadT)) { |
| 292 continue; | 293 continue; |
| 293 } | 294 } |
| 294 double lineT = fLine->nearPoint(fQuad[qIndex], nullptr); | 295 double lineT = fLine->nearPoint(fQuad[qIndex], nullptr); |
| 295 if (lineT < 0) { | 296 if (lineT < 0) { |
| 296 continue; | 297 continue; |
| 297 } | 298 } |
| 298 fIntersections->insert(quadT, lineT, fQuad[qIndex]); | 299 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 299 } | 300 } |
| 300 // FIXME: see if line end is nearly on quad | 301 addLineNearEndPoints(); |
| 302 } | |
| 303 | |
| 304 void addLineNearEndPoints() { | |
| 305 for (int lIndex = 0; lIndex < 2; ++lIndex) { | |
| 306 double lineT = (double) lIndex; | |
| 307 if (fIntersections->hasOppT(lineT)) { | |
| 308 continue; | |
| 309 } | |
| 310 double quadT = ((SkDCurve*) &fQuad)->nearPoint(SkPath::kQuad_Verb, | |
| 311 (*fLine)[lIndex], (*fLine)[!lIndex]); | |
| 312 if (quadT < 0) { | |
| 313 continue; | |
| 314 } | |
| 315 fIntersections->insert(quadT, lineT, (*fLine)[lIndex]); | |
| 316 } | |
| 301 } | 317 } |
| 302 | 318 |
| 303 void addExactHorizontalEndPoints(double left, double right, double y) { | 319 void addExactHorizontalEndPoints(double left, double right, double y) { |
| 304 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 320 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 305 double lineT = SkDLine::ExactPointH(fQuad[qIndex], left, right, y); | 321 double lineT = SkDLine::ExactPointH(fQuad[qIndex], left, right, y); |
| 306 if (lineT < 0) { | 322 if (lineT < 0) { |
| 307 continue; | 323 continue; |
| 308 } | 324 } |
| 309 double quadT = (double) (qIndex >> 1); | 325 double quadT = (double) (qIndex >> 1); |
| 310 fIntersections->insert(quadT, lineT, fQuad[qIndex]); | 326 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 311 } | 327 } |
| 312 } | 328 } |
| 313 | 329 |
| 314 void addNearHorizontalEndPoints(double left, double right, double y) { | 330 void addNearHorizontalEndPoints(double left, double right, double y) { |
| 315 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 331 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 316 double quadT = (double) (qIndex >> 1); | 332 double quadT = (double) (qIndex >> 1); |
| 317 if (fIntersections->hasT(quadT)) { | 333 if (fIntersections->hasT(quadT)) { |
| 318 continue; | 334 continue; |
| 319 } | 335 } |
| 320 double lineT = SkDLine::NearPointH(fQuad[qIndex], left, right, y); | 336 double lineT = SkDLine::NearPointH(fQuad[qIndex], left, right, y); |
| 321 if (lineT < 0) { | 337 if (lineT < 0) { |
| 322 continue; | 338 continue; |
| 323 } | 339 } |
| 324 fIntersections->insert(quadT, lineT, fQuad[qIndex]); | 340 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 325 } | 341 } |
| 326 // FIXME: see if line end is nearly on quad | 342 addLineNearEndPoints(); |
|
herb_g
2016/07/18 15:13:39
this->
caryclark
2016/07/18 15:55:49
Done.
| |
| 327 } | 343 } |
| 328 | 344 |
| 329 void addExactVerticalEndPoints(double top, double bottom, double x) { | 345 void addExactVerticalEndPoints(double top, double bottom, double x) { |
| 330 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 346 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 331 double lineT = SkDLine::ExactPointV(fQuad[qIndex], top, bottom, x); | 347 double lineT = SkDLine::ExactPointV(fQuad[qIndex], top, bottom, x); |
| 332 if (lineT < 0) { | 348 if (lineT < 0) { |
| 333 continue; | 349 continue; |
| 334 } | 350 } |
| 335 double quadT = (double) (qIndex >> 1); | 351 double quadT = (double) (qIndex >> 1); |
| 336 fIntersections->insert(quadT, lineT, fQuad[qIndex]); | 352 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 337 } | 353 } |
| 338 } | 354 } |
| 339 | 355 |
| 340 void addNearVerticalEndPoints(double top, double bottom, double x) { | 356 void addNearVerticalEndPoints(double top, double bottom, double x) { |
| 341 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 357 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 342 double quadT = (double) (qIndex >> 1); | 358 double quadT = (double) (qIndex >> 1); |
| 343 if (fIntersections->hasT(quadT)) { | 359 if (fIntersections->hasT(quadT)) { |
| 344 continue; | 360 continue; |
| 345 } | 361 } |
| 346 double lineT = SkDLine::NearPointV(fQuad[qIndex], top, bottom, x); | 362 double lineT = SkDLine::NearPointV(fQuad[qIndex], top, bottom, x); |
| 347 if (lineT < 0) { | 363 if (lineT < 0) { |
| 348 continue; | 364 continue; |
| 349 } | 365 } |
| 350 fIntersections->insert(quadT, lineT, fQuad[qIndex]); | 366 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 351 } | 367 } |
| 352 // FIXME: see if line end is nearly on quad | 368 addLineNearEndPoints(); |
| 353 } | 369 } |
| 354 | 370 |
| 355 double findLineT(double t) { | 371 double findLineT(double t) { |
| 356 SkDPoint xy = fQuad.ptAtT(t); | 372 SkDPoint xy = fQuad.ptAtT(t); |
| 357 double dx = (*fLine)[1].fX - (*fLine)[0].fX; | 373 double dx = (*fLine)[1].fX - (*fLine)[0].fX; |
| 358 double dy = (*fLine)[1].fY - (*fLine)[0].fY; | 374 double dy = (*fLine)[1].fY - (*fLine)[0].fY; |
| 359 if (fabs(dx) > fabs(dy)) { | 375 if (fabs(dx) > fabs(dy)) { |
| 360 return (xy.fX - (*fLine)[0].fX) / dx; | 376 return (xy.fX - (*fLine)[0].fX) / dx; |
| 361 } | 377 } |
| 362 return (xy.fY - (*fLine)[0].fY) / dy; | 378 return (xy.fY - (*fLine)[0].fY) / dy; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 | 461 |
| 446 // SkDQuad accessors to Intersection utilities | 462 // SkDQuad accessors to Intersection utilities |
| 447 | 463 |
| 448 int SkDQuad::horizontalIntersect(double yIntercept, double roots[2]) const { | 464 int SkDQuad::horizontalIntersect(double yIntercept, double roots[2]) const { |
| 449 return SkIntersections::HorizontalIntercept(*this, yIntercept, roots); | 465 return SkIntersections::HorizontalIntercept(*this, yIntercept, roots); |
| 450 } | 466 } |
| 451 | 467 |
| 452 int SkDQuad::verticalIntersect(double xIntercept, double roots[2]) const { | 468 int SkDQuad::verticalIntersect(double xIntercept, double roots[2]) const { |
| 453 return SkIntersections::VerticalIntercept(*this, xIntercept, roots); | 469 return SkIntersections::VerticalIntercept(*this, xIntercept, roots); |
| 454 } | 470 } |
| OLD | NEW |