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 | 7 |
8 #include "SkIntersections.h" | 8 #include "SkIntersections.h" |
9 #include "SkPathOpsCubic.h" | 9 #include "SkPathOpsCubic.h" |
10 #include "SkPathOpsLine.h" | 10 #include "SkPathOpsLine.h" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 #endif | 114 #endif |
115 SkIntersections locals; | 115 SkIntersections locals; |
116 intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, locals); | 116 intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, locals); |
117 double coStart[2] = { -1 }; | 117 double coStart[2] = { -1 }; |
118 SkDPoint coPoint; | 118 SkDPoint coPoint; |
119 int tCount = locals.used(); | 119 int tCount = locals.used(); |
120 for (int tIdx = 0; tIdx < tCount; ++tIdx) { | 120 for (int tIdx = 0; tIdx < tCount; ++tIdx) { |
121 double to1 = t1Start + (t1 - t1Start) * locals[0][tIdx]; | 121 double to1 = t1Start + (t1 - t1Start) * locals[0][tIdx]; |
122 double to2 = t2Start + (t2 - t2Start) * locals[1][tIdx]; | 122 double to2 = t2Start + (t2 - t2Start) * locals[1][tIdx]; |
123 // if the computed t is not sufficiently precise, iterate | 123 // if the computed t is not sufficiently precise, iterate |
124 SkDPoint p1 = cubic1.xyAtT(to1); | 124 SkDPoint p1 = cubic1.ptAtT(to1); |
125 SkDPoint p2 = cubic2.xyAtT(to2); | 125 SkDPoint p2 = cubic2.ptAtT(to2); |
126 if (p1.approximatelyEqual(p2)) { | 126 if (p1.approximatelyEqual(p2)) { |
127 if (locals.isCoincident(tIdx)) { | 127 if (locals.isCoincident(tIdx)) { |
128 if (coStart[0] < 0) { | 128 if (coStart[0] < 0) { |
129 coStart[0] = to1; | 129 coStart[0] = to1; |
130 coStart[1] = to2; | 130 coStart[1] = to2; |
131 coPoint = p1; | 131 coPoint = p1; |
132 } else { | 132 } else { |
133 i.insertCoincidentPair(coStart[0], to1, coStart[1],
to2, coPoint, p1); | 133 i.insertCoincidentPair(coStart[0], to1, coStart[1],
to2, coPoint, p1); |
134 coStart[0] = -1; | 134 coStart[0] = -1; |
135 } | 135 } |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 #endif | 382 #endif |
383 return; | 383 return; |
384 } | 384 } |
385 | 385 |
386 const double CLOSE_ENOUGH = 0.001; | 386 const double CLOSE_ENOUGH = 0.001; |
387 | 387 |
388 static bool closeStart(const SkDCubic& cubic, int cubicIndex, SkIntersections& i
, SkDPoint& pt) { | 388 static bool closeStart(const SkDCubic& cubic, int cubicIndex, SkIntersections& i
, SkDPoint& pt) { |
389 if (i[cubicIndex][0] != 0 || i[cubicIndex][1] > CLOSE_ENOUGH) { | 389 if (i[cubicIndex][0] != 0 || i[cubicIndex][1] > CLOSE_ENOUGH) { |
390 return false; | 390 return false; |
391 } | 391 } |
392 pt = cubic.xyAtT((i[cubicIndex][0] + i[cubicIndex][1]) / 2); | 392 pt = cubic.ptAtT((i[cubicIndex][0] + i[cubicIndex][1]) / 2); |
393 return true; | 393 return true; |
394 } | 394 } |
395 | 395 |
396 static bool closeEnd(const SkDCubic& cubic, int cubicIndex, SkIntersections& i,
SkDPoint& pt) { | 396 static bool closeEnd(const SkDCubic& cubic, int cubicIndex, SkIntersections& i,
SkDPoint& pt) { |
397 int last = i.used() - 1; | 397 int last = i.used() - 1; |
398 if (i[cubicIndex][last] != 1 || i[cubicIndex][last - 1] < 1 - CLOSE_ENOUGH)
{ | 398 if (i[cubicIndex][last] != 1 || i[cubicIndex][last - 1] < 1 - CLOSE_ENOUGH)
{ |
399 return false; | 399 return false; |
400 } | 400 } |
401 pt = cubic.xyAtT((i[cubicIndex][last] + i[cubicIndex][last - 1]) / 2); | 401 pt = cubic.ptAtT((i[cubicIndex][last] + i[cubicIndex][last - 1]) / 2); |
402 return true; | 402 return true; |
403 } | 403 } |
404 | 404 |
405 int SkIntersections::intersect(const SkDCubic& c1, const SkDCubic& c2) { | 405 int SkIntersections::intersect(const SkDCubic& c1, const SkDCubic& c2) { |
406 ::intersect(c1, 0, 1, c2, 0, 1, 1, *this); | 406 ::intersect(c1, 0, 1, c2, 0, 1, 1, *this); |
407 // FIXME: pass in cached bounds from caller | 407 // FIXME: pass in cached bounds from caller |
408 SkDRect c1Bounds, c2Bounds; | 408 SkDRect c1Bounds, c2Bounds; |
409 c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ? | 409 c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ? |
410 c2Bounds.setBounds(c2); | 410 c2Bounds.setBounds(c2); |
411 intersectEnd(c1, false, c2, c2Bounds, *this); | 411 intersectEnd(c1, false, c2, c2Bounds, *this); |
(...skipping 21 matching lines...) Expand all Loading... |
433 removeOne(used() - 2); | 433 removeOne(used() - 2); |
434 } | 434 } |
435 // vet the pairs of t values to see if the mid value is also on the curve. I
f so, mark | 435 // vet the pairs of t values to see if the mid value is also on the curve. I
f so, mark |
436 // the span as coincident | 436 // the span as coincident |
437 if (fUsed >= 2 && !coincidentUsed()) { | 437 if (fUsed >= 2 && !coincidentUsed()) { |
438 int last = fUsed - 1; | 438 int last = fUsed - 1; |
439 int match = 0; | 439 int match = 0; |
440 for (int index = 0; index < last; ++index) { | 440 for (int index = 0; index < last; ++index) { |
441 double mid1 = (fT[0][index] + fT[0][index + 1]) / 2; | 441 double mid1 = (fT[0][index] + fT[0][index + 1]) / 2; |
442 double mid2 = (fT[1][index] + fT[1][index + 1]) / 2; | 442 double mid2 = (fT[1][index] + fT[1][index + 1]) / 2; |
443 pt[0] = c1.xyAtT(mid1); | 443 pt[0] = c1.ptAtT(mid1); |
444 pt[1] = c2.xyAtT(mid2); | 444 pt[1] = c2.ptAtT(mid2); |
445 if (pt[0].approximatelyEqual(pt[1])) { | 445 if (pt[0].approximatelyEqual(pt[1])) { |
446 match |= 1 << index; | 446 match |= 1 << index; |
447 } | 447 } |
448 } | 448 } |
449 if (match) { | 449 if (match) { |
450 if (((match + 1) & match) != 0) { | 450 if (((match + 1) & match) != 0) { |
451 SkDebugf("%s coincident hole\n", __FUNCTION__); | 451 SkDebugf("%s coincident hole\n", __FUNCTION__); |
452 } | 452 } |
453 // for now, assume that everything from start to finish is coinciden
t | 453 // for now, assume that everything from start to finish is coinciden
t |
454 if (fUsed > 2) { | 454 if (fUsed > 2) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 } | 487 } |
488 (void) intersect(c, c); | 488 (void) intersect(c, c); |
489 if (used() > 0) { | 489 if (used() > 0) { |
490 SkASSERT(used() == 1); | 490 SkASSERT(used() == 1); |
491 if (fT[0][0] > fT[1][0]) { | 491 if (fT[0][0] > fT[1][0]) { |
492 swapPts(); | 492 swapPts(); |
493 } | 493 } |
494 } | 494 } |
495 return used(); | 495 return used(); |
496 } | 496 } |
OLD | NEW |