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 "SkPathOpsLine.h" | 8 #include "SkPathOpsLine.h" |
9 #include "SkPathOpsQuad.h" | 9 #include "SkPathOpsQuad.h" |
10 | 10 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 (2 (a - 2 b + c - d g' + 2 e g' - f g')) | 79 (2 (a - 2 b + c - d g' + 2 e g' - f g')) |
80 } | 80 } |
81 } | 81 } |
82 | 82 |
83 Thus, if the slope of the line tends towards vertical, we use: | 83 Thus, if the slope of the line tends towards vertical, we use: |
84 A = ( (a - 2*b + c) - g'*(d - 2*e + f) ) | 84 A = ( (a - 2*b + c) - g'*(d - 2*e + f) ) |
85 B = 2*(-(a - b ) + g'*(d - e ) ) | 85 B = 2*(-(a - b ) + g'*(d - e ) ) |
86 C = ( (a ) - g'*(d ) - h' ) | 86 C = ( (a ) - g'*(d ) - h' ) |
87 */ | 87 */ |
88 | 88 |
89 | |
90 class LineQuadraticIntersections { | 89 class LineQuadraticIntersections { |
91 public: | 90 public: |
92 enum PinTPoint { | 91 enum PinTPoint { |
93 kPointUninitialized, | 92 kPointUninitialized, |
94 kPointInitialized | 93 kPointInitialized |
95 }; | 94 }; |
96 | 95 |
97 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio
ns* i) | 96 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio
ns* i) |
98 : fQuad(q) | 97 : fQuad(q) |
99 , fLine(l) | 98 , fLine(l) |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 SkDPoint xy = fQuad.ptAtT(t); | 303 SkDPoint xy = fQuad.ptAtT(t); |
305 double dx = fLine[1].fX - fLine[0].fX; | 304 double dx = fLine[1].fX - fLine[0].fX; |
306 double dy = fLine[1].fY - fLine[0].fY; | 305 double dy = fLine[1].fY - fLine[0].fY; |
307 if (fabs(dx) > fabs(dy)) { | 306 if (fabs(dx) > fabs(dy)) { |
308 return (xy.fX - fLine[0].fX) / dx; | 307 return (xy.fX - fLine[0].fX) / dx; |
309 } | 308 } |
310 return (xy.fY - fLine[0].fY) / dy; | 309 return (xy.fY - fLine[0].fY) / dy; |
311 } | 310 } |
312 | 311 |
313 bool pinTs(double* quadT, double* lineT, SkDPoint* pt, PinTPoint ptSet) { | 312 bool pinTs(double* quadT, double* lineT, SkDPoint* pt, PinTPoint ptSet) { |
314 if (!approximately_one_or_less(*lineT)) { | 313 if (!approximately_one_or_less_double(*lineT)) { |
315 return false; | 314 return false; |
316 } | 315 } |
317 if (!approximately_zero_or_more(*lineT)) { | 316 if (!approximately_zero_or_more_double(*lineT)) { |
318 return false; | 317 return false; |
319 } | 318 } |
320 double qT = *quadT = SkPinT(*quadT); | 319 double qT = *quadT = SkPinT(*quadT); |
321 double lT = *lineT = SkPinT(*lineT); | 320 double lT = *lineT = SkPinT(*lineT); |
322 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT
!= 1)) { | 321 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT
!= 1)) { |
323 *pt = fLine.ptAtT(lT); | 322 *pt = fLine.ptAtT(lT); |
324 } else if (ptSet == kPointUninitialized) { | 323 } else if (ptSet == kPointUninitialized) { |
325 *pt = fQuad.ptAtT(qT); | 324 *pt = fQuad.ptAtT(qT); |
326 } | 325 } |
327 SkPoint gridPt = pt->asSkPoint(); | 326 SkPoint gridPt = pt->asSkPoint(); |
328 if (gridPt == fLine[0].asSkPoint()) { | 327 if (gridPt == fLine[0].asSkPoint()) { |
| 328 *pt = fLine[0]; |
329 *lineT = 0; | 329 *lineT = 0; |
330 } else if (gridPt == fLine[1].asSkPoint()) { | 330 } else if (gridPt == fLine[1].asSkPoint()) { |
| 331 *pt = fLine[1]; |
331 *lineT = 1; | 332 *lineT = 1; |
332 } | 333 } |
333 if (gridPt == fQuad[0].asSkPoint()) { | 334 if (gridPt == fQuad[0].asSkPoint()) { |
| 335 *pt = fQuad[0]; |
334 *quadT = 0; | 336 *quadT = 0; |
335 } else if (gridPt == fQuad[2].asSkPoint()) { | 337 } else if (gridPt == fQuad[2].asSkPoint()) { |
| 338 *pt = fQuad[2]; |
336 *quadT = 1; | 339 *quadT = 1; |
337 } | 340 } |
338 return true; | 341 return true; |
339 } | 342 } |
340 | 343 |
341 private: | 344 private: |
342 const SkDQuad& fQuad; | 345 const SkDQuad& fQuad; |
343 const SkDLine& fLine; | 346 const SkDLine& fLine; |
344 SkIntersections* fIntersections; | 347 SkIntersections* fIntersections; |
345 bool fAllowNear; | 348 bool fAllowNear; |
346 }; | 349 }; |
347 | 350 |
348 // utility for pairs of coincident quads | |
349 static double horizontalIntersect(const SkDQuad& quad, const SkDPoint& pt) { | |
350 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), | |
351 static_cast<SkIntersections*>(0)); | |
352 double rootVals[2]; | |
353 int roots = q.horizontalIntersect(pt.fY, rootVals); | |
354 for (int index = 0; index < roots; ++index) { | |
355 double t = rootVals[index]; | |
356 SkDPoint qPt = quad.ptAtT(t); | |
357 if (AlmostEqualUlps(qPt.fX, pt.fX)) { | |
358 return t; | |
359 } | |
360 } | |
361 return -1; | |
362 } | |
363 | |
364 static double verticalIntersect(const SkDQuad& quad, const SkDPoint& pt) { | |
365 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), | |
366 static_cast<SkIntersections*>(0)); | |
367 double rootVals[2]; | |
368 int roots = q.verticalIntersect(pt.fX, rootVals); | |
369 for (int index = 0; index < roots; ++index) { | |
370 double t = rootVals[index]; | |
371 SkDPoint qPt = quad.ptAtT(t); | |
372 if (AlmostEqualUlps(qPt.fY, pt.fY)) { | |
373 return t; | |
374 } | |
375 } | |
376 return -1; | |
377 } | |
378 | |
379 double SkIntersections::Axial(const SkDQuad& q1, const SkDPoint& p, bool vertica
l) { | |
380 if (vertical) { | |
381 return verticalIntersect(q1, p); | |
382 } | |
383 return horizontalIntersect(q1, p); | |
384 } | |
385 | |
386 int SkIntersections::horizontal(const SkDQuad& quad, double left, double right,
double y, | 351 int SkIntersections::horizontal(const SkDQuad& quad, double left, double right,
double y, |
387 bool flipped) { | 352 bool flipped) { |
388 SkDLine line = {{{ left, y }, { right, y }}}; | 353 SkDLine line = {{{ left, y }, { right, y }}}; |
389 LineQuadraticIntersections q(quad, line, this); | 354 LineQuadraticIntersections q(quad, line, this); |
390 return q.horizontalIntersect(y, left, right, flipped); | 355 return q.horizontalIntersect(y, left, right, flipped); |
391 } | 356 } |
392 | 357 |
393 int SkIntersections::vertical(const SkDQuad& quad, double top, double bottom, do
uble x, | 358 int SkIntersections::vertical(const SkDQuad& quad, double top, double bottom, do
uble x, |
394 bool flipped) { | 359 bool flipped) { |
395 SkDLine line = {{{ x, top }, { x, bottom }}}; | 360 SkDLine line = {{{ x, top }, { x, bottom }}}; |
396 LineQuadraticIntersections q(quad, line, this); | 361 LineQuadraticIntersections q(quad, line, this); |
397 return q.verticalIntersect(x, top, bottom, flipped); | 362 return q.verticalIntersect(x, top, bottom, flipped); |
398 } | 363 } |
399 | 364 |
400 int SkIntersections::intersect(const SkDQuad& quad, const SkDLine& line) { | 365 int SkIntersections::intersect(const SkDQuad& quad, const SkDLine& line) { |
401 LineQuadraticIntersections q(quad, line, this); | 366 LineQuadraticIntersections q(quad, line, this); |
402 q.allowNear(fAllowNear); | 367 q.allowNear(fAllowNear); |
403 return q.intersect(); | 368 return q.intersect(); |
404 } | 369 } |
405 | 370 |
406 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { | 371 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { |
407 LineQuadraticIntersections q(quad, line, this); | 372 LineQuadraticIntersections q(quad, line, this); |
408 fUsed = q.intersectRay(fT[0]); | 373 fUsed = q.intersectRay(fT[0]); |
409 for (int index = 0; index < fUsed; ++index) { | 374 for (int index = 0; index < fUsed; ++index) { |
410 fPt[index] = quad.ptAtT(fT[0][index]); | 375 fPt[index] = quad.ptAtT(fT[0][index]); |
411 } | 376 } |
412 return fUsed; | 377 return fUsed; |
413 } | 378 } |
OLD | NEW |