bool intersect3(const Cubic& c1, const Cubic& c2, Intersections& i) { bool result = intersect3(c1, 0, 1, c2, 0, 1, 1, i); // FIXME: pass in cached bounds from caller _Rect c1Bounds, c2Bounds; c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ? c2Bounds.setBounds(c2); result |= intersectEnd(c1, false, c2, c2Bounds, i); result |= intersectEnd(c1, true, c2, c2Bounds, i); bool selfIntersect = c1 == c2; if (!selfIntersect) { i.swap(); result |= intersectEnd(c2, false, c1, c1Bounds, i); result |= intersectEnd(c2, true, c1, c1Bounds, i); i.swap(); } // If an end point and a second point very close to the end is returned, the second // point may have been detected because the approximate quads // intersected at the end and close to it. Verify that the second point is valid. if (i.used() <= 1 || i.coincidentUsed()) { return result; } _Point pt[2]; if (closeStart(c1, 0, i, pt[0]) && closeStart(c2, 1, i, pt[1]) && pt[0].approximatelyEqual(pt[1])) { i.removeOne(1); } if (closeEnd(c1, 0, i, pt[0]) && closeEnd(c2, 1, i, pt[1]) && pt[0].approximatelyEqual(pt[1])) { i.removeOne(i.used() - 2); } return result; }
int SkIntersections::intersect(const SkDCubic& c1, const SkDCubic& c2) { ::intersect(c1, 0, 1, c2, 0, 1, 1, *this); // FIXME: pass in cached bounds from caller SkDRect c1Bounds, c2Bounds; c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ? c2Bounds.setBounds(c2); intersectEnd(c1, false, c2, c2Bounds, *this); intersectEnd(c1, true, c2, c2Bounds, *this); bool selfIntersect = &c1 == &c2; if (!selfIntersect) { swap(); intersectEnd(c2, false, c1, c1Bounds, *this); intersectEnd(c2, true, c1, c1Bounds, *this); swap(); } // If an end point and a second point very close to the end is returned, the second // point may have been detected because the approximate quads // intersected at the end and close to it. Verify that the second point is valid. if (fUsed <= 1 || coincidentUsed()) { return fUsed; } SkDPoint pt[2]; if (closeStart(c1, 0, *this, pt[0]) && closeStart(c2, 1, *this, pt[1]) && pt[0].approximatelyEqual(pt[1])) { removeOne(1); } if (closeEnd(c1, 0, *this, pt[0]) && closeEnd(c2, 1, *this, pt[1]) && pt[0].approximatelyEqual(pt[1])) { removeOne(used() - 2); } return fUsed; }
// FIXME: add intersection of convex null on cubics' ends with the opposite cubic. The hull line // segments can be constructed to be only as long as the calculated precision suggests. If the hull // line segments intersect the cubic, then use the intersections to construct a subdivision for // quadratic curve fitting. bool intersect2(const Cubic& c1, const Cubic& c2, Intersections& i) { #if SK_DEBUG debugDepth = 0; #endif bool result = intersect2(c1, 0, 1, c2, 0, 1, 1, i); // FIXME: pass in cached bounds from caller _Rect c1Bounds, c2Bounds; c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ? c2Bounds.setBounds(c2); result |= intersectEnd(c1, false, c2, c2Bounds, i); result |= intersectEnd(c1, true, c2, c2Bounds, i); i.swap(); result |= intersectEnd(c2, false, c1, c1Bounds, i); result |= intersectEnd(c2, true, c1, c1Bounds, i); i.swap(); return result; }