Beispiel #1
0
bool GiGraphics::drawBeziers(const GiContext* ctx, int count, 
                             const Point2d* points, bool closed, bool modelUnit)
{
    if (count < 4 || !points || isStopping())
        return false;
    if (count > 0x2000)
        count = 0x2000;
    count = 1 + (count - 1) / 3 * 3;

    bool ret = false;
    vector<Point2d> pxpoints;
    vector<Point2d> pointBuf;
    int i, j, n, si, ei;
    Point2d * pxs;
    Matrix2d matD(S2D(xf(), modelUnit));

    const Box2d extent (count, points);                 // 模型坐标范围
    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent))  // 全部在显示区域外
        return false;
    
    if (closed) {
        pxpoints.resize(count);
        pxs = &pxpoints.front();
        for (i = 0; i < count; i++)
            pxs[i] = points[i] * matD;
        ret = rawBeziers(ctx, pxs, count, closed);
    }
    else if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) {   // 全部在显示区域内
        pxpoints.resize(count);
        pxs = &pxpoints.front();
        for (i = 0; i < count; i++)
            pxs[i] = points[i] * matD;
        ret = rawBeziers(ctx, pxs, count);
    } else {
        pointBuf.resize(count);
        for (i = 0; i < count; i++)                 // 转换到像素坐标
            pointBuf[i] = points[i] * matD;
        Point2d* pts = &pointBuf.front();

        for (i = 0; i + 3 < count;) {
            for (; i + 3 < count && !m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3) ;
            si = ei = i;
            for (; i + 3 < count && m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3)
                ei = i + 3;
            if (ei > si) {
                n = ei - si + 1;
                pxpoints.resize(n);
                pxs = &pxpoints.front();
                for (j=0; j<n; j++)
                    pxs[j] = pts[si + j];
                ret = rawBeziers(ctx, pxs, n);
            }
        }
    }
    return ret;
}
Beispiel #2
0
bool GiGraphics::drawBeziers(const GiContext* ctx, int count, 
                             const Point2d* points, bool modelUnit)
{
    if (m_impl->drawRefcnt == 0 || count < 4 || points == NULL)
        return false;
    GiLock lock (&m_impl->drawRefcnt);
    if (count > 0x2000)
        count = 0x2000;
    count = 1 + (count - 1) / 3 * 3;

    bool ret = false;
    vector<Point2d> pxpoints;
    vector<Point2d> pointBuf;
    int i, j, n, si, ei;
    Point2d * pxs;
    Matrix2d matD(S2D(xf(), modelUnit));

    const Box2d extent (count, points);                 // 模型坐标范围
    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent))  // 全部在显示区域外
        return false;

    if (DRAW_MAXR(m_impl, modelUnit).contains(extent))  // 全部在显示区域内
    {
        pxpoints.resize(count);
        pxs = &pxpoints.front();
        for (i = 0; i < count; i++)
            pxs[i] = points[i] * matD;
        ret = rawBeziers(ctx, pxs, count);
    }
    else
    {        
        pointBuf.resize(count);
        for (i = 0; i < count; i++)                 // 转换到像素坐标
            pointBuf[i] = points[i] * matD;
        Point2d* pts = &pointBuf.front();

        si = ei = 0;
        for (i = 3; i < count; i += 3)
        {
            for ( ; i < count
                && m_impl->rectDraw.isIntersect(Box2d(4, &pts[ei])); i += 3)
                ei = i;
            n = ei - si + 1;
            if (n > 1)
            {
                pxpoints.resize(n);
                pxs = &pxpoints.front();
                for (j=0; j<n; j++)
                    pxs[j] = pts[si + j];
                ret = rawBeziers(ctx, pxs, n);
            }
            si = ei = i;
        }
    }
    return ret;
}
Beispiel #3
0
bool GiGraphics::drawSplines(const GiContext* ctx, int count, 
                             const Point2d* knots, 
                             const Vector2d* knotvs, bool modelUnit)
{
    if (m_impl->drawRefcnt == 0 || count < 2 
        || knots == NULL || knotvs == NULL)
        return false;
    GiLock lock (&m_impl->drawRefcnt);
    count = mgMin(count, static_cast<int>(1 + (0x2000 - 1) / 3));

    int i;
    Point2d pt;
    Vector2d vec;
    vector<Point2d> pxpoints;
    Matrix2d matD(S2D(xf(), modelUnit));

    // 开辟整形像素坐标数组
    pxpoints.resize(1 + (count - 1) * 3);
    Point2d *pxs = &pxpoints.front();

    pt = knots[0] * matD;                       // 第一个Bezier段的起点
    vec = knotvs[0] * matD / 3.f;               // 第一个Bezier段的起始矢量
    *pxs++ = pt;                                // 产生Bezier段的起点
    for (i = 1; i < count; i++)                 // 计算每一个Bezier段
    {
        *pxs++ = (pt += vec);                   // 产生Bezier段的第二点
        pt = knots[i] * matD;                   // Bezier段的终点
        vec = knotvs[i] * matD / 3.f;           // Bezier段的终止矢量
        *pxs++ = pt - vec;                      // 产生Bezier段的第三点
        *pxs++ = pt;                            // 产生Bezier段的终点
    }

    // 绘图
    return rawBeziers(ctx, &pxpoints.front(), getSize(pxpoints));
}
Beispiel #4
0
bool GiGraphics::drawHermiteSplines(const GiContext* ctx, int count, const Point2d* knots,
                                    const Vector2d* knotvs, bool closed, bool modelUnit)
{
    if (count < 2 || !knots || !knotvs || isStopping())
        return false;
    count = mgMin(count, 0x1000);

    int i;
    Point2d pt;
    Vector2d vec;
    vector<Point2d> pxpoints;
    Matrix2d matD(S2D(xf(), modelUnit));
    Matrix2d mat2(matD / 3.f);

    pxpoints.resize(1 + (closed ? count : count - 1) * 3);
    Point2d *pxs = &pxpoints.front();

    pt = knots[0] * matD;                       // 第一个Bezier段的起点
    vec = knotvs[0] * mat2;                     // 第一个Bezier段的起始矢量
    *pxs++ = pt;                                // 产生Bezier段的起点
    for (i = 1; i < count; i++) {               // 计算每一个Bezier段
        *pxs++ = (pt += vec);                   // 产生Bezier段的第二点
        pt = knots[i] * matD;                   // Bezier段的终点
        vec = knotvs[i] * mat2;                 // Bezier段的终止矢量
        *pxs++ = pt - vec;                      // 产生Bezier段的第三点
        *pxs++ = pt;                            // 产生Bezier段的终点
    }
    if (closed) {
        *pxs++ = (pt += vec);                   // 产生Bezier段的第二点
        *pxs++ = 2 * pxpoints[0] - pxpoints[1].asVector();  // 产生Bezier段的第三点
        *pxs++ = pxpoints[0];                   // 产生Bezier段的终点
    }
    
    return rawBeziers(ctx, &pxpoints.front(), getSize(pxpoints), closed);
}
Beispiel #5
0
bool GiGraphics::drawEllipse(const GiContext* ctx, const Point2d& center, 
                             float rx, float ry, bool modelUnit)
{
    if (rx < _MGZERO || isStopping())
        return false;
    
    bool ret = false;
    Matrix2d matD(S2D(xf(), modelUnit));

    if (ry < _MGZERO) {
        ry = (Vector2d(rx, rx) * matD).x;
        ry = fabsf((Vector2d(ry, ry) * matD.inverse()).y);
    }

    const Box2d extent (center, rx*2.f, ry*2.f);            // 模型坐标范围
    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent))  // 全部在显示区域外
        return false;

    if (mgIsZero(matD.m12) && mgIsZero(matD.m21)) {
        Point2d cen (center * matD);
        rx *= fabsf(matD.m11);
        ry *= fabsf(matD.m22);
        ret = rawEllipse(ctx, cen.x - rx, cen.y - ry, 2 * rx, 2 * ry);
    } else {
        Point2d pxs[13];
        mgcurv::ellipseToBezier(pxs, center, rx, ry);
        matD.transformPoints(13, pxs);

        ret = rawBeziers(ctx, pxs, 13, true);
    }

    return ret;
}
Beispiel #6
0
bool GiGraphics::drawBSplines(const GiContext* ctx, int count, const Point2d* ctlpts,
                              bool closed, bool modelUnit)
{
    if (closed) {
        if (count < 3 || !ctlpts || isStopping())
            return false;
        count = mgMin(count, static_cast<int>((0x2000 - 1) / 3));
    } else {
        if (count < 4 || !ctlpts || isStopping())
            return false;
        count = mgMin(count, static_cast<int>(3 + (0x2000 - 1) / 3));
    }
    
    const Box2d extent (count, ctlpts);                     // 模型坐标范围
    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent))  // 全部在显示区域外
        return false;

    int i;
    Point2d pt1, pt2, pt3, pt4;
    float d6 = 1.f / 6.f;
    vector<Point2d> pxpoints;
    Matrix2d matD(S2D(xf(), modelUnit));

    // 开辟像素坐标数组
    pxpoints.resize(1 + (closed ? count : (count - 3)) * 3);
    Point2d *pxs = &pxpoints.front();

    // 计算第一个曲线段
    pt1 = ctlpts[0] * matD;
    pt2 = ctlpts[1] * matD;
    pt3 = ctlpts[2] * matD;
    pt4 = ctlpts[3 % count] * matD;
    (*pxs++).set((pt1.x + 4 * pt2.x + pt3.x)*d6, (pt1.y + 4 * pt2.y + pt3.y)*d6);
    (*pxs++).set((4 * pt2.x + 2 * pt3.x)    *d6,  (4 * pt2.y + 2 * pt3.y)   *d6);
    (*pxs++).set((2 * pt2.x + 4 * pt3.x)    *d6,  (2 * pt2.y + 4 * pt3.y)   *d6);
    (*pxs++).set((pt2.x + 4 * pt3.x + pt4.x)*d6, (pt2.y + 4 * pt3.y + pt4.y)*d6);

    // 计算其余曲线段
    for (i = 4; i < (closed ? (count + 3) : count); i++) {
        pt1 = pt2;
        pt2 = pt3;
        pt3 = pt4;
        pt4 = ctlpts[i % count] * matD;
        (*pxs++).set((4 * pt2.x + 2 * pt3.x)    *d6, (4 * pt2.y + 2 * pt3.y)   *d6);
        (*pxs++).set((2 * pt2.x + 4 * pt3.x)    *d6, (2 * pt2.y + 4 * pt3.y)   *d6);
        (*pxs++).set((pt2.x + 4 * pt3.x + pt4.x)*d6,(pt2.y + 4 * pt3.y + pt4.y)*d6);
    }

    // 绘图
    return rawBeziers(ctx, &pxpoints.front(), getSize(pxpoints), closed);
}
Beispiel #7
0
bool GiGraphics::drawArc(const GiContext* ctx,
                         const Point2d& center, float rx, float ry, 
                         float startAngle, float sweepAngle, 
                         bool modelUnit)
{
    if (rx < _MGZERO || fabsf(sweepAngle) < 1e-5f || isStopping())
        return false;

    if (ry < _MGZERO)
        ry = rx;

    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(Box2d(center, 2 * rx, 2 * ry)))
        return false;

    Point2d points[16];
    int count = mgcurv::arcToBezier(points, center,
        rx, ry, startAngle, sweepAngle);
    S2D(xf(), modelUnit).transformPoints(count, points);

    return count > 3 && rawBeziers(ctx, points, count);
}
Beispiel #8
0
bool GiGraphics::drawArc(const GiContext* ctx, 
                         const Point2d& center, float rx, float ry, 
                         float startAngle, float sweepAngle, 
                         bool modelUnit)
{
    if (m_impl->drawRefcnt == 0 || rx < _MGZERO || fabs(sweepAngle) < 1e-5f)
        return false;
    GiLock lock (&m_impl->drawRefcnt);

    if (ry < _MGZERO)
        ry = rx;

    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(Box2d(center, 2 * rx, 2 * ry)))
        return false;

    Point2d points[16];
    int count = mgAngleArcToBezier(points, center,
        rx, ry, startAngle, sweepAngle);
    S2D(xf(), modelUnit).TransformPoints(count, points);

    return count > 3 && rawBeziers(ctx, points, count);
}
Beispiel #9
0
bool GiGraphics::drawBeziers(const GiContext* ctx, int count,
                             const Point2d* knot, const Vector2d* knotvs,
                             bool closed, bool modelUnit)
{
    if (count < 2 || !knot || !knotvs || isStopping())
        return false;
    if (count > 0x1000)
        count = 0x1000;
    
    bool ret = false;
    vector<Point2d> pxpoints;
    vector<Point2d> pointBuf;
    int i, j, n, si, ei;
    Point2d * pxs;
    Matrix2d matD(S2D(xf(), modelUnit));
    
    const Box2d extent (count, knot);                       // 模型坐标范围
    if (!DRAW_RECT(m_impl, modelUnit).isIntersect(extent))  // 全部在显示区域外
        return false;
    
    pointBuf.resize(1 + (count - 1) * 3);
    pxs = &pointBuf.front();
    
    if (closed) {
        pxs[0] = knot[0] * matD;
        for (i = 0, j = 1; i + 1 < count; i++) {
            pxs[j++] = (knot[i] + knotvs[i]) * matD;
            pxs[j++] = (knot[i+1] - knotvs[i+1]) * matD;
            pxs[j++] = knot[i+1] * matD;
        }
        ret = rawBeziers(ctx, pxs, j, closed);
    }
    else if (DRAW_MAXR(m_impl, modelUnit).contains(extent)) {   // 全部在显示区域内
        pxs[0] = knot[0] * matD;
        for (i = 0, j = 1; i + 1 < count; i++) {
            pxs[j++] = (knot[i] + knotvs[i]) * matD;
            pxs[j++] = (knot[i+1] - knotvs[i+1]) * matD;
            pxs[j++] = knot[i+1] * matD;
        }
        ret = rawBeziers(ctx, pxs, j);
    } else {
        pxs[0] = knot[0] * matD;
        for (i = 0, j = 1; i + 1 < count; i++) {
            pxs[j++] = (knot[i] + knotvs[i]) * matD;
            pxs[j++] = (knot[i+1] - knotvs[i+1]) * matD;
            pxs[j++] = knot[i+1] * matD;
        }
        
        Point2d* pts = pxs;
        
        count = 1 + (count - 1) * 3;
        for (i = 0; i + 3 < count;) {
            for (; i + 3 < count && !m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3) ;
            si = ei = i;
            for (; i + 3 < count && m_impl->rectDraw.isIntersect(Box2d(4, &pts[i])); i += 3)
                ei = i + 3;
            if (ei > si) {
                n = ei - si + 1;
                pxpoints.resize(n);
                pxs = &pxpoints.front();
                for (j=0; j<n; j++)
                    pxs[j] = pts[si + j];
                ret = rawBeziers(ctx, pxs, n);
            }
        }
    }
    
    return ret;
}