コード例 #1
0
// from http://blog.gludion.com/2009/08/distance-to-quadratic-bezier-curve.html
// (currently only used by testing)
double SkDQuad::nearestT(const SkDPoint& pt) const {
    SkDVector pos = fPts[0] - pt;
    // search points P of bezier curve with PM.(dP / dt) = 0
    // a calculus leads to a 3d degree equation :
    SkDVector A = fPts[1] - fPts[0];
    SkDVector B = fPts[2] - fPts[1];
    B -= A;
    double a = B.dot(B);
    double b = 3 * A.dot(B);
    double c = 2 * A.dot(A) + pos.dot(B);
    double d = pos.dot(A);
    double ts[3];
    int roots = SkDCubic::RootsValidT(a, b, c, d, ts);
    double d0 = pt.distanceSquared(fPts[0]);
    double d2 = pt.distanceSquared(fPts[2]);
    double distMin = SkTMin(d0, d2);
    int bestIndex = -1;
    for (int index = 0; index < roots; ++index) {
        SkDPoint onQuad = ptAtT(ts[index]);
        double dist = pt.distanceSquared(onQuad);
        if (distMin > dist) {
            distMin = dist;
            bestIndex = index;
        }
    }
    if (bestIndex >= 0) {
        return ts[bestIndex];
    }
    return d0 < d2 ? 0 : 1;
}
コード例 #2
0
ファイル: SkIntersections.cpp プロジェクト: Arternis/skia
int SkIntersections::closestTo(double rangeStart, double rangeEnd, const SkDPoint& testPt,
        double* closestDist) const {
    int closest = -1;
    *closestDist = SK_ScalarMax;
    for (int index = 0; index < fUsed; ++index) {
        if (!between(rangeStart, fT[0][index], rangeEnd)) {
            continue;
        }
        const SkDPoint& iPt = fPt[index];
        double dist = testPt.distanceSquared(iPt);
        if (*closestDist > dist) {
            *closestDist = dist;
            closest = index;
        }
    }
    return closest;
}