Exemplo n.º 1
0
static void oneOffTest() {
    const Quadratic& quad1 = testSet[0];
    const Quadratic& quad2 = testSet[1];
    double minT = 0;
    double maxT = 1;
    bezier_clip(quad1, quad2, minT, maxT);
}
Exemplo n.º 2
0
static void oneAtEndTest() {
    const Quadratic& quad1 = testSet[2];
    const Quadratic& quad2 = testSet[3];
    double minT = 0;
    double maxT = 1;
    bezier_clip(quad1, quad2, minT, maxT);
}
Exemplo n.º 3
0
bool intersect() {
    double minT1, minT2, maxT1, maxT2;
    if (!bezier_clip(quad2, quad1, minT1, maxT1)) {
        return false;
    }
    if (!bezier_clip(quad1, quad2, minT2, maxT2)) {
        return false;
    }
    int split;
    if (maxT1 - minT1 < maxT2 - minT2) {
        intersections.swap();
        minT2 = 0;
        maxT2 = 1;
        split = maxT1 - minT1 > tClipLimit;
    } else {
        minT1 = 0;
        maxT1 = 1;
        split = (maxT2 - minT2 > tClipLimit) << 1;
    }
    return chop(minT1, maxT1, minT2, maxT2, split);
}
Exemplo n.º 4
0
static void standardTestCases() {
    for (size_t index = 0; index < quadraticTests_count; ++index) {
        const Quadratic& quad1 = quadraticTests[index][0];
        const Quadratic& quad2 = quadraticTests[index][1];
        Quadratic reduce1, reduce2;
        int order1 = reduceOrder(quad1, reduce1);
        int order2 = reduceOrder(quad2, reduce2);
        if (order1 < 3) {
            printf("%s [%d] quad1 order=%d\n", __FUNCTION__, (int)index, order1);
        }
        if (order2 < 3) {
            printf("%s [%d] quad2 order=%d\n", __FUNCTION__, (int)index, order2);
        }
        if (order1 == 3 && order2 == 3) {
            double minT = 0;
            double maxT = 1;
            bezier_clip(reduce1, reduce2, minT, maxT);
        }
    }
}
Exemplo n.º 5
0
void CubicBezierClip_Test() {
    for (size_t index = 0; index < tests_count; ++index) {
        const Cubic& cubic1 = tests[index][0];
        const Cubic& cubic2 = tests[index][1];
        Cubic reduce1, reduce2;
        int order1 = reduceOrder(cubic1, reduce1, kReduceOrder_NoQuadraticsAllowed,
                kReduceOrder_TreatAsFill);
        int order2 = reduceOrder(cubic2, reduce2, kReduceOrder_NoQuadraticsAllowed,
                kReduceOrder_TreatAsFill);
        if (order1 < 4) {
            SkDebugf("%s [%d] cubic1 order=%d\n", __FUNCTION__, (int) index, order1);
        }
        if (order2 < 4) {
            SkDebugf("%s [%d] cubic2 order=%d\n", __FUNCTION__, (int) index, order2);
        }
        if (order1 == 4 && order2 == 4) {
            double minT = 0;
            double maxT = 1;
            bezier_clip(reduce1, reduce2, minT, maxT);
        }
    }
}
Exemplo n.º 6
0
bool intersect(double minT1, double maxT1, double minT2, double maxT2) {
    bool t1IsLine = maxT1 - minT1 <= quad1Divisions;
    bool t2IsLine = maxT2 - minT2 <= quad2Divisions;
    if (t1IsLine | t2IsLine) {
        return intersectAsLine(minT1, maxT1, minT2, maxT2, t1IsLine, t2IsLine);
    }
    Quadratic smaller, larger;
    // FIXME: carry last subdivide and reduceOrder result with quad
    sub_divide(quad1, minT1, maxT1, intersections.swapped() ? larger : smaller);
    sub_divide(quad2, minT2, maxT2, intersections.swapped() ? smaller : larger);
    double minT, maxT;
    if (!bezier_clip(smaller, larger, minT, maxT)) {
        if (approximately_equal(minT, maxT)) {
            double smallT, largeT;
            _Point q2pt, q1pt;
            if (intersections.swapped()) {
                largeT = interp(minT2, maxT2, minT);
                xy_at_t(quad2, largeT, q2pt.x, q2pt.y);
                xy_at_t(quad1, minT1, q1pt.x, q1pt.y);
                if (AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y)) {
                    smallT = minT1;
                } else {
                    xy_at_t(quad1, maxT1, q1pt.x, q1pt.y); // FIXME: debug code
                    assert(AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y));
                    smallT = maxT1;
                }
            } else {
                smallT = interp(minT1, maxT1, minT);
                xy_at_t(quad1, smallT, q1pt.x, q1pt.y);
                xy_at_t(quad2, minT2, q2pt.x, q2pt.y);
                if (AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y)) {
                    largeT = minT2;
                } else {
                    xy_at_t(quad2, maxT2, q2pt.x, q2pt.y); // FIXME: debug code
                    assert(AlmostEqualUlps(q2pt.x, q1pt.x) && AlmostEqualUlps(q2pt.y, q1pt.y));
                    largeT = maxT2;
                }
            }
            intersections.add(smallT, largeT);
            return true;
        }
        return false;
    }
    int split;
    if (intersections.swapped()) {
        double newMinT1 = interp(minT1, maxT1, minT);
        double newMaxT1 = interp(minT1, maxT1, maxT);
        split = (newMaxT1 - newMinT1 > (maxT1 - minT1) * tClipLimit) << 1;
#define VERBOSE 0
#if VERBOSE
        printf("%s d=%d s=%d new1=(%g,%g) old1=(%g,%g) split=%d\n", __FUNCTION__, depth,
            splits, newMinT1, newMaxT1, minT1, maxT1, split);
#endif
        minT1 = newMinT1;
        maxT1 = newMaxT1;
    } else {
        double newMinT2 = interp(minT2, maxT2, minT);
        double newMaxT2 = interp(minT2, maxT2, maxT);
        split = newMaxT2 - newMinT2 > (maxT2 - minT2) * tClipLimit;
#if VERBOSE
        printf("%s d=%d s=%d new2=(%g,%g) old2=(%g,%g) split=%d\n", __FUNCTION__, depth,
            splits, newMinT2, newMaxT2, minT2, maxT2, split);
#endif
        minT2 = newMinT2;
        maxT2 = newMaxT2;
    }
    return chop(minT1, maxT1, minT2, maxT2, split);
}
Exemplo n.º 7
0
bool intersect(double minT1, double maxT1, double minT2, double maxT2) {
    Quadratic smaller, larger;
    // FIXME: carry last subdivide and reduceOrder result with quad 
    sub_divide(quad1, minT1, maxT1, intersections.swapped() ? larger : smaller);
    sub_divide(quad2, minT2, maxT2, intersections.swapped() ? smaller : larger);
    Quadratic smallResult;
    if (reduceOrder(smaller, smallResult) <= 2) {
        Quadratic largeResult;
        if (reduceOrder(larger, largeResult) <= 2) {
            double smallT[2], largeT[2];
            const _Line& smallLine = (const _Line&) smallResult;
            const _Line& largeLine = (const _Line&) largeResult;
            // FIXME: this doesn't detect or deal with coincident lines
            if (!::intersect(smallLine, largeLine, smallT, largeT)) {
                return false;
            }
            if (intersections.swapped()) {
                smallT[0] = interp(minT2, maxT2, smallT[0]); 
                largeT[0] = interp(minT1, maxT1, largeT[0]); 
            } else {
                smallT[0] = interp(minT1, maxT1, smallT[0]); 
                largeT[0] = interp(minT2, maxT2, largeT[0]); 
            }
            intersections.add(smallT[0], largeT[0]);
            return true;
        }
    }
    double minT, maxT;
    if (!bezier_clip(smaller, larger, minT, maxT)) {
        if (minT == maxT) {
            if (intersections.swapped()) {
                minT1 = (minT1 + maxT1) / 2;
                minT2 = interp(minT2, maxT2, minT);
            } else {
                minT1 = interp(minT1, maxT1, minT);
                minT2 = (minT2 + maxT2) / 2;
            }
            intersections.add(minT1, minT2);
            return true;
        }
        return false;
    }
    
    int split;
    if (intersections.swapped()) {
        double newMinT1 = interp(minT1, maxT1, minT);
        double newMaxT1 = interp(minT1, maxT1, maxT);
        split = (newMaxT1 - newMinT1 > (maxT1 - minT1) * tClipLimit) << 1;
#define VERBOSE 0
#if VERBOSE
        printf("%s d=%d s=%d new1=(%g,%g) old1=(%g,%g) split=%d\n", __FUNCTION__, depth,
            splits, newMinT1, newMaxT1, minT1, maxT1, split);
#endif
        minT1 = newMinT1;
        maxT1 = newMaxT1;
    } else {
        double newMinT2 = interp(minT2, maxT2, minT);
        double newMaxT2 = interp(minT2, maxT2, maxT);
        split = newMaxT2 - newMinT2 > (maxT2 - minT2) * tClipLimit;
#define VERBOSE 0
#if VERBOSE
        printf("%s d=%d s=%d new2=(%g,%g) old2=(%g,%g) split=%d\n", __FUNCTION__, depth,
            splits, newMinT2, newMaxT2, minT2, maxT2, split);
#endif
        minT2 = newMinT2;
        maxT2 = newMaxT2;
    }
    return chop(minT1, maxT1, minT2, maxT2, split);
}