Exemplo n.º 1
0
SkDQuadPair SkDQuad::chopAt(double t) const
{
    SkDQuadPair dst;
    interp_quad_coords(&fPts[0].fX, &dst.pts[0].fX, t);
    interp_quad_coords(&fPts[0].fY, &dst.pts[0].fY, t);
    return dst;
}
void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t)
{
    SkASSERT(t > 0 && t < SK_Scalar1);

    interp_quad_coords(&src[0].fX, &dst[0].fX, t);
    interp_quad_coords(&src[0].fY, &dst[0].fY, t);
}
Exemplo n.º 3
0
static int check_linear(const Quadratic& quad, Quadratic& reduction,
        int minX, int maxX, int minY, int maxY) {
    int startIndex = 0;
    int endIndex = 2;
    while (quad[startIndex].approximatelyEqual(quad[endIndex])) {
        --endIndex;
        if (endIndex == 0) {
            printf("%s shouldn't get here if all four points are about equal", __FUNCTION__);
            assert(0);
        }
    }
    if (!isLinear(quad, startIndex, endIndex)) {
        return 0;
    }
    // four are colinear: return line formed by outside
    reduction[0] = quad[0];
    reduction[1] = quad[2];
    int sameSide;
    bool useX = quad[maxX].x - quad[minX].x >= quad[maxY].y - quad[minY].y;
    if (useX) {
        sameSide = sign(quad[0].x - quad[1].x) + sign(quad[2].x - quad[1].x);
    } else {
        sameSide = sign(quad[0].y - quad[1].y) + sign(quad[2].y - quad[1].y);
    }
    if ((sameSide & 3) != 2) {
        return 2;
    }
    double tValue;
    int root;
    if (useX) {
        root = findExtrema(quad[0].x, quad[1].x, quad[2].x, &tValue);
    } else {
        root = findExtrema(quad[0].y, quad[1].y, quad[2].y, &tValue);
    }
    if (root) {
        _Point extrema;
        extrema.x = interp_quad_coords(quad[0].x, quad[1].x, quad[2].x, tValue);
        extrema.y = interp_quad_coords(quad[0].x, quad[1].x, quad[2].x, tValue);
        // sameSide > 0 means mid is smaller than either [0] or [2], so replace smaller
        int replace;
        if (useX) {
            if (extrema.x < quad[0].x ^ extrema.x < quad[2].x) {
                return 2;
            }
            replace = (extrema.x < quad[0].x | extrema.x < quad[2].x)
                    ^ (quad[0].x < quad[2].x);
        } else {
            if (extrema.y < quad[0].y ^ extrema.y < quad[2].y) {
                return 2;
            }
            replace = (extrema.y < quad[0].y | extrema.y < quad[2].y)
                    ^ (quad[0].y < quad[2].y);
        }
        reduction[replace] = extrema;
    }
    return 2;
}
Exemplo n.º 4
0
SkDPoint SkDQuad::subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2) const {
    SkASSERT(t1 != t2);
    SkDPoint b;
#if 0
    // this approach assumes that the control point computed directly is accurate enough
    double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2);
    double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2);
    b.fX = 2 * dx - (a.fX + c.fX) / 2;
    b.fY = 2 * dy - (a.fY + c.fY) / 2;
#else
    SkDQuad sub = subDivide(t1, t2);
    SkDLine b0 = {{a, sub[1] + (a - sub[0])}};
    SkDLine b1 = {{c, sub[1] + (c - sub[2])}};
    SkIntersections i;
    i.intersectRay(b0, b1);
    if (i.used() == 1 && i[0][0] >= 0 && i[1][0] >= 0) {
        b = i.pt(0);
    } else {
        SkASSERT(i.used() <= 2);
        b = SkDPoint::Mid(b0[1], b1[1]);
    }
#endif
    if (t1 == 0 || t2 == 0) {
        align(0, &b);
    }
    if (t1 == 1 || t2 == 1) {
        align(2, &b);
    }
    if (AlmostBequalUlps(b.fX, a.fX)) {
        b.fX = a.fX;
    } else if (AlmostBequalUlps(b.fX, c.fX)) {
        b.fX = c.fX;
    }
    if (AlmostBequalUlps(b.fY, a.fY)) {
        b.fY = a.fY;
    } else if (AlmostBequalUlps(b.fY, c.fY)) {
        b.fY = c.fY;
    }
    return b;
}
Exemplo n.º 5
0
static int horizontal_line(const Quadratic& quad, Quadratic& reduction) {
    double tValue;
    reduction[0] = quad[0];
    reduction[1] = quad[2];
    int smaller = reduction[1].x > reduction[0].x;
    int larger = smaller ^ 1;
    if (findExtrema(quad[0].x, quad[1].x, quad[2].x, &tValue)) {
        double xExtrema = interp_quad_coords(quad[0].x, quad[1].x, quad[2].x, tValue);
        if (reduction[smaller].x > xExtrema) {
            reduction[smaller].x = xExtrema;
        }  else if (reduction[larger].x < xExtrema) {
            reduction[larger].x = xExtrema;
        }
    }
    return 2;
}
Exemplo n.º 6
0
static int vertical_line(const Quadratic& quad, Quadratic& reduction) {
    double tValue;
    reduction[0] = quad[0];
    reduction[1] = quad[2];
    int smaller = reduction[1].y > reduction[0].y;
    int larger = smaller ^ 1;
    if (findExtrema(quad[0].y, quad[1].y, quad[2].y, &tValue)) {
        double yExtrema = interp_quad_coords(quad[0].y, quad[1].y, quad[2].y, tValue);
        if (reduction[smaller].y > yExtrema) {
            reduction[smaller].y = yExtrema;
        } else if (reduction[larger].y < yExtrema) {
            reduction[larger].y = yExtrema;
        }
    }
    return 2;
}
Exemplo n.º 7
0
// OPTIMIZE : special case either or both of t1 = 0, t2 = 1 
SkDQuad SkDQuad::subDivide(double t1, double t2) const {
    SkDQuad dst;
    double ax = dst[0].fX = interp_quad_coords(&fPts[0].fX, t1);
    double ay = dst[0].fY = interp_quad_coords(&fPts[0].fY, t1);
    double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2);
    double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2);
    double cx = dst[2].fX = interp_quad_coords(&fPts[0].fX, t2);
    double cy = dst[2].fY = interp_quad_coords(&fPts[0].fY, t2);
    /* bx = */ dst[1].fX = 2 * dx - (ax + cx) / 2;
    /* by = */ dst[1].fY = 2 * dy - (ay + cy) / 2;
    return dst;
}