qt判定某个点是否在多边形区域内

550 阅读1分钟
QVector<QPointF> vpf;
    QPointF pfIn = QPointF(0,0);
    QPointF pf = QPointF(-10,-10);
    vpf.append(pf);
    pf = QPointF(10,-10);
    vpf.append(pf);
    pf = QPointF(10,10);
    vpf.append(pf);
    pf = QPointF(-10,10);
    vpf.append(pf);
    QPolygonF pol(vpf);
    qDebug()<<"pol:"<<pol;
    if(pol.contains(pfIn))
    {
        qDebug()<<"pol contains ptIn";
    }
    if(pol.containsPoint(pfIn,Qt::WindingFill))
    {
        qDebug()<<"pol containsPoint ptIn WindingFill";
    }

执行结果为,用containsPoint能判定到在区域内,而用contains则不行。

一般这种需求都是在mousepress函数内使用的,我的例程如下

void mygraphicCaliperitem::mousePressEvent(QGraphicsSceneMouseEvent *event)
```

```
{
```

```
    QList<QGraphicsItem *> items = scene()->items();
```

```
    for(int i = 0;i<items.count();i++)
```

```
    {
```

```
        ((mygraphicCaliperitem*)items[i])->m_bSelected = false;
```

```
    }
```

```
    this->m_bSelected=true;
```

```
    if(event->button()== Qt::LeftButton)
```

```
    {
```

```
        //setSelected(true);
```

```
        m_startPos = event->pos();//鼠标左击时,获取当前鼠标在图片中的坐标,
```

```
        if(m_ShapeType == CALIPER_RECT)//矩形卡尺
```

```
        {
```

```
            if(m_tCaliRect.m_RECT_Rotate_Pol.containsPoint(m_startPos,Qt::WindingFill))//旋转矩形
```

```
            {
```

```
                m_StateFlag = CALIPER_STATE_FLAG::CALI_RECT_ROTATE;
```

```
                setCursor(Qt::PointingHandCursor);
```

```
            }
```

```
            else if(m_tCaliRect.m_RECT_BR_Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CALI_RECT_BR;//标记当前为用户按下矩形的右下角顶点矩形区域
```

```
                setCursor(Qt::SizeAllCursor);
```

```
            }
```

```
            else if(m_tCaliRect.m_RECT_Shear_Pol.containsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下鼠标,则可拖动图片
```

```
            {
```

```
                m_StateFlag = CALIPER_STATE_FLAG::CALI_RECT_SHEAR;//标记当前为鼠标拖动图片移动状态
```

```
                setCursor(Qt::PointingHandCursor);   //改变光标形状,手指的形状
```

```
            }
```

```
            else if(m_tCaliRect.m_RECT_Inside_Pol.containsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下鼠标,则可拖动图片
```

```
            {
```

```
                m_StateFlag = CALIPER_STATE_FLAG::CALI_RECT_MOVE;//标记当前为鼠标拖动图片移动状态
```

```
                setCursor(Qt::ClosedHandCursor);   //改变光标形状,手的形状
```

```
            }
```

```
            else
```

```
            {
```

```
                m_StateFlag = CALI_DEFAULT;
```

```
            }
```

```
        }
```

```
        else if(m_ShapeType == CALIPER_LINE)//直线卡尺
```

```
        {
```

```
            int nCount = m_tCaliRectLst.count();
```

```
            for(int i=0;i<nCount;i++)
```

```
            {
```

```
                if((nCount+1)/2-1==i)//让中间那个矩形控制所有矩形的变换
```

```
                {
```

```
                    if(m_tCaliRectLst[i].m_RECT_Rotate_Pol.containsPoint(m_startPos,Qt::WindingFill))//旋转矩形
```

```
                    {
```

```
                        m_StateFlag = CALIPER_STATE_FLAG::CALI_RECT_ROTATE;
```

```
                        setCursor(Qt::PointingHandCursor);
```

```
                        return;
```

```
                    }
```

```
                    else if(m_tCaliRectLst[i].m_RECT_BR_Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
                    {
```

```
                        m_StateFlag = CALI_RECT_BR;//标记当前为用户按下矩形的右下角顶点矩形区域
```

```
                        setCursor(Qt::SizeAllCursor);
```

```
                        return;
```

```
                    }
```

```
                    else if(m_tCaliRectLst[i].m_RECT_Shear_Pol.containsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下鼠标,则可拖动图片
```

```
                    {
```

```
                        m_StateFlag = CALIPER_STATE_FLAG::CALI_RECT_SHEAR;//标记当前为切变状态
```

```
                        setCursor(Qt::PointingHandCursor);   //改变光标形状,手指的形状
```

```
                        return;
```

```
                    }
```

```
                }
```

```
            }
```

```
            if(m_LineBodyPol.containsPoint(m_startPos,Qt::WindingFill))//拖动直线
```

```
            {
```

```
                m_StateFlag = CALI_LINE_MOVE;//标记当前为直线卡尺的拖动
```

```
                setCursor(Qt::ClosedHandCursor);   //改变光标形状,手的形状
```

```
            }
```

```
            else if(m_LineP1Pol.containsPoint(m_startPos,Qt::WindingFill))//移动直线顶点1
```

```
            {
```

```
                m_StateFlag =CALI_LINE_PT1_MOVE;
```

```
                setCursor(Qt::SizeAllCursor);//变换鼠标形状
```

```
            }
```

```
            else if(m_LineP2Pol.containsPoint(m_startPos,Qt::WindingFill))//移动直线顶点1
```

```
            {
```

```
                m_StateFlag =CALI_LINE_PT2_MOVE;
```

```
                setCursor(Qt::SizeAllCursor);//变换鼠标形状
```

```
            }
```

```
            for(int i=0;i<nCount;i++)
```

```
            {
```

```
                if(m_tCaliRectLst[i].m_RECT_Inside_Pol.containsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下鼠标,则可拖动图片
```

```
                {
```

```
                    m_StateFlag = CALI_LINE_MOVE;//标记当前为直线卡尺的拖动
```

```
                    setCursor(Qt::ClosedHandCursor);   //改变光标形状,手的形状
```

```
                }
```

```
            }
```

```
        }
```

```
        else if(m_ShapeType == CALIPER_CIRCLE)
```

```
        {
```

```
            QPolygonF CirclePoly = QPolygonF(m_CircleRect);
```

```
            QPolygonF FillCircleP1Poly = QPolygonF(m_FillCircleP1Rect);
```

```
            QPolygonF FillCircleP3Poly = QPolygonF(m_FillCircleP3Rect);
```

```
            int nCount = m_tCaliRectLst.count();
```

```
            for(int i=0;i<nCount;i++)
```

```
            {
```

```
                if((nCount+1)/2-1==i)//让中间那个矩形控制所有矩形的变换
```

```
                {
```

```
                    if(m_tCaliRectLst[i].m_RECT_BR_Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
                    {
```

```
                        m_StateFlag = CALI_RECT_BR;//标记当前为用户按下矩形的右下角顶点矩形区域
```

```
                        setCursor(Qt::SizeAllCursor);
```

```
                        return;
```

```
                    }
```

```
                }
```

```
            }
```

```
            if(m_CircleP1Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CALI_CIRCLE_PT1_MOVE;
```

```
                setCursor(Qt::SizeAllCursor);//变换鼠标形状
```

```
                return;
```

```
            }
```

```
            else if(m_CircleP2Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CALI_CIRCLE_PT2_MOVE;
```

```
                setCursor(Qt::SizeAllCursor);//变换鼠标形状
```

```
                return;
```

```
            }
```

```
            else if(m_CircleP3Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CALI_CIRCLE_PT3_MOVE;
```

```
                setCursor(Qt::SizeAllCursor);//变换鼠标形状
```

```
                return;
```

```
            }
```

```
            else if(FillCircleP1Poly.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CALI_CIRCLE_FillP1;
```

```
                setCursor(Qt::PointingHandCursor);//变成手指形状
```

```
                return;
```

```
            }
```

```
            else if(FillCircleP3Poly.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CALI_CIRCLE_FillP3;
```

```
                setCursor(Qt::PointingHandCursor);//变成手指形状
```

```
                return;
```

```
            }
```

```
            else if(CirclePoly.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CALI_CIRCLE_MOVE;
```

```
                setCursor(Qt::ClosedHandCursor);//鼠标变成抓取的样式
```

```
                return;
```

```
            }
```

```
            for(int i=0;i<nCount;i++)
```

```
            {
```

```
                if(m_tCaliRectLst[i].m_RECT_Inside_Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
                {
```

```
                    m_StateFlag = CALI_CIRCLE_MOVE;//移动圆形卡尺
```

```
                    setCursor(Qt::ClosedHandCursor);
```

```
                    return;
```

```
                }
```

```
            }
```

```
        }
```

```
        else if(m_ShapeType == C_CIRCLE)//圆形
```

```
        {
```

```
            if(m_tCircle.m_RECT_BR_Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CIRCLE_SCALE;
```

```
                setCursor(Qt::SizeAllCursor);//鼠标变成上下左右箭头
```

```
                return;
```

```
            }
```

```
            else if(m_tCircle.m_RECT_Pol.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = CIRCLE_MOVE;
```

```
                setCursor(Qt::ClosedHandCursor);
```

```
            }
```

```
        }
```

```
        else if(m_ShapeType == C_ELLIPSE)//椭圆
```

```
        {
```

```
            if(m_tEllipse.m_RECT_Rotate_Pol.containsPoint(m_startPos,Qt::WindingFill))//旋转矩形
```

```
            {
```

```
                m_StateFlag = ELLIPSE_ROTATE;
```

```
                setCursor(Qt::PointingHandCursor);
```

```
            }
```

```
            else if(m_tEllipse.m_leftPolygon.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = ELLIPSE_LEFT_MOVE;
```

```
                setCursor(Qt::PointingHandCursor);//鼠标变成上下左右箭头
```

```
            }
```

```
            else if(m_tEllipse.m_topPolygon.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = ELLIPSE_TOP_MOVE;
```

```
                setCursor(Qt::PointingHandCursor);//鼠标变成上下左右箭头
```

```
            }
```

```
            else if(m_tEllipse.m_rightPolygon.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = ELLIPSE_RIGHT_MOVE;
```

```
                setCursor(Qt::PointingHandCursor);//鼠标变成上下左右箭头
```

```
            }
```

```
            else if(m_tEllipse.m_bottomPolygon.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = ELLIPSE_BOTTOM_MOVE;
```

```
                setCursor(Qt::PointingHandCursor);//鼠标变成上下左右箭头
```

```
            }
```

```
            else if(m_tEllipse.m_RECT_Inside_Pol.containsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下鼠标,则可拖动图片
```

```
            {
```

```
                m_StateFlag = ELLIPSE_MOVE;//标记当前为鼠标拖动图片移动状态
```

```
                setCursor(Qt::ClosedHandCursor);   //改变光标形状,手的形状
```

```
            }
```

```
            else
```

```
            {
```

```
                m_StateFlag = CALI_DEFAULT;
```

```
            }
```

```
        }
```

```
        else if(m_ShapeType==C_LINE)//直线
```

```
        {
```

```
            QPolygonF pol1 = QPolygonF(QRectF(m_Line.p1().x()-5,m_Line.p1().y()-5,10,10));
```

```
            QPolygonF pol2 = QPolygonF(QRectF(m_Line.p2().x()-5,m_Line.p2().y()-5,10,10));
```

```
            if(pol1.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = LINE_PT1_MOVE;
```

```
                setCursor(Qt::SizeAllCursor);
```

```
            }
```

```
            else if(pol2.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = LINE_PT2_MOVE;
```

```
                setCursor(Qt::SizeAllCursor);
```

```
            }
```

```
            else if(m_LinePol.containsPoint(m_startPos,Qt::WindingFill))
```

```
            {
```

```
                m_StateFlag = LINE_MOVE;
```

```
                setCursor(Qt::SizeAllCursor);
```

```
            }
```

```
        }
```

```
        else if(m_ShapeType == C_POLYGON)//多边形
```

```
        {
```

```
            m_nPolygonMovePointIndex = GetIndexOfMovePointInPolygon(m_startPos);
```

```
            if(m_nPolygonMovePointIndex>-1 && m_nPolygonMovePointIndex<m_oldPolygon.count())
```

```
            {
```

```
                m_StateFlag = POLYGON_POINT_MOVE;//移动多边形的某个点
```

```
                setCursor(Qt::PointingHandCursor);//设置鼠标形状
```

```
            }
```

```
            else if(m_oldPolygon.containsPoint(m_startPos,Qt::WindingFill))//如果在多边形内
```

```
            {
```

```
                m_StateFlag = POLYGON_MOVE;//移动多边形
```

```
                setCursor(Qt::ClosedHandCursor);   //改变光标形状,手的形状
```

```
            }
```

```
        }
```

```
        else if(m_ShapeType== C_MASK)
```

```
        {
```

```
            if(m_bStartMask)
```

```
            {
```

```
                m_vPoints.clear();
```

```
                m_vPoints.append(m_startPos);
```

```
            }
```

```
        }
```

```
    }
```

```
    else if(event->button()== Qt::RightButton)
```

```
    {
```

```
        m_startPos = event->pos();
```

```
        if(m_ShapeType==C_POLYGON)
```

```
        {
```

```
            m_nPolyRemoveIndex = GetIndexOfMovePointInPolygon(m_startPos);
```

```
            if(m_nPolyRemoveIndex>-1&&m_nPolyRemoveIndex<m_oldPolygon.count())//说明在顶点附近右击
```

```
            {
```

```
                //弹出的菜单只显示 删除顶点
```

```
                pMenu->actions()[0]->setVisible(false);
```

```
                pMenu->actions()[1]->setVisible(true);
```

```
                pMenu->exec(event->screenPos());//弹出菜单
```

```
            }
```

```
            else//说明不在顶点附近右击,弹出的菜单只显示 增加顶点
```

```
            {
```

```
                m_MinDis = 9999999;
```

```
                m_MapDis2Line.clear();
```

```
                for(int i = 0;i<m_oldPolygon.count();i++)
```

```
                {
```

```
                    QLineF line;
```

```
                    if(i<m_oldPolygon.count()-1)
```

```
                    {
```

```
                        line = QLineF(QPointF(m_oldPolygon[i]),QPointF(m_oldPolygon[i+1]));
```

```
                    }
```

```
                    else
```

```
                    {
```

```
                        line = QLineF(QPointF(m_oldPolygon[i]),QPointF(m_oldPolygon[0]));
```

```
                    }
```

```
                    qreal dis = CalDis(m_startPos.x(),m_startPos.y(),line.x1(),line.y1(),line.x2(),line.y2());
```

```
                    if(m_MinDis>dis)
```

```
                        m_MinDis = dis;//找到离那条线段距离最近距离
```

```
                    m_MapDis2Line.insert(dis,i);
```

```
                }
```

```
                pMenu->actions()[0]->setVisible(true);
```

```
                pMenu->actions()[1]->setVisible(false);
```

```
                pMenu->exec(event->screenPos());//弹出菜单 只显示增加顶点
```

```
            }
```

```
```

```
        }
```

```
    }
```

```
    else
```

```
    {
```

```
        QGraphicsItem::mousePressEvent(event);
```

```
    }
```

```
    scene()->update();
```

```
}