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 |