Пример #1
0
bool mglnrel::cross2Line(
    const Point2d& a, const Point2d& b, const Point2d& c, const Point2d& d,
    Point2d& ptCross, const Tol& tolVec)
{
    float u, v, denom, cosnum;
    
    if (mgMin(a.x,b.x) - mgMax(c.x,d.x) > _MGZERO 
        || mgMin(c.x,d.x) - mgMax(a.x,b.x) > _MGZERO
        || mgMin(a.y,b.y) - mgMax(c.y,d.y) > _MGZERO 
        || mgMin(c.y,d.y) - mgMax(a.y,b.y) > _MGZERO)
        return false;
    
    denom = (c.x-d.x)*(b.y-a.y)-(c.y-d.y)*(b.x-a.x);
    if (mgIsZero(denom))
        return false;
    
    cosnum = (b.x-a.x)*(d.x - c.x) + (b.y-a.y)*(d.y-c.y);
    if (!mgIsZero(cosnum) && fabsf(denom / cosnum) < tolVec.equalVector())
        return false;
    
    u = ((c.x-a.x)*(d.y-c.y)-(c.y-a.y)*(d.x-c.x)) / denom;
    if (u < _MGZERO || u > 1.f - _MGZERO)
        return false;
    
    v = ((c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x)) / denom;
    if (v < _MGZERO || v > 1.f - _MGZERO)
        return false;
    
    ptCross.x = (1 - u) * a.x + u * b.x;
    ptCross.y = (1 - u) * a.y + u * b.y;
    
    return true;
}
Пример #2
0
bool mglnrel::cross2Beeline(
    const Point2d& a, const Point2d& b, const Point2d& c, const Point2d& d, 
    Point2d& ptCross, float* pu, float* pv, const Tol& tolVec)
{
    float u, v, denom, cosnum;
    
    denom = (c.x-d.x)*(b.y-a.y)-(c.y-d.y)*(b.x-a.x);
    if (mgIsZero(denom))            // 平行或重合
        return false;
    
    cosnum = (b.x-a.x)*(d.x - c.x) + (b.y-a.y)*(d.y-c.y);
    if (!mgIsZero(cosnum) && fabsf(denom / cosnum) < tolVec.equalVector())
        return false;
    
    u = ((c.x-a.x)*(d.y-c.y)-(c.y-a.y)*(d.x-c.x)) / denom;
    v = ((c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x)) / denom;
    
    if (pu) *pu = u;
    if (pv) *pv = v;
    
    ptCross.x = (1 - u) * a.x + u * b.x;
    ptCross.y = (1 - u) * a.y + u * b.y;
    
    return true;
}
Пример #3
0
bool mgcurv::triEquations(
    int n, float *a, float *b, float *c, Vector2d *vs)
{
    if (!a || !b || !c || !vs || n < 2)
        return false;
    
    float w;
    int i;
    
    w = b[0];
    if (mgIsZero(w))
        return false;
    w = 1 / w;
    vs[0].x = vs[0].x * w;
    vs[0].y = vs[0].y * w;
    
    for (i = 0; i <= n-2; i++)
    {
        b[i] = c[i] * w;
        w = b[i+1] - a[i] * b[i];
        if (mgIsZero(w))
            return false;
        w = 1 / w;
        vs[i+1].x = (vs[i+1].x - a[i] * vs[i].x) * w;
        vs[i+1].y = (vs[i+1].y - a[i] * vs[i].y) * w;
    }
    
    for (i = n-2; i >= 0; i--)
    {
        vs[i].x -= b[i] * vs[i+1].x;
        vs[i].y -= b[i] * vs[i+1].y;
    }
    
    return true;
}
Пример #4
0
bool Matrix2d::isConformal(float& scaleX, float& scaleY, float& angle, 
                           bool& isMirror, Vector2d& reflex) const
{
    Vector2d e0 (m11, m12);
    Vector2d e1 (m21, m22);
    if (!e0.isPerpendicularTo(e1))
        return false;
    
    scaleX = e0.length();
    scaleY = e1.length();
    e0 /= scaleX;
    e1 /= scaleY;
    
    if (mgIsZero(e0.x - e1.y) && mgIsZero(e0.y + e1.x))
    {
        isMirror = false;
        angle = e0.angle2();
    }
    else
    {
        isMirror = true;
        angle = e0.angle2() / 2.f;
        reflex.x = cosf(angle);
        reflex.y = sinf(angle);
        angle = 0.f;
    }
    
    return true;
}
Пример #5
0
bool mglnrel::crossLineBeeline(
    const Point2d& a, const Point2d& b, const Point2d& c, const Point2d& d,
    Point2d& ptCross, float* pv, const Tol& tolVec)
{
    float u, denom, cosnum;
    
    denom = (c.x-d.x)*(b.y-a.y)-(c.y-d.y)*(b.x-a.x);
    if (mgIsZero(denom))
        return false;
    
    cosnum = (b.x-a.x)*(d.x - c.x) + (b.y-a.y)*(d.y-c.y);
    if (!mgIsZero(cosnum) && fabsf(denom / cosnum) < tolVec.equalVector())
        return false;
    
    u = ((c.x-a.x)*(d.y-c.y)-(c.y-a.y)*(d.x-c.x)) / denom;
    if (u < _MGZERO || u > 1.f - _MGZERO)
        return false;
    
    if (pv) {
        *pv = ((c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x)) / denom;
    }
    
    ptCross.x = (1 - u) * a.x + u * b.x;
    ptCross.y = (1 - u) * a.y + u * b.y;
    
    return true;
}
Пример #6
0
// 计算点pt到无穷直线ab的距离
GEOMAPI float mgPtToBeeline2(
    const Point2d& a, const Point2d& b, const Point2d& pt, Point2d& ptPerp)
{
    // 两点重合
    if (a == b)
    {
        ptPerp = a;
        return a.distanceTo(pt);
    }
    // 竖直线
    else if (mgIsZero(a.x - b.x))
    {
        ptPerp.set(a.x, pt.y);
        return fabs(a.x - pt.x);
    }
    // 水平线
    else if (mgIsZero(a.y - b.y))
    {
        ptPerp.set(pt.x, a.y);
        return fabs(a.y - pt.y);
    }
    else
    {
        float t1 = ( b.y - a.y ) / ( b.x - a.x );
        float t2 = -1.f / t1;
        ptPerp.x = ( pt.y - a.y + a.x * t1 - pt.x * t2 ) / ( t1 - t2 );
        ptPerp.y = a.y + (ptPerp.x - a.x) * t1;
        return pt.distanceTo(ptPerp);
    }
}
Пример #7
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;
}
Пример #8
0
bool Matrix2d::hasMirror(Vector2d& reflex) const
{
    Vector2d e0 (m11, m12);
    Vector2d e1 (m21, m22);
    if (e0.normalize() && e1.normalize() && e0.isPerpendicularTo(e1)) {
        if (!mgIsZero(e0.x - e1.y) || !mgIsZero(e0.y + e1.x)) {
            reflex.setAngleLength(e0.angle2() / 2.f, 1.f);
            return true;
        }
    }
    return false;
}
Пример #9
0
void MgBaseRect::setRectWithAngle(const Point2d& pt1, const Point2d& pt2,
                                  float angle, const Point2d& basept)
{
    Box2d rect(pt1, pt2);
    
    if (getFlag(kMgSquare)) {
        if (basept == pt1 && isCurve()) {
            rect.set(basept, 2 * basept.distanceTo(pt2), 0);
        }
        else {
            float len = mgMax(fabsf(pt2.x - pt1.x), fabsf(pt2.y - pt1.y));
            if (basept == pt1 && !isCurve()) {
                rect.set(pt1, pt1 + Point2d(pt2.x > pt1.x ? len : -len,
                                            pt2.y > pt1.y ? len : -len));
            } else {
                rect.set(basept, basept == pt1 ? 2 * len : len, 0);
            }
        }
    }
    
    _points[0] = rect.leftTop();
    _points[1] = rect.rightTop();
    _points[2] = rect.rightBottom();
    _points[3] = rect.leftBottom();

    if (!mgIsZero(angle))
    {
        Matrix2d mat(Matrix2d::rotation(angle, basept));
        for (int i = 0; i < 4; i++)
            _points[i] *= mat;
    }
}
Пример #10
0
static bool PtInArea_Edge(int &odd, const Point2d& pt, const Point2d& p1, 
                          const Point2d& p2, const Point2d& p0)
{
    // 如果从X方向上P不在边[P1,P2)上,则没有交点. 竖直边也没有
    if (!((p2.x > p1.x) && (pt.x >= p1.x) && (pt.x < p2.x)) &&
        !((p1.x > p2.x) && (pt.x <= p1.x) && (pt.x > p2.x)) )
    {
        return false;
    }
    
    // 求从Y负无穷大向上到P的射线和该边的交点(pt.x, yy)
    float yy = p1.y + (pt.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
    if (pt.y > yy)      // 相交
    {
        if (mgIsZero(pt.x - p1.x))    // 交点是顶点, 则比较P[i+1]和P[i-1]是否在pt.x同侧
        {
            if (((p0.x > pt.x) && (p2.x > pt.x)) ||
                ((p0.x < pt.x) && (p2.x < pt.x)) )      // 同侧
            {
                return false;
            }
        }
        odd = 1 - odd;      // 增加一个交点, 奇偶切换
    }
    
    return true;
}
Пример #11
0
Matrix2d& Matrix2d::setToScaling(float scaleX, float scaleY, 
                                 const Point2d& center)
{
    if (mgIsZero(scaleY)) scaleY = scaleX;
    return set(scaleX, 0, 0, scaleY,
        (1 - scaleX) * center.x, (1 - scaleY) * center.y);
}
Пример #12
0
bool GiGraphics::drawEllipse(const GiContext* ctx, const Point2d& center, 
                             float rx, float ry, bool modelUnit)
{
    if (m_impl->drawRefcnt == 0 || rx < _MGZERO)
        return false;
    GiLock lock (&m_impl->drawRefcnt);
    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 = rawBeginPath();
        if (ret)
        {
            rawMoveTo(pxs[0].x, pxs[0].y);
            for (int i = 1; i + 2 < 13; i += 3) {
                rawBezierTo(pxs[i].x, pxs[i].y,
                    pxs[i+1].x, pxs[i+1].y, pxs[i+2].x, pxs[i+2].y);
            }
            rawClosePath();
            ret = rawEndPath(ctx, true);
        }
    }

    return ret;
}
Пример #13
0
Matrix2d Matrix2d::coordSystem(const Point2d& origin, float scaleX, 
                               float scaleY, float angle)
{
    if (mgIsZero(scaleY)) scaleY = scaleX;
    float s = sinf(angle);
    float c = cosf(angle);
    return Matrix2d(c*scaleX, s*scaleX, -s*scaleY, c*scaleY, origin.x, origin.y);
}
Пример #14
0
bool mglnrel::crossLineAbc(
    float a1, float b1, float c1, float a2, float b2, float c2,
    Point2d& ptCross, const Tol& tolVec)
{
    float sinnum, cosnum;
    
    sinnum = a1*b2 - a2*b1;
    if (mgIsZero(sinnum))
        return false;
    cosnum = a1*a2 + b1*b2;
    if (!mgIsZero(cosnum) && fabsf(sinnum / cosnum) < tolVec.equalVector())
        return false;
    
    ptCross.x = (b1*c2 - b2*c1) / sinnum;
    ptCross.y = (a2*c1 - a1*c2) / sinnum;
    
    return true;
}
Пример #15
0
float MgArc::getSweepAngle() const
{
    if (!mgIsZero(_sweepAngle)) {
        return _sweepAngle;
    }
    
    const float midAngle = (getMidPoint() - getCenter()).angle2();
    const float startAngle = getStartAngle();
    const float endAngle = getEndAngle();

    if (mgEquals(midAngle, startAngle) && mgEquals(startAngle, endAngle)) {
        return endAngle - startAngle;
    }
    
    Tol tol(getRadius() * 1e-3f, 1e-4f);
    if (getStartPoint().isEqualTo(getEndPoint(), tol)
        && (getMidPoint() + (getStartPoint() + getEndPoint()) / 2).isEqualTo(2 * getCenter(), tol)) {
        return _M_2PI;
    }

    float startAngle2 = startAngle;
    float midAngle2 = midAngle;
    float endAngle2 = endAngle;

    // 先尝试看是否为逆时针方向:endAngle2 > midAngle2 > startAngle2 >= 0
    if (startAngle2 < 0)
        startAngle2 += _M_2PI;
    while (midAngle2 < startAngle2)
        midAngle2 += _M_2PI;
    while (endAngle2 < midAngle2)
        endAngle2 += _M_2PI;

    if (fabsf(startAngle2 + endAngle2 - 2 * midAngle2) < _M_PI_6
        && endAngle2 - startAngle2 < _M_2PI) {
        return endAngle2 - startAngle2;
    }

    // 再尝试看是否为顺时针方向:endAngle2 < midAngle2 < startAngle2 <= 0
    startAngle2 = startAngle;
    midAngle2 = midAngle;
    endAngle2 = endAngle;
    if (startAngle2 > 0)
        startAngle2 -= _M_2PI;
    while (midAngle2 > startAngle2)
        midAngle2 -= _M_2PI;
    while (endAngle2 > midAngle2)
        endAngle2 -= _M_2PI;

    if (fabsf(startAngle2 + endAngle2 - 2 * midAngle2) < _M_PI_6) {
        if (endAngle2 - startAngle2 > -_M_2PI)
            return endAngle2 - startAngle2;
        return mgbase::toRange(endAngle2 - startAngle2, -_M_2PI, 0);
    }

    return endAngle - startAngle;   // error
}
Пример #16
0
bool mgcurv::gaussJordan(int n, float *mat, Vector2d *vs)
{
    int i, j, k, m;
    float c, t;
    Vector2d tt;
    
    if (!mat || !vs || n < 2)
        return false;
    
    for (k = 0; k < n; k++) {
        // 找主元. 即找第k列中第k行以下绝对值最大的元素
        m = k;
        c = mat[k*n+k];
        for (i = k+1; i < n; i++) {
            if (fabsf(mat[i*n+k]) > fabsf(c)) {
                m = i;
                c = mat[i*n+k];
            }
        }
        // 交换第k行和第m行中第k列以后的元素
        if (m != k) {
            for (j = k; j < n; j++) {
                t = mat[m*n+j]; mat[m*n+j] = mat[k*n+j]; mat[k*n+j] = t; 
            }
            tt = vs[m]; vs[m] = vs[k]; vs[k] = tt;
        }
        // 消元. 第k行中第k列以后元素/=mat[k][k]
        c = mat[k*n+k];
        if (mgIsZero(c))
            return false;
        c = 1.f / c;
        for (j = k; j < n; j++)
            mat[k*n+j] *= c;
        vs[k].x = vs[k].x * c;
        vs[k].y = vs[k].y * c;
        // 从第k+1行以下每一行, 对该行第k列以后各元素-=
        for (i = k+1; i < n; i++) {
            c = mat[i*n+k];
            for (j = k; j < n; j++)
                mat[i*n+j] -= mat[k*n+j] * c;
            vs[i].x -= vs[k].x * c;
            vs[i].y -= vs[k].y * c;
        }
    }
    
    // 回代
    for (i = n-2; i >= 0; i--) {
        for (j = i; j < n; j++) {
            vs[i].x -= mat[i*n+j+1] * vs[j+1].x;
            vs[i].y -= mat[i*n+j+1] * vs[j+1].y;
        }
    }
    
    return true;
}
Пример #17
0
bool GiGraphics::drawEllipse(const GiContext* ctx, const Point2d& center, 
                             float rx, float ry, bool modelUnit)
{
    if (m_impl->drawRefcnt == 0 || rx < _MGZERO)
        return false;
    GiLock lock (&m_impl->drawRefcnt);
    bool ret = false;
    Matrix2d matD(S2D(xf(), modelUnit));

    if (ry < _MGZERO)
        ry = rx;

    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 *= matD.m11;
        ry *= matD.m22;

        ret = rawEllipse(ctx, cen.x - rx, cen.y - ry, 2 * rx, 2 * ry);
    }
    else
    {
        Point2d points[13];
        mgEllipseToBezier(points, center, rx, ry);
        matD.TransformPoints(13, points);

        ret = rawBeginPath();
        if (ret)
        {
            ret = rawMoveTo(points[0].x, points[0].y);
            ret = rawBezierTo(points + 1, 12);
            ret = rawClosePath();
            ret = rawEndPath(ctx, true);
        }
    }

    return ret;
}
Пример #18
0
int mgcurv::arcToBezier(
    Point2d points[16], const Point2d& center, float rx, float ry,
    float startAngle, float sweepAngle)
{
    if (mgIsZero(rx) || fabsf(sweepAngle) < 1e-5)
        return 0;
    if (mgIsZero(ry))
        ry = rx;
    if (sweepAngle > _M_2PI)
        sweepAngle = _M_2PI;
    else if (sweepAngle < -_M_2PI)
        sweepAngle = -_M_2PI;
    
    int n = 0;
    
    if (fabsf(sweepAngle) < _M_PI_2 + 1e-5)
    {
        _arcToBezier(points, center, rx, ry, startAngle, sweepAngle);
        n = 4;
    }
    else if (sweepAngle > 0)
    {
        startAngle = mgbase::to0_2PI(startAngle);
        n = _arcToBezierPlusSweep(
            points, center, rx, ry, startAngle, sweepAngle);
    }
    else // sweepAngle < 0
    {
        float endAngle = startAngle + sweepAngle;
        sweepAngle = -sweepAngle;
        startAngle = mgbase::to0_2PI(endAngle);
        n = _arcToBezierPlusSweep(
            points, center, rx, ry, startAngle, sweepAngle);

        for (int i = 0; i < n / 2; i++)
            mgSwap(points[i], points[n - 1 - i]);
    }
    
    return n;
}
Пример #19
0
// 将本矢量在两个不共线的非零矢量上进行矢量分解, vec = u*uAxis+v*vAxis
bool Vector2d::resolveVector(const Vector2d& uAxis, const Vector2d& vAxis, 
                             Vector2d& uv) const
{
    float denom = uAxis.crossProduct(vAxis);
    if (mgIsZero(denom)) {
        uv.x = 0.f; uv.y = 0.f;
        return false;
    }
    float c = uAxis.crossProduct(*this);
    uv.x = crossProduct(vAxis) / denom;
    uv.y = c / denom;
    return true;
}
Пример #20
0
// 将本矢量在两个不共线的非零矢量上进行矢量分解, vec = u*uAxis+v*vAxis
bool Vector2d::resolveVector(const Vector2d& uAxis, const Vector2d& vAxis, 
                             float& u, float& v) const
{
    float denom = uAxis.crossProduct(vAxis);
    if (mgIsZero(denom))
    {
        u = 0.f; v = 0.f;
        return false;
    }
    u = crossProduct(vAxis) / denom;
    v = uAxis.crossProduct(*this) / denom;
    return true;
}
Пример #21
0
Matrix2d& Matrix2d::setToMirroring(const Point2d& pnt, const Vector2d& dir)
{
    float d2 = dir.lengthSquare();
    if (mgIsZero(d2))
        setToIdentity();
    else
    {
        float s2 = 2.f * dir.x * dir.y / d2;
        float c2 = (dir.x * dir.x - dir.y * dir.y) / d2;
        set(c2, s2, s2, -c2, (1 - c2) * pnt.x - s2 * pnt.y, 
            (1 + c2) * pnt.y - s2 * pnt.x);
    }
    return *this;
}
Пример #22
0
void MgBaseRect::setRect(const Box2d& rect, float angle)
{
    _points[0] = rect.leftTop();
    _points[1] = rect.rightTop();
    _points[2] = rect.rightBottom();
    _points[3] = rect.leftBottom();

    if (!mgIsZero(angle))
    {
        Matrix2d mat(Matrix2d::rotation(angle, rect.center()));
        for (int i = 0; i < 4; i++)
            _points[i] *= mat;
    }
}
Пример #23
0
// 判断两个矢量是否平行
bool Vector2d::isParallelTo(const Vector2d& vec, 
                            const Tol& tol, bool& nonzero) const
{
    bool ret = false;
    nonzero = true;
    float cosfz = dotProduct(vec);
    float sinfz = crossProduct(vec);
    if (fabsf(sinfz) <= fabsf(cosfz) * tol.equalVector())
    {
        if (mgIsZero(cosfz))
            nonzero = false;
        ret = true;
    }
    return ret;
}
Пример #24
0
bool MgArc::setCenterStartEnd(const Point2d& center, const Point2d& start, const Point2d& end)
{
    float startAngle = (start - center).angle2();
    float endAngle = (end - center).angle2();
    float sweepAngle = mgToRange(endAngle - startAngle, -_M_2PI, _M_2PI);

    if (!mgIsZero(sweepAngle)) {
        float lastSweepAngle = getSweepAngle();
        if (fabsf( fabsf(sweepAngle) - fabsf(lastSweepAngle) ) > _M_PI_6) {
            sweepAngle = sweepAngle + (sweepAngle > 0 ?  -_M_2PI :  _M_2PI);
        }
    }

    return setCenterRadius(center, start.distanceTo(center), startAngle, sweepAngle);
}
Пример #25
0
bool Matrix2d::invert()
{
    float d = m11 * m22 - m12 * m21;
    if (mgIsZero(d))
    {
        setToIdentity();
        return false;
    }
    
    d = 1.f / d;
    set(m22 * d, -m12 * d, 
        -m21 * d, m11 * d,
        (m21 * dy - m22 * dx) * d, 
        (m12 * dx - m11 * dy) * d);
    return true;
}
Пример #26
0
bool GiTransform::zoomByFactor(float factor, const Point2d* pxAt, bool adjust)
{
    float scale = m_impl->viewScale;
    if (factor > 0)
        scale *= (1 + fabs(factor));
    else
        scale /= (1 + fabs(factor));

    if (adjust)
    {
        scale = mgMax(scale, m_impl->minViewScale);
        scale = mgMin(scale, m_impl->maxViewScale);
    }
    if (mgIsZero(scale - m_impl->viewScale))
        return false;
    return zoomScale(scale, pxAt, adjust);
}
Пример #27
0
void GiGraphics::drawArrayHead(const GiContext& ctx, MgPath& path, int type, float px, float scale)
{
    float xoffset = _arrayHeads[type - 1].xoffset * scale;
    Point2d startpt(path.getStartPoint());
    path.trimStart(startpt, xoffset + px / 2);
    
    Matrix2d mat(Matrix2d::translation(startpt.asVector()));
    Vector2d vec(mgIsZero(xoffset) ? path.getStartTangent() : path.getStartPoint() - startpt);
    mat *= Matrix2d::rotation(vec.angle2(), startpt);
    mat *= Matrix2d::scaling(scale, startpt);
    
    MgPath headPath(_arrayHeads[type - 1].types);
    headPath.transform(mat);
    
    GiContext ctxhead(ctx);
    if (_arrayHeads[type - 1].fill) {
        ctxhead.setFillColor(ctxhead.getLineColor());
        ctxhead.setNullLine();
    }
    drawPath_(&ctxhead, headPath, ctxhead.hasFillColor(), Matrix2d::kIdentity());
}
Пример #28
0
void MgBaseRect::setRect(const Point2d& pt1, const Point2d& pt2,
                         float angle, const Point2d& basept)
{
    Box2d rect(pt1, pt2);
    
    if (getFlag(kMgSquare)) {
        float len = (float)sqrt(fabs((pt2.x - pt1.x) * (pt2.y - pt1.y)));
        rect.set(basept, len, 0);
    }
    
    _points[0] = rect.leftTop();
    _points[1] = rect.rightTop();
    _points[2] = rect.rightBottom();
    _points[3] = rect.leftBottom();

    if (!mgIsZero(angle))
    {
        Matrix2d mat(Matrix2d::rotation(angle, basept));
        for (int i = 0; i < 4; i++)
            _points[i] *= mat;
    }
}
Пример #29
0
    bool zoomNoAdjust(const Point2d& pnt, float scale, bool* changed = NULL)
    {
        bool bChanged = false;

        if (pnt != centerW || !mgIsZero(scale - viewScale))
        {
            tmpCenterW = pnt;
            tmpViewScale = scale;
            bChanged = true;
            if (zoomEnabled)
            {
                centerW = pnt;
                viewScale = scale;
                updateTransforms();
                zoomChanged();
            }
        }
        if (changed != NULL)
            *changed = bChanged;

        return bChanged;
    }
Пример #30
0
float GiGraphics::drawTextAt(GiTextWidthCallback* c, int argb, const char* text, const Point2d& pnt, float h, int align, float angle)
{
    float ret = 0;
    
    if (m_impl->canvas && text && h > 0 && !m_impl->stopping && !pnt.isDegenerate()) {
        Point2d ptd(pnt * xf().modelToDisplay());
        float w2d = xf().getWorldToDisplayY(h < 0);
        h = fabsf(h) * w2d;
        
        if (!mgIsZero(angle)) {
            angle = (Vector2d::angledVector(angle, 1) * xf().modelToWorld()).angle2();
        }
        
        GiContext ctx;
        ctx.setFillARGB(argb ? argb : 0xFF000000);
        if (setBrush(&ctx)) {
            TextWidthCallback1 *cw = c ? new TextWidthCallback1(c, w2d) : (TextWidthCallback1 *)0;
            ret = m_impl->canvas->drawTextAt(cw, text, ptd.x, ptd.y, h, align, angle) / w2d;
        }
    }
    
    return ret;
}