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;
}
Example #2
0
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;
}
Example #3
0
// 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;
}