void CubicCoincidence_Test() {
    // split large quadratic
    // upscale quadratics to cubics
    // compare original, parts, to see if the are coincident
    for (size_t index = firstCubicCoincidenceTest; index < quadratics_count; ++index) {
        const Quadratic& test = quadratics[index];
        QuadraticPair split;
        chop_at(test, split, 0.5);
        Quadratic midThird;
        sub_divide(test, 1.0/3, 2.0/3, midThird);
        Cubic whole, first, second, mid;
        quad_to_cubic(test, whole);
        quad_to_cubic(split.first(), first);
        quad_to_cubic(split.second(), second);
        quad_to_cubic(midThird, mid);
        if (!implicit_matches(whole, first)) {
            printf("%s-1 %d\n", __FUNCTION__, (int)index);
        }
        if (!implicit_matches(whole, second)) {
            printf("%s-2 %d\n", __FUNCTION__, (int)index);
        }
        if (!implicit_matches(mid, first)) {
            printf("%s-3 %d\n", __FUNCTION__, (int)index);
        }
        if (!implicit_matches(mid, second)) {
            printf("%s-4 %d\n", __FUNCTION__, (int)index);
        }
        if (!implicit_matches(first, second)) {
            printf("%s-5 %d\n", __FUNCTION__, (int)index);
        }
    }
}
Exemple #2
0
bool intersect(const Quadratic& q1, const Quadratic& q2, Intersections& i) {
    if (implicit_matches(q1, q2)) {
        // FIXME: compute T values
        // compute the intersections of the ends to find the coincident span
        bool useVertical = fabs(q1[0].x - q1[2].x) < fabs(q1[0].y - q1[2].y);
        double t;
        if ((t = axialIntersect(q1, q2[0], useVertical)) >= 0) {
            i.addCoincident(t, 0);
        }
        if ((t = axialIntersect(q1, q2[2], useVertical)) >= 0) {
            i.addCoincident(t, 1);
        }
        useVertical = fabs(q2[0].x - q2[2].x) < fabs(q2[0].y - q2[2].y);
        if ((t = axialIntersect(q2, q1[0], useVertical)) >= 0) {
            i.addCoincident(0, t);
        }
        if ((t = axialIntersect(q2, q1[2], useVertical)) >= 0) {
            i.addCoincident(1, t);
        }
        assert(i.fCoincidentUsed <= 2);
        return i.fCoincidentUsed > 0;
    }
    QuadraticIntersections q(q1, q2, i);
    bool result = q.intersect();
    // FIXME: partial coincidence detection is currently poor. For now, try
    // to fix up the data after the fact. In the future, revisit the error
    // term to try to avoid this kind of result in the first place.
    if (i.fUsed && i.fCoincidentUsed) {
        hackToFixPartialCoincidence(q1, q2, i);
    }
    return result;
}
void CubicParameterization_Test() {
    for (size_t index = firstCubicParameterizationTest; index < cubics_count; ++index) {
        for (size_t inner = 0; inner < 4; inner += 3) {
            if (!point_on_parameterized_curve(cubics[index], cubics[index][inner])) {
                    printf("%s [%zu,%zu] 1 parameterization failed\n", 
                        __FUNCTION__, index, inner);
            }
            if (!point_on_parameterized_curve(cubics[index], cubics[index ^ 1][inner])) {
                    printf("%s [%zu,%zu] 2 parameterization failed\n",
                        __FUNCTION__, index, inner);
            }
        }
        if (!implicit_matches(cubics[index], cubics[index ^ 1])) {
            printf("%s %d\n", __FUNCTION__, (int)index);
        }
    }
}
Exemple #4
0
void CubicIntersection_Test() {
    for (size_t index = firstCubicIntersectionTest; 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);
        int order2 = reduceOrder(cubic2, reduce2, kReduceOrder_NoQuadraticsAllowed);
        if (order1 < 4) {
            printf("%s [%d] cubic1 order=%d\n", __FUNCTION__, (int) index, order1);
            continue;
        }
        if (order2 < 4) {
            printf("%s [%d] cubic2 order=%d\n", __FUNCTION__, (int) index, order2);
            continue;
        }
        if (implicit_matches(reduce1, reduce2)) {
            printf("%s [%d] coincident\n", __FUNCTION__, (int) index);
            continue;
        }
        Intersections tIntersections;
        intersect(reduce1, reduce2, tIntersections);
        if (!tIntersections.intersected()) {
            printf("%s [%d] no intersection\n", __FUNCTION__, (int) index);
            continue;
        }
        for (int pt = 0; pt < tIntersections.used(); ++pt) {
            double tt1 = tIntersections.fT[0][pt];
            double tx1, ty1;
            xy_at_t(cubic1, tt1, tx1, ty1);
            double tt2 = tIntersections.fT[1][pt];
            double tx2, ty2;
            xy_at_t(cubic2, tt2, tx2, ty2);
            if (!AlmostEqualUlps(tx1, tx2)) {
                printf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                    __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2);
            }
            if (!AlmostEqualUlps(ty1, ty2)) {
                printf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                    __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2);
            }
        }
    }
}