Example #1
0
void mgnear::getRectHandle(const Box2d& rect, int index, Point2d& pt)
{
    switch (index)
    {
    case 0: pt = rect.leftTop(); break;
    case 1: pt = rect.rightTop(); break;
    case 2: pt = rect.rightBottom(); break;
    case 3: pt = rect.leftBottom(); break;
    case 4: pt = Point2d(rect.center().x, rect.ymax); break;
    case 5: pt = Point2d(rect.xmax, rect.center().y); break;
    case 6: pt = Point2d(rect.center().x, rect.ymin); break;
    case 7: pt = Point2d(rect.xmin, rect.center().y); break;
    default: pt = rect.center(); break;
    }
}
Example #2
0
void mgcurv::roundRectToBeziers(
    Point2d points[16], const Box2d& rect, float rx, float ry)
{
    if (2 * rx > rect.width())
        rx = rect.width() / 2;
    if (2 * ry > rect.height())
        ry = rect.height() / 2;

    int i, j;
    float dx = rect.width() / 2 - rx;
    float dy = rect.height() / 2 - ry;

    mgcurv::ellipseToBezier(points, rect.center(), rx, ry);

    for (i = 3; i >= 1; i--)
    {
        for (j = 3; j >= 0; j--)
            points[4 * i + j] = points[3 * i + j];
    }
    for (i = 0; i < 4; i++)
    {
        float dx1 = (0 == i || 3 == i) ? dx : -dx;
        float dy1 = (0 == i || 1 == i) ? dy : -dy;
        for (j = 0; j < 4; j++)
            points[4 * i + j].offset(dx1, dy1);
    }
}
Example #3
0
static void AdjustCenterW(Point2d &ptW, float halfw, float halfh, 
                          const Box2d& rectW)
{
    if (ptW.x - halfw < rectW.xmin)
        ptW.x += rectW.xmin - (ptW.x - halfw);
    if (ptW.x + halfw > rectW.xmax)
        ptW.x += rectW.xmax - (ptW.x + halfw);
    if (2 * halfw >= rectW.width())
        ptW.x = rectW.center().x;

    if (ptW.y - halfh < rectW.ymin)
        ptW.y += rectW.ymin - (ptW.y - halfh);
    if (ptW.y + halfh > rectW.ymax)
        ptW.y += rectW.ymax - (ptW.y + halfh);
    if (2 * halfh >= rectW.height())
        ptW.y = rectW.center().y;
}
Example #4
0
bool GiTransformImpl::zoomPanAdjust(Point2d &ptW, float dxPixel, float dyPixel) const
{
    bool bAdjusted = false;
    float halfw = cxWnd / w2dx * 0.5f;
    float halfh = cyWnd / w2dy * 0.5f;

    if (dxPixel > 0 && ptW.x - halfw < rectLimitsW.xmin)
    {
        bAdjusted = true;
        ptW.x += rectLimitsW.xmin - (ptW.x - halfw);
    }
    if (dxPixel < 0 && ptW.x + halfw > rectLimitsW.xmax)
    {
        bAdjusted = true;
        ptW.x += rectLimitsW.xmax - (ptW.x + halfw);
    }
    if (fabs(dxPixel) > 0 && 2 * halfw >= rectLimitsW.width())
    {
        bAdjusted = true;
        ptW.x = rectLimitsW.center().x;
    }
    if (dyPixel < 0 && ptW.y - halfh < rectLimitsW.ymin)
    {
        bAdjusted = true;
        ptW.y += rectLimitsW.ymin - (ptW.y - halfh);
    }
    if (dyPixel > 0 && ptW.y + halfh > rectLimitsW.ymax)
    {
        bAdjusted = true;
        ptW.y += rectLimitsW.ymax - (ptW.y + halfh);
    }
    if (fabs(dyPixel) > 0 && 2 * halfh >= rectLimitsW.height())
    {
        bAdjusted = true;
        ptW.y = rectLimitsW.center().y;
    }

    return bAdjusted;
}
Example #5
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;
    }
}
Example #6
0
static void _RoundRectHit(
    const Box2d& rect, float rx, float ry, 
    const Point2d& pt, float tol, const Box2d &rectTol, 
    Point2d* pts, float& distMin, 
    Point2d& nearpt, int& segment)
{
    Point2d ptsBezier[13], ptTemp;
    Vector2d vec;
    float dx = rect.width() * 0.5f - rx;
    float dy = rect.height() * 0.5f - ry;
    
    // 按逆时针方向从第一象限到第四象限连接的四段
    mgcurv::ellipseToBezier(ptsBezier, rect.center(), rx, ry);
    
    pts[3] = ptsBezier[0];
    for (int i = 0; i < 4; i++)
    {
        pts[0] = pts[3];
        pts[1] = ptsBezier[3 * i];
        pts[2] = ptsBezier[3 * i + 1];
        pts[3] = ptsBezier[3 * i + 2];
        
        switch (i)
        {
        case 0: vec.set(dx, dy); break;
        case 1: vec.set(-dx, dy); break;
        case 2: vec.set(-dx, -dy); break;
        case 3: vec.set(dx, -dy); break;
        }
        
        for (int j = 0; j < 4; j++)
            pts[j] += vec;
        
        if (rectTol.isIntersect(Box2d(4, pts)))
        {
            mgnear::nearestOnBezier(pt, pts, ptTemp);
            float dist = pt.distanceTo(ptTemp);
            if (dist <= tol && dist < distMin)
            {
                distMin = dist;
                nearpt = ptTemp;
                segment = (5 - i) % 4;
            }
        }
        
        pts[3] -= vec;
    }
}
Example #7
0
    Box2d calcButtonPosition(mgvector<float>& pos, int n, const Box2d& selbox)
    {
        Box2d rect;

        for (int i = 0; i < n; i++) {
            switch (i)
            {
            case 0:
                if (n == 1) {
                    pos.set(2 * i, selbox.center().x, selbox.ymin); // MT
                } else {
                    pos.set(2 * i, selbox.xmin, selbox.ymin);       // LT
                }
                break;
            case 1:
                if (n == 3) {
                    pos.set(2 * i, selbox.center().x, selbox.ymin); // MT
                } else {
                    pos.set(2 * i, selbox.xmax, selbox.ymin);       // RT
                }
                break;
            case 2:
                if (n == 3) {
                    pos.set(2 * i, selbox.xmax, selbox.ymin);       // RT
                } else {
                    pos.set(2 * i, selbox.xmax, selbox.ymax);       // RB
                }
                break;
            case 3:
                pos.set(2 * i, selbox.xmin, selbox.ymax);           // LB
                break;
            case 4:
                pos.set(2 * i, selbox.center().x, selbox.ymin);     // MT
                break;
            case 5:
                pos.set(2 * i, selbox.center().x, selbox.ymax);     // MB
                break;
            case 6:
                pos.set(2 * i, selbox.xmax, selbox.center().y);     // RM
                break;
            case 7:
                pos.set(2 * i, selbox.xmin, selbox.center().y);     // LM
                break;
            default:
                return rect;
            }
            rect.unionWith(Box2d(Point2d(pos.get(2 * i), pos.get(2 * i + 1)), 32, 32));
        }

        return rect;
    }
Example #8
0
bool GiCanvasIos::drawImage(CGImageRef image, const Box2d& rectM)
{
    CGContextRef context = m_draw->getContext();
    bool ret = false;
    
    if (context && image) {
        Point2d ptD = rectM.center() * m_draw->xf().modelToDisplay();
        Box2d rect = rectM * m_draw->xf().modelToDisplay();
        
        CGAffineTransform af = CGAffineTransformMake(1, 0, 0, -1, 0, m_draw->height());
        af = CGAffineTransformTranslate(af, ptD.x - rect.width() * 0.5f, 
                                        m_draw->height() - (ptD.y + rect.height() * 0.5f));
        
        CGContextConcatCTM(context, af);
        CGContextDrawImage(context, CGRectMake(0, 0, rect.width(), rect.height()), image);
        CGContextConcatCTM(context, CGAffineTransformInvert(af));
        ret = true;
    }
    
    return ret;
}
Example #9
0
bool MgPath::crossWithPath(const MgPath& p, const Box2d& box, Point2d& ptCross) const
{
    MgPathCrossCallback cc(box, ptCross);
    
    if (isLine() && p.isLine()) {
        return (mglnrel::cross2Line(getPoint(0), getPoint(1),
                                    p.getPoint(0), p.getPoint(1), ptCross)
                && box.contains(ptCross));
    }
    if (isLines() && p.isLines()) {
        for (int m = getCount() - (isClosed() ? 0 : 1), i = 0; i < m; i++) {
            Point2d a(getPoint(i)), b(getPoint(i + 1));
            
            for (int n = p.getCount() - (p.isClosed() ? 0 : 1), j = 0; j < n; j++) {
                Point2d c(p.getPoint(j)), d(p.getPoint(j + 1));
                
                if (mglnrel::cross2Line(a, b, c, d, cc.tmpcross)
                    && box.contains(cc.tmpcross)) {
                    float dist = cc.tmpcross.distanceTo(box.center());
                    if (cc.mindist > dist) {
                        cc.mindist = dist;
                        ptCross = cc.tmpcross;
                    }
                }
            }
        }
    }
    else if (isLine() && p.getSubPathCount() == 1) {
        cc.a = getPoint(0);
        cc.b = getPoint(1);
        p.scanSegments(cc);
    }
    else if (p.isLine() && getSubPathCount() == 1) {
        cc.a = p.getPoint(0);
        cc.b = p.getPoint(1);
        scanSegments(cc);
    }
    
    return cc.mindist < box.width();
}
Example #10
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);
}
Example #11
0
bool GiGraphics::drawEllipse(const GiContext* ctx, const Box2d& rect, bool modelUnit)
{
    return drawEllipse(ctx, rect.center(), rect.width() / 2, rect.height() / 2, modelUnit);
}