Ejemplo n.º 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;
}
Ejemplo n.º 2
0
void GiTransform::setViewScaleRange(float minScale, float maxScale)
{
    if (minScale > maxScale)
        mgSwap(minScale, maxScale);

    minScale = mgMax(minScale, 1e-5f);
    minScale = mgMin(minScale, 0.5f);

    maxScale = mgMax(maxScale, 1.f);
    maxScale = mgMin(maxScale, 50.f);

    m_impl->minViewScale = minScale;
    m_impl->maxViewScale = maxScale;
}
Ejemplo n.º 3
0
bool MgGrid::_setHandlePoint(int index, const Point2d& pt, float tol)
{
    if (index < 8) {
        return __super::_setHandlePoint(index, pt, tol);
    }
    
    float cx = (float)fabs(pt.x - getPoint(3).x);
    float cy = (float)fabs(pt.y - getPoint(3).y);
    cx = mgMax(mgMax(cx, tol / 3.f), cy);
    cx = (float)( (int)(cx * 100) / 10 ) * 0.1f;
    m_cell.set(cx, cx);
    
    return true;
}
Ejemplo n.º 4
0
float GiGraphics::calcPenWidth(float lineWidth, bool useViewScale) const
{
    float w = 1;
    float px;

    if (m_impl->maxPenWidth <= 1)
        lineWidth = 0;

    if (lineWidth > 0)      // 单位:0.01mm
    {
        px = lineWidth / 2540.f * xf().getDpiY();
        if (useViewScale)
            px *= xf().getViewScale();
        w = mgMin(px, m_impl->maxPenWidth);
    }
    else if (lineWidth < 0) // 单位:像素
    {
        w = mgMin(-lineWidth, m_impl->maxPenWidth);
    }
    
    w = mgMax(w, m_impl->minPenWidth);
    if (lineWidth <= 0 && xf().getDpiY() > getScreenDpi()) {
        w = w * xf().getDpiY() / getScreenDpi();
    }

    return w;
}
Ejemplo n.º 5
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;
    }
}
Ejemplo n.º 6
0
float GiGraphics::calcPenWidth(float lineWidth, bool useViewScale) const
{
    float w = mgMin(m_impl->minPenWidth, 1.f);

    if (m_impl->maxPenWidth <= 1)
        lineWidth = 0;

    if (lineWidth > 0) {            // 单位:0.01mm
        w = lineWidth / 2540.f * xf().getDpiY();
        if (useViewScale)
            w *= xf().getViewScale();
    }
    else if (lineWidth < 0) {       // 单位:像素
        if (lineWidth < -1e3f)      // 不使用UI放缩系数
            w = 1e3f - lineWidth;
        else
            w = -lineWidth * _penWidthFactor;
        if (useViewScale)
            w *= xf().getViewScale();
    }
    w = mgMin(w, m_impl->maxPenWidth);
    w = mgMax(w, m_impl->minPenWidth);
    //if (lineWidth <= 0 && xf().getDpiY() > getScreenDpi())
    //    w = w * xf().getDpiY() / getScreenDpi();

    return w;
}
Ejemplo n.º 7
0
// ConvertToBezierForm :
//      Given a point and a Bezier curve, generate a 5th-degree
//      Bezier-format equation whose solution finds the point on the
//      curve nearest the user-defined point.
// Parameters :
//      pt: The point to find t for
//      pts: The control points
//      w: Ctl pts of 5th-degree curve, [W_DEGREE+1]
//
static void ConvertToBezierForm(const Point2d& pt, const Point2d* pts, Point2d* w)
{
    int     i, j, k, m, n, ub, lb;
    int     row, column;            // Table indices
    Vector2d    c[DEGREE+1];        // pts(i)'s - pt
    Vector2d    d[DEGREE];          // pts(i+1) - pts(i)
    float  cdTable[3][4];           // Dot product of c, d
    const float z[3][4] = {         // Precomputed "z" for cubics
        {1.0f, 0.6f, 0.3f, 0.1f},
        {0.4f, 0.6f, 0.6f, 0.4f},
        {0.1f, 0.3f, 0.6f, 1.0f},
    };


    // Determine the c's -- these are vectors created by subtracting
    // point pt from each of the control points
    for (i = 0; i <= DEGREE; i++) {
        c[i] = pts[i] - pt;
    }
    // Determine the d's -- these are vectors created by subtracting
    // each control point from the next
    for (i = 0; i <= DEGREE - 1; i++) {
        d[i] = 3.f * (pts[i+1] - pts[i]);
    }

    // Create the c,d table -- this is a table of dot products of the
    // c's and d's
    for (row = 0; row <= DEGREE - 1; row++) {
        for (column = 0; column <= DEGREE; column++) {
            cdTable[row][column] = d[row].dotProduct(c[column]);
        }
    }

    // Now, apply the z's to the dot products, on the skew diagonal
    // Also, set up the x-values, making these "points"
    for (i = 0; i <= W_DEGREE; i++) {
        w[i].y = 0.f;
        w[i].x = static_cast<float>(i) / W_DEGREE;
    }

    n = DEGREE;
    m = DEGREE-1;
    for (k = 0; k <= n + m; k++) {
        lb = mgMax(0, k - m);
        ub = mgMin(k, n);
        for (i = lb; i <= ub; i++) {
            j = k - i;
            w[i+j].y += cdTable[j][i] * z[j][i];
        }
    }
}
Ejemplo n.º 8
0
bool GiTransform::zoomByFactor(float factor, const Point2d* pxAt, bool adjust)
{
    float scale = m_impl->viewScale;
    if (factor > 0)
        scale *= (1.f + fabsf(factor));
    else
        scale /= (1.f + fabsf(factor));

    if (adjust) {
        scale = mgMax(scale, m_impl->minViewScale);
        scale = mgMin(scale, m_impl->maxViewScale);
    }
    if (mgEquals(scale, m_impl->viewScale))
        return false;
    return zoomScale(scale, pxAt, adjust);
}
Ejemplo n.º 9
0
bool GiGraphics::drawPathWithArrayHead(const GiContext& ctx, MgPath& path, int startArray, int endArray)
{
    float px = calcPenWidth(ctx.getLineWidth(), ctx.isAutoScale());
    float scale = 0.5f * xf().getWorldToDisplayX() * (1 + mgMax(0.f, (px - 4.f) / 5));
    
    if (startArray > 0 && startArray <= GiContext::kArrowOpenedCircle) {
        drawArrayHead(ctx, path, startArray, px, scale);
    }
    if (endArray > 0 && endArray <= GiContext::kArrowOpenedCircle) {
        path.reverse();
        drawArrayHead(ctx, path, endArray, px, scale);
        path.reverse();
    }
    
    return drawPath_(&ctx, path, false, Matrix2d::kIdentity());
}
Ejemplo n.º 10
0
bool MgCmdDrawRect::touchMoved(const MgMotion* sender)
{
    Point2d pt1(m_startPt);
    Point2d pt2(snapPoint(sender));
    MgBaseRect* shape = (MgBaseRect*)dynshape()->shape();
    
    if (shape->getFlag(kMgSquare)) {
        float len = (float)mgMax(fabs(pt2.x - pt1.x), fabs(pt2.y - pt1.y));
        Box2d rect(m_startPt, 2.f * len, 0);
        pt1 = rect.leftTop();
        pt2 = rect.rightBottom();
    }
    shape->setRect(pt1, pt2);
    dynshape()->shape()->update();

    return _touchMoved(sender);
}
Ejemplo n.º 11
0
bool GiTransform::zoomWnd(const Point2d& pt1, const Point2d& pt2, bool adjust)
{
    // 计算开窗矩形的中心和宽高
    Point2d ptCen ((pt2.x + pt1.x) * 0.5f, (pt2.y + pt1.y) * 0.5f);
    float w = fabs(static_cast<float>(pt2.x - pt1.x));
    float h = fabs(static_cast<float>(pt2.y - pt1.y));
    if (w < 4 || h < 4)
        return false;

    // 中心不变,扩大开窗矩形使得宽高比例和显示窗口相同
    if (h * m_impl->cxWnd > w * m_impl->cyWnd)
        w = h * m_impl->cxWnd / m_impl->cyWnd;
    else
        h = w * m_impl->cyWnd / m_impl->cxWnd;

    // 计算放缩前矩形中心的世界坐标
    Point2d ptW (ptCen * m_impl->matD2W);

    // 计算新显示比例
    float scale = m_impl->viewScale * m_impl->cyWnd / h;
    if (!adjust && ScaleOutRange(scale, m_impl))
        return false;
    scale = mgMax(scale, m_impl->minViewScale);
    scale = mgMin(scale, m_impl->maxViewScale);

    // 计算新显示比例下的显示窗口的世界坐标范围
    float halfw = m_impl->cxWnd / (m_impl->w2dx / m_impl->viewScale * scale) * 0.5f;
    float halfh = m_impl->cyWnd / (m_impl->w2dy / m_impl->viewScale * scale) * 0.5f;
    Box2d box (ptW, 2 * halfw, 2 * halfh);

    // 检查显示窗口的新坐标范围是否在极限范围内
    if (!m_impl->rectLimitsW.isEmpty() && !m_impl->rectLimitsW.contains(box))
    {
        if (adjust)
            AdjustCenterW(ptW, halfw, halfh, m_impl->rectLimitsW);
        else
            return false;
    }

    // 改变显示比例和位置
    return m_impl->zoomNoAdjust(ptW, scale);
}
Ejemplo n.º 12
0
bool GiTransform::zoomScale(float viewScale, const Point2d* pxAt, bool adjust)
{
    // 检查显示比例
    if (!adjust && ScaleOutRange(viewScale, m_impl))
        return false;
    viewScale = mgMax(viewScale, m_impl->minViewScale);
    viewScale = mgMin(viewScale, m_impl->maxViewScale);

    // 得到放缩中心点的客户区坐标
    Point2d ptAt (m_impl->cxWnd * 0.5f,  m_impl->cyWnd * 0.5f);
    if (pxAt != NULL)
        ptAt.set(pxAt->x, pxAt->y);

    // 得到放缩中心点在放缩前的世界坐标
    Point2d ptAtW (ptAt * m_impl->matD2W);

    // 计算新显示比例下显示窗口中心的世界坐标
    Point2d ptW;
    float w2dx = m_impl->w2dx / m_impl->viewScale * viewScale;
    float w2dy = m_impl->w2dy / m_impl->viewScale * viewScale;
    ptW.x = ptAtW.x + (m_impl->cxWnd * 0.5f - ptAt.x) / w2dx;
    ptW.y = ptAtW.y - (m_impl->cyWnd * 0.5f - ptAt.y) / w2dy;

    // 检查新显示比例下显示窗口的世界坐标范围是否在极限范围内
    float halfw = m_impl->cxWnd / w2dx * 0.5f;
    float halfh = m_impl->cyWnd / w2dy * 0.5f;
    Box2d box (ptW, 2 * halfw, 2 * halfh);

    if (!AdjustCenterIn(adjust, box, m_impl->rectLimitsW, ptW, halfw, halfh)) {
        return false;
    }
    if (halfw - 3 > m_impl->rectLimitsW.width() / 2
        && halfh - 3 > m_impl->rectLimitsW.height() / 2)    // 显示比例太小
    {
        viewScale *= mgMin(2 * (halfw - 3) / m_impl->rectLimitsW.width(),
            2 * (halfh - 3) / m_impl->rectLimitsW.height());
        viewScale = mgMin(viewScale, m_impl->maxViewScale);
    }

    return m_impl->zoomNoAdjust(ptW, viewScale);
}
Ejemplo n.º 13
0
bool GiTransform::zoom(Point2d centerW, float viewScale, bool* changed)
{
    viewScale = mgMax(viewScale, m_impl->minViewScale);
    viewScale = mgMin(viewScale, m_impl->maxViewScale);

    if (!m_impl->rectLimitsW.isEmpty())
    {
        float halfw = m_impl->cxWnd / m_impl->w2dx * 0.5f;
        float halfh = m_impl->cyWnd / m_impl->w2dy * 0.5f;

        if (centerW.x - halfw < m_impl->rectLimitsW.xmin)
            centerW.x += m_impl->rectLimitsW.xmin - (centerW.x - halfw);
        if (centerW.x + halfw > m_impl->rectLimitsW.xmax)
            centerW.x += m_impl->rectLimitsW.xmax - (centerW.x + halfw);
        if (2 * halfw >= m_impl->rectLimitsW.width())
            centerW.x = m_impl->rectLimitsW.center().x;

        if (centerW.y - halfh < m_impl->rectLimitsW.ymin)
            centerW.y += m_impl->rectLimitsW.ymin - (centerW.y - halfh);
        if (centerW.y + halfh > m_impl->rectLimitsW.ymax)
            centerW.y += m_impl->rectLimitsW.ymax - (centerW.y + halfh);
        if (2 * halfh >= m_impl->rectLimitsW.height())
            centerW.y = m_impl->rectLimitsW.center().y;

        // 如果显示比例很小使得窗口超界,就放大显示
        if (2 * halfw > m_impl->rectLimitsW.width()
            && 2 * halfh > m_impl->rectLimitsW.height())
        {
            viewScale *= mgMin(2 * halfw / m_impl->rectLimitsW.width(),
                2 * halfh / m_impl->rectLimitsW.height());
            if (viewScale > m_impl->maxViewScale)
                viewScale = m_impl->maxViewScale;
        }
    }

    m_impl->zoomNoAdjust(centerW, viewScale, changed);

    return true;
}
Ejemplo n.º 14
0
bool GiTransform::zoom(Point2d centerW, float viewScale)
{
    bool changed = false;

    viewScale = mgMax(viewScale, m_impl->minViewScale);
    viewScale = mgMin(viewScale, m_impl->maxViewScale);

    Box2d rectW(m_impl->rectLimitsW);
    rectW.inflate(2);
    float halfw = m_impl->cxWnd / m_impl->w2dx * 0.5f;
    float halfh = m_impl->cyWnd / m_impl->w2dy * 0.5f;

    if (centerW.x - halfw < rectW.xmin)
        centerW.x += rectW.xmin - (centerW.x - halfw);
    if (centerW.x + halfw > rectW.xmax)
        centerW.x += rectW.xmax - (centerW.x + halfw);
    if (2 * halfw >= rectW.width())
        centerW.x = rectW.center().x;

    if (centerW.y - halfh < rectW.ymin)
        centerW.y += rectW.ymin - (centerW.y - halfh);
    if (centerW.y + halfh > rectW.ymax)
        centerW.y += rectW.ymax - (centerW.y + halfh);
    if (2 * halfh >= rectW.height())
        centerW.y = rectW.center().y;

    // 如果显示比例很小使得窗口超界,就放大显示
    if (2 * halfw > rectW.width() && 2 * halfh > rectW.height()) {
        viewScale *= mgMin(2 * halfw / rectW.width(),
            2 * halfh / rectW.height());
        if (viewScale > m_impl->maxViewScale)
            viewScale = m_impl->maxViewScale;
    }

    m_impl->zoomNoAdjust(centerW, viewScale, &changed);

    return changed;
}
Ejemplo n.º 15
0
bool GiGraphics::setPen(const GiContext* ctx)
{
    bool changed = !(m_impl->ctxused & 1);
    
    if (m_impl->canvas) {
        if (ctx && (!mgEquals(ctx->getLineWidth(), m_impl->ctx.getLineWidth())
                    || ctx->isAutoScale() != m_impl->ctx.isAutoScale())) {
            m_impl->ctx.setLineWidth(ctx->getLineWidth(), ctx->isAutoScale());
            changed = true;
        }
        if (ctx && !mgEquals(ctx->getExtraWidth(), m_impl->ctx.getExtraWidth())) {
            m_impl->ctx.setExtraWidth(ctx->getExtraWidth());
            changed = true;
        }
        if (ctx && ctx->getLineColor() != m_impl->ctx.getLineColor()) {
            m_impl->ctx.setLineColor(ctx->getLineColor());
            changed = true;
        }
        if (ctx && ctx->getLineStyleEx() != m_impl->ctx.getLineStyleEx()) {
            m_impl->ctx.setLineStyle(ctx->getLineStyleEx(), true);
            changed = true;
        }
    }
    
    ctx = &(m_impl->ctx);
    if (m_impl->canvas && changed) {
        m_impl->ctxused &= 1;
        float w = calcPenWidth(ctx->getLineWidth(), ctx->isAutoScale());
        float orgw = ctx->getLineWidth();
        orgw = (orgw < -0.1f && ctx->isAutoScale()) ? orgw - 1e4f : orgw;
        m_impl->canvas->setPen(calcPenColor(ctx->getLineColor()).getARGB(),
                               w + ctx->getExtraWidth(),
                               ctx->getLineStyleEx(),
                               mgMax(m_impl->phase, 0.f), orgw);
    }
    
    return !ctx->isNullLine();
}
Ejemplo n.º 16
0
bool MgCmdDrawRect::touchEnded(const MgMotion* sender)
{
    Point2d pt1(m_startPt);
    Point2d pt2(snapPoint(sender));
    MgBaseRect* shape = (MgBaseRect*)dynshape()->shape();
    
    if (shape->getFlag(kMgSquare)) {
        float len = (float)mgMax(fabs(pt2.x - pt1.x), fabs(pt2.y - pt1.y));
        Box2d rect(m_startPt, 2.f * len, 0);
        pt1 = rect.leftTop();
        pt2 = rect.rightBottom();
    }
    shape->setRect(pt1, pt2);
    dynshape()->shape()->update();

    float minDist = mgDisplayMmToModel(5, sender);

    if (shape->getWidth() > minDist && shape->getHeight() > minDist) {
        addRectShape(sender);
    }

    return _touchEnded(sender);
}
Ejemplo n.º 17
0
bool GiTransform::zoomScale(float viewScale, const Point2d* pxAt, bool adjust)
{
    // 检查显示比例
    if (!adjust && ScaleOutRange(viewScale, m_impl))
        return false;
    viewScale = mgMax(viewScale, m_impl->minViewScale);
    viewScale = mgMin(viewScale, m_impl->maxViewScale);

    // 得到放缩中心点的客户区坐标
    Point2d ptAt (m_impl->cxWnd * 0.5f,  m_impl->cyWnd * 0.5f);
    if (pxAt != NULL)
        ptAt.set(pxAt->x, pxAt->y);

    // 得到放缩中心点在放缩前的世界坐标
    Point2d ptAtW (ptAt * m_impl->matD2W);

    // 计算新显示比例下显示窗口中心的世界坐标
    Point2d ptW;
    float w2dx = m_impl->w2dx / m_impl->viewScale * viewScale;
    float w2dy = m_impl->w2dy / m_impl->viewScale * viewScale;
    ptW.x = ptAtW.x + (m_impl->cxWnd * 0.5f - ptAt.x) / w2dx;
    ptW.y = ptAtW.y - (m_impl->cyWnd * 0.5f - ptAt.y) / w2dy;

    // 检查新显示比例下显示窗口的世界坐标范围是否在极限范围内
    float halfw = m_impl->cxWnd / w2dx * 0.5f;
    float halfh = m_impl->cyWnd / w2dy * 0.5f;
    Box2d box (ptW, 2 * halfw, 2 * halfh);
    if (!m_impl->rectLimitsW.isEmpty() && !m_impl->rectLimitsW.contains(box))
    {
        if (adjust)
            AdjustCenterW(ptW, halfw, halfh, m_impl->rectLimitsW);
        else
            return false;
    }

    return m_impl->zoomNoAdjust(ptW, viewScale);
}
Ejemplo n.º 18
0
bool MgBaseRect::isEmpty(float minDist) const
{
    return _points[2].distanceTo(_points[0]) < mgMax(minDist, _MGZERO);
}
Ejemplo n.º 19
0
// ControlPolygonFlatEnough :
//      Check if the control polygon of a Bezier curve is flat enough
//      for recursive subdivision to bottom out.
// Parameters :
//      pts: Control pts
//      degree: Degree of bezier curve
//
static int ControlPolygonFlatEnough(const Point2d* pts, int degree)
{
    int     i;                      // Index variable
    float  distance[W_DEGREE+1];   // Distances from pts to line
    float  max_distance_above;     // maximum of these
    float  max_distance_below;
    float  error;                  // Precision of root
    float  intercept_1,
        intercept_2,
        left_intercept,
        right_intercept;
    float  a, b, c;    // Coefficients of implicit eqn for line from pts[0]-pts[deg]

    // Find the  perpendicular distance
    // from each interior control point to
    // line connecting pts[0] and pts[degree]
    {
        float  abSquared;

        // Derive the implicit equation for line connecting first *'
        // and last control points
        a = pts[0].y - pts[degree].y;
        b = pts[degree].x - pts[0].x;
        c = pts[0].x * pts[degree].y - pts[degree].x * pts[0].y;

        abSquared = (a * a) + (b * b);

        for (i = 1; i < degree; i++)
        {
            // Compute distance from each of the points to that line
            distance[i] = a * pts[i].x + b * pts[i].y + c;
            if (distance[i] > 0.0) {
                distance[i] = (distance[i] * distance[i]) / abSquared;
            }
            if (distance[i] < 0.0) {
                distance[i] = -((distance[i] * distance[i]) / abSquared);
            }
        }
    }


    // Find the largest distance
    max_distance_above = 0.0;
    max_distance_below = 0.0;
    for (i = 1; i < degree; i++)
    {
        if (distance[i] < 0.0) {
            max_distance_below = mgMin(max_distance_below, distance[i]);
        };
        if (distance[i] > 0.0) {
            max_distance_above = mgMax(max_distance_above, distance[i]);
        }
    }

    {
        float  det, dInv;
        float  a1, b1, c1, a2, b2, c2;

        // Implicit equation for zero line
        a1 = 0.0;
        b1 = 1.0;
        c1 = 0.0;

        // Implicit equation for "above" line
        a2 = a;
        b2 = b;
        c2 = c + max_distance_above;

        det = a1 * b2 - a2 * b1;
        dInv = 1 / det;

        intercept_1 = (b1 * c2 - b2 * c1) * dInv;

        // Implicit equation for "below" line
        a2 = a;
        b2 = b;
        c2 = c + max_distance_below;

        det = a1 * b2 - a2 * b1;
        dInv = 1 / det;

        intercept_2 = (b1 * c2 - b2 * c1) * dInv;
    }

    // Compute intercepts of bounding box
    left_intercept = mgMin(intercept_1, intercept_2);
    right_intercept = mgMax(intercept_1, intercept_2);

    error = 0.5f * (right_intercept-left_intercept);
    if (error < _MGZERO) {
        return 1;
    }
    else {
        return 0;
    }
}
Ejemplo n.º 20
0
 void makeLinePattern(CGFloat* dest, const CGFloat* src, int n, float w)
 {
     for (int i = 0; i < n; i++) {
         dest[i] = src[i] * mgMax(w, 1.f);
     }
 }
Ejemplo n.º 21
0
bool GiTransform::zoomTo(const Box2d& rectWorld, const RECT_2D* rcTo, bool adjust)
{
    // 如果图形范围的宽或高接近于零,就返回
    if (rectWorld.isEmpty())
        return false;

    // 计算像素到毫米的比例
    const float d2mmX = m_impl->viewScale / m_impl->w2dx;
    const float d2mmY = m_impl->viewScale / m_impl->w2dy;

    // 计算目标窗口区域(毫米)
    float w = 0, h = 0;
    Point2d ptCen;

    if (rcTo != NULL) {
        w = fabsf(static_cast<float>(rcTo->right - rcTo->left));
        h = fabsf(static_cast<float>(rcTo->bottom - rcTo->top));
        ptCen.x = (rcTo->left + rcTo->right) * 0.5f;
        ptCen.y = (rcTo->top + rcTo->bottom) * 0.5f;
    }
    if (w < 4 || h < 4) {
        w = (float)m_impl->cxWnd;
        h = (float)m_impl->cyWnd;
        ptCen.set(w * 0.5f, h * 0.5f);
        w -= 8;
        h -= 8;
    }
    if (w < 4 || h < 4)
        return false;
    w *= d2mmX;
    h *= d2mmY;
    ptCen.scaleBy(d2mmX, d2mmY);

    // 计算新显示比例 (中心不变,缩小窗口区域使得宽高比例和图形范围相同)
    float scale;
    if (h * rectWorld.width() > w * rectWorld.height()) {
        //h = w * rectWorld.height() / rectWorld.width();
        scale = w / rectWorld.width();
    }
    else {
        //w = h * rectWorld.width() / rectWorld.height();
        scale = h / rectWorld.height();
    }

    // 检查显示比例
    if (!adjust && ScaleOutRange(scale, m_impl))
        return false;
    scale = mgMax(scale, m_impl->minViewScale);
    scale = mgMin(scale, m_impl->maxViewScale);

    // 计算在新显示比例下显示窗口中心的世界坐标
    Point2d ptW;
    ptW.x = rectWorld.center().x + (m_impl->cxWnd * d2mmX * 0.5f - ptCen.x) / scale;
    ptW.y = rectWorld.center().y - (m_impl->cyWnd * d2mmY * 0.5f - ptCen.y) / scale;

    // 检查新显示比例下显示窗口的世界坐标范围是否在极限范围内
    float halfw = m_impl->cxWnd * d2mmX  / scale * 0.5f;
    float halfh = m_impl->cyWnd * d2mmY  / scale * 0.5f;
    Box2d box (ptW, 2 * halfw, 2 * halfh);

    if (!AdjustCenterIn(adjust, box, m_impl->rectLimitsW, ptW, halfw, halfh)) {
        return false;
    }

    return m_impl->zoomNoAdjust(ptW, scale);
}