コード例 #1
0
ファイル: 05.13.cpp プロジェクト: walrus7521/code
int main()
{
    rect a = {4,4,10,17};
    rect b = {2,2,22,22};
    rect c = {2,14,11,11};
    rect d = {11,2,12,12};
    rect e = {7,10,8,8};
    show(a);
    printf("intersect: %d\n", intersect2(a, b));
    printf("intersect: %d\n", intersect2(a, c));
    printf("intersect: %d\n", intersect2(a, d));
    printf("intersect: %d\n", intersect2(a, e));
    rect *r = min_rect(a, b);
    show(*r);
}
コード例 #2
0
ファイル: CubicIntersection_Test.cpp プロジェクト: Cue/skia
bool intersect(double minT1, double maxT1, double minT2, double maxT2) {
    Cubic sub1, sub2;
    // FIXME: carry last subdivide and reduceOrder result with cubic
    sub_divide(cubic1, minT1, maxT1, sub1);
    sub_divide(cubic2, minT2, maxT2, sub2);
    Intersections i;
    intersect2(sub1, sub2, i);
    if (i.used() == 0) {
        return false;
    }
    double x1, y1, x2, y2;
    t1 = minT1 + i.fT[0][0] * (maxT1 - minT1);
    t2 = minT2 + i.fT[1][0] * (maxT2 - minT2);
    xy_at_t(cubic1, t1, x1, y1);
    xy_at_t(cubic2, t2, x2, y2);
    if (AlmostEqualUlps(x1, x2) && AlmostEqualUlps(y1, y2)) {
        return true;
    }
    double half1 = (minT1 + maxT1) / 2;
    double half2 = (minT2 + maxT2) / 2;
    ++depth;
    bool result;
    if (depth & 1) {
        result = intersect(minT1, half1, minT2, maxT2) || intersect(half1, maxT1, minT2, maxT2)
            || intersect(minT1, maxT1, minT2, half2) || intersect(minT1, maxT1, half2, maxT2);
    } else {
        result = intersect(minT1, maxT1, minT2, half2) || intersect(minT1, maxT1, half2, maxT2)
            || intersect(minT1, half1, minT2, maxT2) || intersect(half1, maxT1, minT2, maxT2);
    }
    --depth;
    return result;
}
コード例 #3
0
static void oneOffTest() {
    for (size_t outer = 0; outer < testSetCount - 1; ++outer) {
        for (size_t inner = outer + 1; inner < testSetCount; ++inner) {
            const Quadratic& quad1 = testSet[outer];
            const Quadratic& quad2 = testSet[inner];
            double tt1, tt2;
            Intersections intersections2;
            intersect2(quad1, quad2, intersections2);
            for (int pt = 0; pt < intersections2.used(); ++pt) {
                tt1 = intersections2.fT[0][pt];
                double tx1, ty1;
                xy_at_t(quad1, tt1, tx1, ty1);
                int pt2 = intersections2.fFlip ? intersections2.used() - pt - 1 : pt;
                tt2 = intersections2.fT[1][pt2];
                double tx2, ty2;
                xy_at_t(quad2, tt2, tx2, ty2);
                if (!approximately_equal(tx1, tx2)) {
                    SkDebugf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                        __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2);
                    SkASSERT(0);
                }
                if (!approximately_equal(ty1, ty2)) {
                    SkDebugf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                        __FUNCTION__, (int)index, pt, tt1, tx1, ty1, tt2, tx2, ty2);
                    SkASSERT(0);
                }
                SkDebugf("%s [%d][%d] t1=%1.9g (%1.9g, %1.9g) t2=%1.9g\n", __FUNCTION__,
                    outer, inner, tt1, tx1, tx2, tt2);
            }
        }
    }
}
コード例 #4
0
static void oneOffTest1(size_t outer, size_t inner) {
    const Quadratic& quad1 = testSet[outer];
    const Quadratic& quad2 = testSet[inner];
    Intersections intersections2;
    intersect2(quad1, quad2, intersections2);
    if (intersections2.fUnsortable) {
        SkASSERT(0);
        return;
    }
    for (int pt = 0; pt < intersections2.used(); ++pt) {
        double tt1 = intersections2.fT[0][pt];
        double tx1, ty1;
        xy_at_t(quad1, tt1, tx1, ty1);
        int pt2 = intersections2.fFlip ? intersections2.used() - pt - 1 : pt;
        double tt2 = intersections2.fT[1][pt2];
        double tx2, ty2;
        xy_at_t(quad2, tt2, tx2, ty2);
        if (!AlmostEqualUlps(tx1, tx2)) {
            SkDebugf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                __FUNCTION__, (int)outer, (int)inner, tt1, tx1, ty1, tt2, tx2, ty2);
            SkASSERT(0);
        }
        if (!AlmostEqualUlps(ty1, ty2)) {
            SkDebugf("%s [%d,%d] y!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
                __FUNCTION__, (int)outer, (int)inner, tt1, tx1, ty1, tt2, tx2, ty2);
            SkASSERT(0);
        }
#if ONE_OFF_DEBUG
        SkDebugf("%s [%d][%d] t1=%1.9g (%1.9g, %1.9g) t2=%1.9g\n", __FUNCTION__,
            outer, inner, tt1, tx1, tx2, tt2);
#endif
    }
}
コード例 #5
0
ファイル: Ray.cpp プロジェクト: vuhonganh/projet3D
bool Ray::intersect_remake(Vec3f * triangle, Vec3f &result)
{
    Vec3f o = this->position;
    Vec3f w = this->direction;

    if(intersect2(triangle, o, w, result))
        return true;
    return false;
}
コード例 #6
0
ファイル: CubicIntersection_Test.cpp プロジェクト: Cue/skia
void CubicIntersection_RandTest() {
    srand(0);
    const int tests = 10000000;
    for (int test = 0; test < tests; ++test) {
        Cubic cubic1, cubic2;
        for (int i = 0; i < 4; ++i) {
            cubic1[i].x = (double) rand() / RAND_MAX * 100;
            cubic1[i].y = (double) rand() / RAND_MAX * 100;
            cubic2[i].x = (double) rand() / RAND_MAX * 100;
            cubic2[i].y = (double) rand() / RAND_MAX * 100;
        }
    #if DEBUG_CRASH
        char str[1024];
        sprintf(str, "{{%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}},\n"
            "{{%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}},\n",
                cubic1[0].x, cubic1[0].y,  cubic1[1].x, cubic1[1].y, cubic1[2].x, cubic1[2].y,
                cubic1[3].x, cubic1[3].y,
                cubic2[0].x, cubic2[0].y,  cubic2[1].x, cubic2[1].y, cubic2[2].x, cubic2[2].y,
                cubic2[3].x, cubic2[3].y);
    #endif
        _Rect rect1, rect2;
        rect1.setBounds(cubic1);
        rect2.setBounds(cubic2);
        bool boundsIntersect = rect1.left <= rect2.right && rect2.left <= rect2.right
                && rect1.top <= rect2.bottom && rect2.top <= rect1.bottom;
        if (test == -1) {
            SkDebugf("ready...\n");
        }
        Intersections intersections2;
        bool newIntersects = intersect2(cubic1, cubic2, intersections2);
        if (!boundsIntersect && newIntersects) {
            SkDebugf("%s %d unexpected intersection boundsIntersect=%d "
                    " newIntersects=%d\n%s %s\n", __FUNCTION__, test, boundsIntersect,
                    newIntersects, __FUNCTION__, str);
            assert(0);
        }
        for (int pt = 0; pt < intersections2.used(); ++pt) {
            double tt1 = intersections2.fT[0][pt];
            _Point xy1, xy2;
            xy_at_t(cubic1, tt1, xy1.x, xy1.y);
            int pt2 = intersections2.fFlip ? intersections2.used() - pt - 1 : pt;
            double tt2 = intersections2.fT[1][pt2];
            xy_at_t(cubic2, tt2, xy2.x, xy2.y);
        #if 0
            SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g) t2=%1.9g\n", __FUNCTION__,
                tt1, xy1.x, xy1.y, xy2.x, xy2.y, tt2);
        #endif
            assert(xy1.approximatelyEqual(xy2));
        }
    }
}
コード例 #7
0
static void coincidentTest() {
    for (size_t testIndex = 0; testIndex < coincidentTestSetCount - 1; testIndex += 2) {
        const Quadratic& quad1 = coincidentTestSet[testIndex];
        const Quadratic& quad2 = coincidentTestSet[testIndex + 1];
        Intersections intersections2;
        intersect2(quad1, quad2, intersections2);
        SkASSERT(intersections2.coincidentUsed() == 2);
        for (int pt = 0; pt < intersections2.coincidentUsed(); ++pt) {
            double tt1 = intersections2.fT[0][pt];
            double tt2 = intersections2.fT[1][pt];
            SkASSERT(approximately_equal(1, tt1) || approximately_zero(tt1));
            SkASSERT(approximately_equal(1, tt2) || approximately_zero(tt2));
        }
    }
}
コード例 #8
0
ファイル: CubicIntersection.cpp プロジェクト: Cue/skia
static bool intersectEnd(const Cubic& cubic1, bool start, const Cubic& cubic2, const _Rect& bounds2,
        Intersections& i) {
    _Line line1;
    line1[0] = line1[1] = cubic1[start ? 0 : 3];
    _Point dxy1 = line1[0] - cubic1[start ? 1 : 2];
    dxy1 /= precisionUnit;
    line1[1] += dxy1;
    _Rect line1Bounds;
    line1Bounds.setBounds(line1);
    if (!bounds2.intersects(line1Bounds)) {
        return false;
    }
    _Line line2;
    line2[0] = line2[1] = line1[0];
    _Point dxy2 = line2[0] - cubic1[start ? 3 : 0];
    dxy2 /= precisionUnit;
    line2[1] += dxy2;
#if 0 // this is so close to the first bounds test it isn't worth the short circuit test
    _Rect line2Bounds;
    line2Bounds.setBounds(line2);
    if (!bounds2.intersects(line2Bounds)) {
        return false;
    }
#endif
    Intersections local1;
    if (!intersect(cubic2, line1, local1)) {
        return false;
    }
    Intersections local2;
    if (!intersect(cubic2, line2, local2)) {
        return false;
    }
    double tMin, tMax;
    tMin = tMax = local1.fT[0][0];
    for (int index = 1; index < local1.fUsed; ++index) {
        tMin = std::min(tMin, local1.fT[0][index]);
        tMax = std::max(tMax, local1.fT[0][index]);
    }
    for (int index = 1; index < local2.fUsed; ++index) {
        tMin = std::min(tMin, local2.fT[0][index]);
        tMax = std::max(tMax, local2.fT[0][index]);
    }
#if SK_DEBUG
    debugDepth = 0;
#endif
    return intersect2(cubic1, start ? 0 : 1, start ? 1.0 / precisionUnit : 1 - 1.0 / precisionUnit,
            cubic2, tMin, tMax, 1, i);
}
コード例 #9
0
static void intersectWithOrder(const Quadratic& simple1, int order1, const Quadratic& simple2,
        int order2, Intersections& i) {
    if (order1 == 3 && order2 == 3) {
        intersect2(simple1, simple2, i);
    } else if (order1 <= 2 && order2 <= 2) {
        intersect((const _Line&) simple1, (const _Line&) simple2, i);
    } else if (order1 == 3 && order2 <= 2) {
        intersect(simple1, (const _Line&) simple2, i);
    } else {
        SkASSERT(order1 <= 2 && order2 == 3);
        intersect(simple2, (const _Line&) simple1, i);
        for (int s = 0; s < i.fUsed; ++s) {
            SkTSwap(i.fT[0][s], i.fT[1][s]);
        }
    }
}
コード例 #10
0
ファイル: CubicIntersection.cpp プロジェクト: Cue/skia
// 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;
}
コード例 #11
0
static void standardTestCases() {
    for (size_t index = firstQuadIntersectionTest; 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("[%d] quad1 order=%d\n", (int) index, order1);
        }
        if (order2 < 3) {
            printf("[%d] quad2 order=%d\n", (int) index, order2);
        }
        if (order1 == 3 && order2 == 3) {
            Intersections intersections, intersections2;
            intersect(reduce1, reduce2, intersections);
            intersect2(reduce1, reduce2, intersections2);
            SkASSERT(intersections.used() == intersections2.used());
            if (intersections.intersected()) {
                for (int pt = 0; pt < intersections.used(); ++pt) {
                    double tt1 = intersections.fT[0][pt];
                    double tx1, ty1;
                    xy_at_t(quad1, tt1, tx1, ty1);
                    double tt2 = intersections.fT[1][pt];
                    double tx2, ty2;
                    xy_at_t(quad2, tt2, tx2, ty2);
                    if (!approximately_equal(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 (!approximately_equal(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);
                    }
                    tt1 = intersections2.fT[0][pt];
                    SkASSERT(approximately_equal(intersections.fT[0][pt], tt1));
                    tt2 = intersections2.fT[1][pt];
                    SkASSERT(approximately_equal(intersections.fT[1][pt], tt2));
                }
            }
        }
    }
}
コード例 #12
0
ファイル: CubicIntersection.cpp プロジェクト: Cue/skia
bool intersect(const Cubic& cubic, Intersections& i) {
    SkTDArray<double> ts;
    double precision = calcPrecision(cubic);
    cubic_to_quadratics(cubic, precision, ts);
    int tsCount = ts.count();
    if (tsCount == 1) {
        return false;
    }
    double t1Start = 0;
    Cubic part;
    for (int idx = 0; idx < tsCount; ++idx) {
        double t1 = ts[idx];
        Quadratic q1;
        sub_divide(cubic, t1Start, t1, part);
        demote_cubic_to_quad(part, q1);
        double t2Start = t1;
        for (int i2 = idx + 1; i2 <= tsCount; ++i2) {
            const double t2 = i2 < tsCount ? ts[i2] : 1;
            Quadratic q2;
            sub_divide(cubic, t2Start, t2, part);
            demote_cubic_to_quad(part, q2);
            Intersections locals;
            intersect2(q1, q2, locals);
            for (int tIdx = 0; tIdx < locals.used(); ++tIdx) {
            // discard intersections at cusp? (maximum curvature)
                double t1sect = locals.fT[0][tIdx];
                double t2sect = locals.fT[1][tIdx];
                if (idx + 1 == i2 && t1sect == 1 && t2sect == 0) {
                    continue;
                }
                double to1 = t1Start + (t1 - t1Start) * t1sect;
                double to2 = t2Start + (t2 - t2Start) * t2sect;
                i.insert(to1, to2);
            }
            t2Start = t2;
        }
        t1Start = t1;
    }
    return i.intersected();
}
コード例 #13
0
ファイル: CubicIntersection_Test.cpp プロジェクト: Cue/skia
static void oneOff(const Cubic& cubic1, const Cubic& cubic2) {
    SkTDArray<Quadratic> quads1;
    cubic_to_quadratics(cubic1, calcPrecision(cubic1), quads1);
#if ONE_OFF_DEBUG
    for (int index = 0; index < quads1.count(); ++index) {
        const Quadratic& q = quads1[index];
        SkDebugf("  {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", q[0].x, q[0].y,
                 q[1].x, q[1].y,  q[2].x, q[2].y);
    }
    SkDebugf("\n");
#endif
    SkTDArray<Quadratic> quads2;
    cubic_to_quadratics(cubic2, calcPrecision(cubic2), quads2);
#if ONE_OFF_DEBUG
    for (int index = 0; index < quads2.count(); ++index) {
        const Quadratic& q = quads2[index];
        SkDebugf("  {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", q[0].x, q[0].y,
                 q[1].x, q[1].y,  q[2].x, q[2].y);
    }
    SkDebugf("\n");
#endif
    Intersections intersections2;
    intersect2(cubic1, cubic2, intersections2);
    for (int pt = 0; pt < intersections2.used(); ++pt) {
        double tt1 = intersections2.fT[0][pt];
        _Point xy1, xy2;
        xy_at_t(cubic1, tt1, xy1.x, xy1.y);
        int pt2 = intersections2.fFlip ? intersections2.used() - pt - 1 : pt;
        double tt2 = intersections2.fT[1][pt2];
        xy_at_t(cubic2, tt2, xy2.x, xy2.y);
#if ONE_OFF_DEBUG
        SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g) t2=%1.9g\n", __FUNCTION__,
            tt1, xy1.x, xy1.y, xy2.x, xy2.y, tt2);
#endif
        assert(xy1.approximatelyEqual(xy2));
    }
}
コード例 #14
0
ファイル: CubicIntersection.cpp プロジェクト: Cue/skia
int intersect(const Cubic& cubic, const Quadratic& quad, Intersections& i) {
    SkTDArray<double> ts;
    double precision = calcPrecision(cubic);
    cubic_to_quadratics(cubic, precision, ts);
    double tStart = 0;
    Cubic part;
    int tsCount = ts.count();
    for (int idx = 0; idx <= tsCount; ++idx) {
        double t = idx < tsCount ? ts[idx] : 1;
        Quadratic q1;
        sub_divide(cubic, tStart, t, part);
        demote_cubic_to_quad(part, q1);
        Intersections locals;
        intersect2(q1, quad, locals);
        for (int tIdx = 0; tIdx < locals.used(); ++tIdx) {
            double globalT = tStart + (t - tStart) * locals.fT[0][tIdx];
            i.insertOne(globalT, 0);
            globalT = locals.fT[1][tIdx];
            i.insertOne(globalT, 1);
        }
        tStart = t;
    }
    return i.used();
}
コード例 #15
0
ファイル: CubicIntersection.cpp プロジェクト: Cue/skia
// this flavor approximates the cubics with quads to find the intersecting ts
// OPTIMIZE: if this strategy proves successful, the quad approximations, or the ts used
// to create the approximations, could be stored in the cubic segment
// FIXME: this strategy needs to intersect the convex hull on either end with the opposite to
// account for inset quadratics that cause the endpoint intersection to avoid detection
// the segments can be very short -- the length of the maximum quadratic error (precision)
// FIXME: this needs to recurse on itself, taking a range of T values and computing the new
// t range ala is linear inner. The range can be figured by taking the dx/dy and determining
// the fraction that matches the precision. That fraction is the change in t for the smaller cubic.
static bool intersect2(const Cubic& cubic1, double t1s, double t1e, const Cubic& cubic2,
        double t2s, double t2e, double precisionScale, Intersections& i) {
    Cubic c1, c2;
    sub_divide(cubic1, t1s, t1e, c1);
    sub_divide(cubic2, t2s, t2e, c2);
    SkTDArray<double> ts1;
    cubic_to_quadratics(c1, calcPrecision(c1) * precisionScale, ts1);
    SkTDArray<double> ts2;
    cubic_to_quadratics(c2, calcPrecision(c2) * precisionScale, ts2);
    double t1Start = t1s;
    int ts1Count = ts1.count();
    for (int i1 = 0; i1 <= ts1Count; ++i1) {
        const double tEnd1 = i1 < ts1Count ? ts1[i1] : 1;
        const double t1 = t1s + (t1e - t1s) * tEnd1;
        Cubic part1;
        sub_divide(cubic1, t1Start, t1, part1);
        Quadratic q1;
        demote_cubic_to_quad(part1, q1);
  //      start here;
        // should reduceOrder be looser in this use case if quartic is going to blow up on an
        // extremely shallow quadratic?
        Quadratic s1;
        int o1 = reduceOrder(q1, s1);
        double t2Start = t2s;
        int ts2Count = ts2.count();
        for (int i2 = 0; i2 <= ts2Count; ++i2) {
            const double tEnd2 = i2 < ts2Count ? ts2[i2] : 1;
            const double t2 = t2s + (t2e - t2s) * tEnd2;
            Cubic part2;
            sub_divide(cubic2, t2Start, t2, part2);
            Quadratic q2;
            demote_cubic_to_quad(part2, q2);
            Quadratic s2;
            double o2 = reduceOrder(q2, s2);
            Intersections locals;
            if (o1 == 3 && o2 == 3) {
                intersect2(q1, q2, locals);
            } else if (o1 <= 2 && o2 <= 2) {
                locals.fUsed = intersect((const _Line&) s1, (const _Line&) s2, locals.fT[0],
                        locals.fT[1]);
            } else if (o1 == 3 && o2 <= 2) {
                intersect(q1, (const _Line&) s2, locals);
            } else {
                SkASSERT(o1 <= 2 && o2 == 3);
                intersect(q2, (const _Line&) s1, locals);
                for (int s = 0; s < locals.fUsed; ++s) {
                    SkTSwap(locals.fT[0][s], locals.fT[1][s]);
                }
            }
            for (int tIdx = 0; tIdx < locals.used(); ++tIdx) {
                double to1 = t1Start + (t1 - t1Start) * locals.fT[0][tIdx];
                double to2 = t2Start + (t2 - t2Start) * locals.fT[1][tIdx];
    // if the computed t is not sufficiently precise, iterate
                _Point p1, p2;
                xy_at_t(cubic1, to1, p1.x, p1.y);
                xy_at_t(cubic2, to2, p2.x, p2.y);
                if (p1.approximatelyEqual(p2)) {
                    i.insert(i.swapped() ? to2 : to1, i.swapped() ? to1 : to2);
                } else {
                    double dt1, dt2;
                    computeDelta(cubic1, to1, (t1e - t1s), cubic2, to2, (t2e - t2s), dt1, dt2);
                    double scale = precisionScale;
                    if (dt1 > 0.125 || dt2 > 0.125) {
                        scale /= 2;
                        SkDebugf("%s scale=%1.9g\n", __FUNCTION__, scale);
                    }
#if SK_DEBUG
                    ++debugDepth;
                    assert(debugDepth < 10);
#endif
                    i.swap();
                    intersect2(cubic2, SkTMax(to2 - dt2, 0.), SkTMin(to2 + dt2, 1.),
                            cubic1, SkTMax(to1 - dt1, 0.), SkTMin(to1 + dt1, 1.), scale, i);
                    i.swap();
#if SK_DEBUG
                    --debugDepth;
#endif
                }
            }
            t2Start = t2;
        }
        t1Start = t1;
    }
    return i.intersected();
}
コード例 #16
0
ファイル: CubicIntersection_Test.cpp プロジェクト: Cue/skia
void CubicIntersection_RandTestOld() {
    srand(0);
    const int tests = 1000000; // 10000000;
    double largestFactor = DBL_MAX;
    for (int test = 0; test < tests; ++test) {
        Cubic cubic1, cubic2;
        for (int i = 0; i < 4; ++i) {
            cubic1[i].x = (double) rand() / RAND_MAX * 100;
            cubic1[i].y = (double) rand() / RAND_MAX * 100;
            cubic2[i].x = (double) rand() / RAND_MAX * 100;
            cubic2[i].y = (double) rand() / RAND_MAX * 100;
        }
        if (test == 2513) { // the pair crosses three times, but the quadratic approximation
            continue; // only sees one -- should be OK to ignore the other two?
        }
        if (test == 12932) { // this exposes a weakness when one cubic touches the other but
            continue; // does not touch the quad approximation. Captured in qc.htm as cubic15
        }
    #if DEBUG_CRASH
        char str[1024];
        sprintf(str, "{{%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}},\n"
            "{{%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}, {%1.9g, %1.9g}},\n",
                cubic1[0].x, cubic1[0].y,  cubic1[1].x, cubic1[1].y, cubic1[2].x, cubic1[2].y,
                cubic1[3].x, cubic1[3].y,
                cubic2[0].x, cubic2[0].y,  cubic2[1].x, cubic2[1].y, cubic2[2].x, cubic2[2].y,
                cubic2[3].x, cubic2[3].y);
    #endif
        _Rect rect1, rect2;
        rect1.setBounds(cubic1);
        rect2.setBounds(cubic2);
        bool boundsIntersect = rect1.left <= rect2.right && rect2.left <= rect2.right
                && rect1.top <= rect2.bottom && rect2.top <= rect1.bottom;
        Intersections i1, i2;
    #if TRY_OLD
        bool oldIntersects = intersect(cubic1, cubic2, i1);
    #else
        bool oldIntersects = false;
    #endif
        if (test == -1) {
            SkDebugf("ready...\n");
        }
        bool newIntersects = intersect2(cubic1, cubic2, i2);
        if (!boundsIntersect && (oldIntersects || newIntersects)) {
            SkDebugf("%s %d unexpected intersection boundsIntersect=%d oldIntersects=%d"
                    " newIntersects=%d\n%s %s\n", __FUNCTION__, test, boundsIntersect,
                    oldIntersects, newIntersects, __FUNCTION__, str);
            assert(0);
        }
        if (oldIntersects && !newIntersects) {
            SkDebugf("%s %d missing intersection oldIntersects=%d newIntersects=%d\n%s %s\n",
                    __FUNCTION__, test, oldIntersects, newIntersects, __FUNCTION__, str);
            assert(0);
        }
        if (!oldIntersects && !newIntersects) {
            continue;
        }
        if (i2.used() > 1) {
            continue;
            // just look at single intercepts for simplicity
        }
        Intersections self1, self2; // self-intersect checks
        if (intersect(cubic1, self1)) {
            continue;
        }
        if (intersect(cubic2, self2)) {
            continue;
        }
        // binary search for range necessary to enclose real intersection
        CubicChopper c(cubic1, cubic2);
        bool result = c.intersect(0, 1, 0, 1);
        if (!result) {
            // FIXME: a failure here probably means that a core routine used by CubicChopper is failing
            continue;
        }
        double delta1 = fabs(c.t1 - i2.fT[0][0]);
        double delta2 = fabs(c.t2 - i2.fT[1][0]);
        double calc1 = calcPrecision(cubic1);
        double calc2 = calcPrecision(cubic2);
        double factor1 = calc1 / delta1;
        double factor2 = calc2 / delta2;
        SkDebugf("%s %d calc1=%1.9g delta1=%1.9g factor1=%1.9g calc2=%1.9g delta2=%1.9g"
                " factor2=%1.9g\n", __FUNCTION__, test,
                calc1, delta1, factor1, calc2, delta2, factor2);
        if (factor1 < largestFactor) {
            SkDebugf("WE HAVE A WINNER! %1.9g\n", factor1);
            SkDebugf("%s\n", str);
            oneOff(cubic1, cubic2);
            largestFactor = factor1;
        }
        if (factor2 < largestFactor) {
            SkDebugf("WE HAVE A WINNER! %1.9g\n", factor2);
            SkDebugf("%s\n", str);
            oneOff(cubic1, cubic2);
            largestFactor = factor2;
        }
    }
}
コード例 #17
0
ファイル: BSPTree.cpp プロジェクト: jeppewalther/GEL
 inline void IntersectAlltrianglesInLeaf(const BSPLeaf* leaf, Ray &ray, double t_max) {
   TriAccel** tri_acc_ptr = reinterpret_cast<TriAccel**>(leaf->flagAndOffset & (0x7FFFFFFF));
   for(unsigned int i = 0; i < leaf->count; ++i)
     intersect2(ray, *(*tri_acc_ptr + i), t_max);
 }