zoukankan      html  css  js  c++  java
  • Qt 通过重写QGraphicItem实现绘制、拖动、缩放、旋转矩形

    本例程通过重写了一个类,继承自QGraphicItem,来实现了在qgraphicsScene上绘制、拖动、缩放、旋转矩形。
    效果如下:
    在这里插入图片描述

    其实要实现绘制、拖动、缩放矩形都不难,难的是在旋转之后还要支持缩放。
    我的思路是:
    1.实现绘制矩形:只要定义一个全局变量QRectF m_oldRect,在外面矩形大小传进来,然后在paint函数里面绘制这个矩形就行
    2.实现拖动矩形:重写mousePressEvent,mouseMoveEvent,mouseReleaseEvent,记录鼠标按下的起始点和移动时候的点,并用moveBy()函数来移动矩形即可
    3.实现缩放:在矩形内部靠近4条边的地方定义4个矩形,当鼠标按下的时候在这4个矩形方框内,则将矩形往4个方向拉伸
    4.实现旋转:
    我给之前定义的矩形全部配一个QPolygonF,因为我只能通过绘制多边形的方式来画出旋转之后的矩形。
    矩形正上方的圆圈我是通过三角函数+直线方程来计算,让其始终绘制在矩形左右两个顶点的中垂线上方。
    当鼠标落在圆形内部的时候可以控制矩形旋转。
    在矩形旋转之后,再进行拉伸的时候,我是通过的计算鼠标的点离对面的边的距离来重新计算矩形的大小,然后计算对应的QPolygonF的大小。

    主要代码如下:
    mygraphicrectitem.h

     1 #ifndef MYGRAPHICRECTITEM_H
     2 #define MYGRAPHICRECTITEM_H
     3 #include <QObject>
     4 #include <QWidget>
     5 #include <QMouseEvent>
     6 #include <QGraphicsScene>
     7 #include <QGraphicsRectItem>
     8 #include <QGraphicsSceneMouseEvent>
     9 #include <QRect>
    10 #include <QPainter>
    11 #include <QPolygon>
    12 #include <QList>
    13 enum STATE_FLAG{
    14     DEFAULT_FLAG=0,
    15     MOV_LEFT_LINE,//标记当前为用户按下矩形的左边界区域
    16     MOV_TOP_LINE,//标记当前为用户按下矩形的上边界区域
    17     MOV_RIGHT_LINE,//标记当前为用户按下矩形的右边界区域
    18     MOV_BOTTOM_LINE,//标记当前为用户按下矩形的下边界区域
    19     MOV_RIGHTBOTTOM_RECT,//标记当前为用户按下矩形的右下角
    20     MOV_RECT,//标记当前为鼠标拖动图片移动状态
    21     ROTATE//标记当前为旋转状态
    22 };
    23 class myGraphicRectItem:public QObject,public QGraphicsItem
    24 {
    25     Q_OBJECT
    26 public:
    27     myGraphicRectItem(QGraphicsItem *parent = nullptr);
    28     //myGraphicRectItem(QRectF m_OriginRect = QRectF(0,0,100,100));
    29     QRectF  boundingRect() const;
    30     ~myGraphicRectItem();
    31     void setRectSize(QRectF mrect,bool bResetRotateCenter = true);
    32     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    33     void mousePressEvent(QGraphicsSceneMouseEvent *event);
    34     void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    35     void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    36     void SetRotate(qreal RotateAngle,QPointF ptCenter=QPointF(-999,-999));
    37     QPointF getRotatePoint(QPointF ptCenter, QPointF ptIn, qreal angle);//获取旋转后的点
    38     QList<QPointF> getRotatePoints(QPointF ptCenter,QList<QPointF> ptIns,qreal angle);//获取多个旋转后的点
    39     QPolygonF getRotatePolygonFromRect(QPointF ptCenter,QRectF rectIn,qreal angle);//将矩形旋转之后返回多边形
    40     QRectF getCrtPosRectToSceen();
    41     QRectF m_SmallRotateRect;//矩形顶部用来表示旋转的标记的矩形
    42     QPolygonF m_SmallRotatePolygon;//矩形顶部用来表示旋转的标记的矩形旋转后形成的多边形
    43     QPointF getSmallRotateRectCenter(QPointF ptA,QPointF ptB);//获取旋转时候矩形正上方的旋转标记矩形
    44     QRectF  getSmallRotateRect(QPointF ptA,QPointF ptB);
    45     bool    m_bRotate;
    46     qreal   m_RotateAngle;
    47     QPointF m_RotateCenter;
    48 
    49 private:
    50     QRectF  m_oldRect;
    51     QPolygonF m_oldRectPolygon;
    52     QRectF  m_RotateAreaRect;
    53     bool    m_bResize;
    54     QPolygonF m_insicedPolygon;
    55     QRectF  m_insicedRectf;
    56     QPolygonF m_leftPolygon;
    57     QRectF  m_leftRectf;
    58     QPolygonF m_topPolygon;
    59     QRectF  m_topRectf;
    60     QPolygonF m_rightPolygon;
    61     QRectF  m_rightRectf;
    62     QPolygonF m_bottomPolygon;
    63     QRectF  m_bottomRectf;
    64 //    QPolygonF m_rbPolygon;
    65 //    QRectF  m_rbRectf;
    66     QPointF m_startPos;
    67     STATE_FLAG m_StateFlag;
    68     QPointF *pPointFofSmallRotateRect;
    69 protected:
    70 
    71 };
    72 #endif // MYGRAPHICRECTITEM_H

    mygraphicrectitem.cpp

      1 #include "mygraphicrectitem.h"
      2 #include <QtMath>
      3 #include <QDebug>
      4 
      5 myGraphicRectItem::myGraphicRectItem(QGraphicsItem *parent):
      6     m_bResize(false),
      7     m_oldRect(0,0,100,100),
      8     m_bRotate(false),
      9     m_RotateAngle(0),
     10     m_StateFlag(DEFAULT_FLAG)
     11 {
     12     //setParent(parent);
     13     setRectSize(m_oldRect);
     14     setToolTip("Click and drag me!");  //提示
     15     setCursor(Qt::ArrowCursor);   //改变光标形状,手的形状
     16     setFlag(QGraphicsItem::ItemIsMovable);
     17     //    setAcceptDrops(true);
     18     pPointFofSmallRotateRect = new QPointF[4];
     19     SetRotate(0);
     20     setFlag(QGraphicsItem::ItemIsSelectable);//
     21 }
     22 
     23 QRectF myGraphicRectItem::boundingRect() const
     24 {
     25     //return m_oldRectPolygon.boundingRect();
     26     QRectF boundingRectF = m_oldRectPolygon.boundingRect();
     27     return QRectF(boundingRectF.x()-40,boundingRectF.y()-40,boundingRectF.width()+80,boundingRectF.height()+80);
     28 }
     29 
     30 myGraphicRectItem::~myGraphicRectItem()
     31 {
     32     delete []pPointFofSmallRotateRect;
     33     pPointFofSmallRotateRect = nullptr;
     34 }
     35 
     36 void myGraphicRectItem::setRectSize(QRectF mrect, bool bResetRotateCenter)
     37 {
     38     m_oldRect = mrect;
     39     if(bResetRotateCenter)
     40     {
     41         m_RotateCenter.setX(m_oldRect.x()+m_oldRect.width()/2);
     42         m_RotateCenter.setY(m_oldRect.y()+m_oldRect.height()/2);
     43     }
     44     m_oldRectPolygon = getRotatePolygonFromRect(m_RotateCenter,m_oldRect,m_RotateAngle);
     45 
     46     m_insicedRectf = QRectF(m_oldRect.x()+8,m_oldRect.y()+8,m_oldRect.width()-16,m_oldRect.height()-16);
     47     m_insicedPolygon =getRotatePolygonFromRect(m_RotateCenter,m_insicedRectf,m_RotateAngle);
     48 
     49     m_leftRectf = QRectF(m_oldRect.x(),m_oldRect.y(),8,m_oldRect.height()-8);
     50     m_leftPolygon = getRotatePolygonFromRect(m_RotateCenter,m_leftRectf,m_RotateAngle);
     51 
     52     m_topRectf = QRectF(m_oldRect.x()+8,m_oldRect.y(),m_oldRect.width()-8,8);
     53     m_topPolygon = getRotatePolygonFromRect(m_RotateCenter,m_topRectf,m_RotateAngle);
     54 
     55     m_rightRectf = QRectF(m_oldRect.right()-8,m_oldRect.y()+8,8,m_oldRect.height()-16);
     56     m_rightPolygon = getRotatePolygonFromRect(m_RotateCenter,m_rightRectf,m_RotateAngle);
     57 
     58     m_bottomRectf = QRectF(m_oldRect.x(),m_oldRect.bottom()-8,m_oldRect.width()-8,8);
     59     m_bottomPolygon = getRotatePolygonFromRect(m_RotateCenter,m_bottomRectf,m_RotateAngle);
     60 
     61 //    m_rbRectf = QRectF(m_oldRect.right()-8,m_oldRect.bottom()-8,8,8);
     62 //    m_rbPolygon = getRotatePolygonFromRect(m_RotateCenter,m_rbRectf,m_RotateAngle);
     63 
     64     m_SmallRotateRect = getSmallRotateRect(mrect.topLeft(),mrect.topRight());//矩形正上方的旋转标记矩形
     65     m_SmallRotatePolygon = getRotatePolygonFromRect(m_RotateCenter,m_SmallRotateRect,m_RotateAngle);
     66 }
     67 
     68 void myGraphicRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
     69 {
     70     QPen mPen = QPen(Qt::yellow);
     71     painter->setPen(mPen);
     72     //绘制旋转后的矩形
     73     painter->drawPolygon(m_oldRectPolygon);
     74     //绘制旋转圆形
     75     mPen.setWidth(2);
     76     mPen.setColor(Qt::green);
     77     painter->setPen(mPen);
     78     QPointF pf = getSmallRotateRectCenter(m_oldRectPolygon[0],m_oldRectPolygon[1]);
     79     QRectF rect = QRectF(pf.x()-10,pf.y()-10,20,20);
     80     painter->drawEllipse(rect);//绘制圆形
     81     painter->drawPoint(pf);//绘制点
     82 }
     83 
     84 void myGraphicRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
     85 {
     86     if(event->button()== Qt::LeftButton)
     87     {
     88         m_startPos = event->pos();//鼠标左击时,获取当前鼠标在图片中的坐标,
     89         if(m_SmallRotatePolygon.containsPoint(m_startPos,Qt::WindingFill))//旋转矩形
     90         {
     91             setCursor(Qt::PointingHandCursor);
     92             m_StateFlag = ROTATE;
     93         }
     94         else if(m_insicedPolygon.containsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下鼠标,则可拖动图片
     95         {
     96             setCursor(Qt::ClosedHandCursor);   //改变光标形状,手的形状
     97             m_StateFlag = MOV_RECT;//标记当前为鼠标拖动图片移动状态
     98         }
     99         else if(m_leftPolygon.containsPoint(m_startPos,Qt::WindingFill))
    100         {
    101             setCursor(Qt::SizeHorCursor);
    102             m_StateFlag = MOV_LEFT_LINE;//标记当前为用户按下矩形的左边界区域
    103         }
    104         else if(m_rightPolygon.containsPoint(m_startPos,Qt::WindingFill))
    105         {
    106             setCursor(Qt::SizeHorCursor);
    107             m_StateFlag = MOV_RIGHT_LINE;//标记当前为用户按下矩形的右边界区域
    108         }
    109         else if(m_topPolygon.containsPoint(m_startPos,Qt::WindingFill))
    110         {
    111             setCursor(Qt::SizeVerCursor);
    112             m_StateFlag = MOV_TOP_LINE;//标记当前为用户按下矩形的上边界区域
    113         }
    114         else if(m_bottomPolygon.containsPoint(m_startPos,Qt::WindingFill))
    115         {
    116             setCursor(Qt::SizeVerCursor);
    117             m_StateFlag = MOV_BOTTOM_LINE;//标记当前为用户按下矩形的下边界区域
    118         }
    119 //        else if(m_rbPolygon.containsPoint(m_startPos,Qt::WindingFill))
    120 //        {
    121 //            setCursor(Qt::SizeFDiagCursor);
    122 //            m_StateFlag = MOV_RIGHTBOTTOM_RECT;//标记当前为用户按下矩形的右下角
    123 //        }
    124         else
    125         {
    126             m_StateFlag = DEFAULT_FLAG;
    127         }
    128     }
    129     else
    130     {
    131         QGraphicsItem::mousePressEvent(event);
    132     }
    133 }
    134 
    135 void myGraphicRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    136 {
    137     if(m_StateFlag == ROTATE)
    138     {
    139        int nRotateAngle = atan2((event->pos().x()-m_RotateCenter.x()),(event->pos().y()-m_RotateCenter.y()))*180/M_PI;
    140        SetRotate(180-nRotateAngle);
    141        setRectSize(m_oldRect);
    142        //qDebug()<<nRotateAngle;
    143     }
    144     else if(m_StateFlag == MOV_RECT)
    145     {
    146         QPointF point = (event->pos() - m_startPos);
    147         moveBy(point.x(), point.y());
    148         setRectSize(m_oldRect);
    149         scene()->update();
    150     }
    151     else if(m_StateFlag == MOV_LEFT_LINE)
    152     {
    153         QPointF pf = QPointF((m_oldRectPolygon.at(1).x()+m_oldRectPolygon.at(2).x())/2,((m_oldRectPolygon.at(1).y()+m_oldRectPolygon.at(2).y())/2));
    154         //计算到右侧边中点的距离
    155         qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
    156         qreal dis2LT = sqrt((event->pos().x()-m_oldRectPolygon.at(0).x())*(event->pos().x()-m_oldRectPolygon.at(0).x()) +(event->pos().y()-m_oldRectPolygon.at(0).y())*(event->pos().y()-m_oldRectPolygon.at(0).y()));
    157         qreal dis2RT = sqrt((event->pos().x()-m_oldRectPolygon.at(1).x())*(event->pos().x()-m_oldRectPolygon.at(1).x()) +(event->pos().y()-m_oldRectPolygon.at(1).y())*(event->pos().y()-m_oldRectPolygon.at(1).y()));
    158         if(dis<16||dis2LT>dis2RT)
    159         {
    160             return;
    161         }
    162         else
    163         {
    164             QRectF newRect(m_oldRect);
    165             newRect.setLeft(m_oldRect.right()-dis);
    166             newRect.setRight(m_oldRect.right());
    167             setRectSize(newRect,false);
    168             m_RotateCenter=QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(2).x())/2,(m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(2).y())/2);
    169             m_oldRect.moveCenter(m_RotateCenter);
    170             setRectSize(m_oldRect);
    171             scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
    172         }
    173     }
    174     else if(m_StateFlag == MOV_TOP_LINE)
    175     {
    176         //底边中点
    177         QPointF pf = QPointF((m_oldRectPolygon.at(2).x()+m_oldRectPolygon.at(3).x())/2,((m_oldRectPolygon.at(2).y()+m_oldRectPolygon.at(3).y())/2));
    178         //计算到底边中点的距离
    179         qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
    180         qreal dis2LT = sqrt((event->pos().x()-m_oldRectPolygon.at(0).x())*(event->pos().x()-m_oldRectPolygon.at(0).x()) +(event->pos().y()-m_oldRectPolygon.at(0).y())*(event->pos().y()-m_oldRectPolygon.at(0).y()));
    181         qreal dis2LB = sqrt((event->pos().x()-m_oldRectPolygon.at(3).x())*(event->pos().x()-m_oldRectPolygon.at(3).x()) +(event->pos().y()-m_oldRectPolygon.at(3).y())*(event->pos().y()-m_oldRectPolygon.at(3).y()));
    182         if(dis<16||dis2LT>dis2LB)
    183         {
    184             return;
    185         }
    186         else
    187         {
    188             QRectF newRect(m_oldRect);
    189             newRect.setTop(m_oldRect.bottom()-dis);
    190             newRect.setBottom(m_oldRect.bottom());
    191             setRectSize(newRect,false);
    192             m_RotateCenter=QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(2).x())/2,(m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(2).y())/2);
    193             m_oldRect.moveCenter(m_RotateCenter);
    194             setRectSize(m_oldRect);
    195             scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
    196         }
    197     }
    198     else if(m_StateFlag == MOV_RIGHT_LINE)
    199     {
    200         QPointF pf = QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(3).x())/2,((m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(3).y())/2));
    201         //计算到左侧边中点的距离
    202         qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
    203         qreal dis2LT = sqrt((event->pos().x()-m_oldRectPolygon.at(0).x())*(event->pos().x()-m_oldRectPolygon.at(0).x()) +(event->pos().y()-m_oldRectPolygon.at(0).y())*(event->pos().y()-m_oldRectPolygon.at(0).y()));
    204         qreal dis2RT = sqrt((event->pos().x()-m_oldRectPolygon.at(1).x())*(event->pos().x()-m_oldRectPolygon.at(1).x()) +(event->pos().y()-m_oldRectPolygon.at(1).y())*(event->pos().y()-m_oldRectPolygon.at(1).y()));
    205         if(dis<16||dis2LT<dis2RT)
    206         {
    207             return;
    208         }
    209         else
    210         {
    211             QRectF newRect(m_oldRect);
    212             newRect.setLeft(m_oldRect.left());
    213             newRect.setRight(m_oldRect.left()+dis);
    214             setRectSize(newRect,false);
    215             m_RotateCenter=QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(2).x())/2,(m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(2).y())/2);
    216             m_oldRect.moveCenter(m_RotateCenter);
    217             setRectSize(m_oldRect);
    218             scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
    219         }
    220     }
    221     else if(m_StateFlag == MOV_BOTTOM_LINE)
    222     {
    223         //顶边中点
    224         QPointF pf = QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(1).x())/2,((m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(1).y())/2));
    225         //计算到底边中点的距离
    226         qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
    227         qreal dis2LT = sqrt((event->pos().x()-m_oldRectPolygon.at(0).x())*(event->pos().x()-m_oldRectPolygon.at(0).x()) +(event->pos().y()-m_oldRectPolygon.at(0).y())*(event->pos().y()-m_oldRectPolygon.at(0).y()));
    228         qreal dis2LB = sqrt((event->pos().x()-m_oldRectPolygon.at(3).x())*(event->pos().x()-m_oldRectPolygon.at(3).x()) +(event->pos().y()-m_oldRectPolygon.at(3).y())*(event->pos().y()-m_oldRectPolygon.at(3).y()));
    229         if(dis<16||dis2LT<dis2LB)
    230         {
    231             return;
    232         }
    233         else
    234         {
    235             QRectF newRect(m_oldRect);
    236             newRect.setTop(m_oldRect.top());
    237             newRect.setBottom(m_oldRect.top()+dis);
    238             setRectSize(newRect,false);
    239             m_RotateCenter=QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(2).x())/2,(m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(2).y())/2);
    240             m_oldRect.moveCenter(m_RotateCenter);
    241             setRectSize(m_oldRect);
    242             scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
    243         }
    244     }
    245 }
    246 
    247 void myGraphicRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    248 {
    249     setCursor(Qt::ArrowCursor);
    250     if(m_StateFlag == MOV_RECT)
    251     {
    252         m_StateFlag = DEFAULT_FLAG;
    253     }
    254     else {
    255         QGraphicsItem::mouseReleaseEvent(event);
    256     }
    257 }
    258 
    259 void myGraphicRectItem::SetRotate(qreal RotateAngle, QPointF ptCenter)
    260 {
    261     m_bRotate = true;
    262     if(ptCenter.x()==-999 && ptCenter.y()==-999)
    263     {
    264         m_RotateCenter = QPointF(m_oldRect.x()+m_oldRect.width()/2,m_oldRect.y()+m_oldRect.height()/2);
    265     }
    266     else
    267     {
    268         m_RotateCenter = ptCenter;
    269     }
    270     m_RotateAngle = RotateAngle;
    271     this->update();
    272 }
    273 
    274 QPointF myGraphicRectItem::getRotatePoint(QPointF ptCenter, QPointF ptIn, qreal angle)
    275 {
    276     double dx = ptCenter.x();
    277     double dy = ptCenter.y();
    278     double x = ptIn.x();
    279     double y = ptIn.y();
    280     double xx,yy;
    281     xx = (x-dx)*cos(angle*M_PI/180)-(y-dy)*sin(angle*M_PI/180)+dx;
    282     yy = (x-dx)*sin(angle*M_PI/180)+(y-dy)*cos(angle*M_PI/180)+dy;
    283 
    284     return QPointF(xx,yy);
    285 }
    286 
    287 QList<QPointF> myGraphicRectItem::getRotatePoints(QPointF ptCenter, QList<QPointF> ptIns, qreal angle)
    288 {
    289     QList<QPointF> lstPt;
    290     for(int i = 0;i<ptIns.count();i++)
    291     {
    292         lstPt.append(getRotatePoint(ptCenter,ptIns.at(i),angle));
    293     }
    294     return lstPt;
    295 }
    296 
    297 QPolygonF myGraphicRectItem::getRotatePolygonFromRect(QPointF ptCenter, QRectF rectIn, qreal angle)
    298 {
    299     QVector<QPointF> vpt;
    300     QPointF pf = getRotatePoint(ptCenter,rectIn.topLeft(),angle);
    301     vpt.append(pf);
    302     pf = getRotatePoint(ptCenter,rectIn.topRight(),angle);
    303     vpt.append(pf);
    304     pf = getRotatePoint(ptCenter,rectIn.bottomRight(),angle);
    305     vpt.append(pf);
    306     pf = getRotatePoint(ptCenter,rectIn.bottomLeft(),angle);
    307     vpt.append(pf);
    308     pf = getRotatePoint(ptCenter,rectIn.topLeft(),angle);
    309     vpt.append(pf);
    310     return QPolygonF(vpt);
    311 }
    312 
    313 QRectF myGraphicRectItem::getCrtPosRectToSceen()
    314 {
    315     QRectF retRect = QRectF(m_oldRect.x()+pos().x(),m_oldRect.y()+pos().y(),m_oldRect.width(),m_oldRect.height());
    316     return retRect;
    317 }
    318 QRectF myGraphicRectItem::getSmallRotateRect(QPointF ptA,QPointF ptB)
    319 {
    320     QPointF pt = getSmallRotateRectCenter(ptA,ptB);
    321     return QRectF(pt.x()-10,pt.y()-10,20,20);
    322 }
    323 QPointF myGraphicRectItem::getSmallRotateRectCenter(QPointF ptA,QPointF ptB)
    324 {
    325     QPointF ptCenter = QPointF((ptA.x()+ptB.x())/2,(ptA.y()+ptB.y())/2);//A,B点的中点C
    326     //中垂线方程式为 y=x*k + b;
    327     qreal x,y;//旋转图标矩形的中心
    328     if(abs(ptB.y()-ptA.y())<0.1)
    329     {
    330         if(ptA.x()<ptB.x())//矩形左上角在上方
    331         {
    332             x = ptCenter.x();
    333             y = ptCenter.y()-20;
    334         }
    335         else//矩形左上角在下方
    336         {
    337             x = ptCenter.x();
    338             y = ptCenter.y()+20;
    339         }
    340     }
    341     else if(ptB.y()>ptA.y())//顺时针旋转0-180
    342     {
    343         qreal k = (ptA.x()-ptB.x())/(ptB.y()-ptA.y());//中垂线斜率
    344         qreal b = (ptA.y()+ptB.y())/2-k*(ptA.x()+ptB.x())/2;
    345         //求AB线中垂线上离AB中点20个像素的点C的坐标
    346         x = 20*cos(atan(k))+ptCenter.x();
    347         y = k*x+b;
    348     }
    349     else if(ptB.y()<ptA.y())//顺时针旋转180-360
    350     {
    351         qreal k = (ptA.x()-ptB.x())/(ptB.y()-ptA.y());//中垂线斜率
    352         qreal b = (ptA.y()+ptB.y())/2-k*(ptA.x()+ptB.x())/2;
    353         //求AB线中垂线上离AB中点20个像素的点C的坐标
    354         x = -20*cos(atan(k))+ptCenter.x();
    355         y = k*x+b;
    356     }
    357     return QPointF(x,y);
    358 }
  • 相关阅读:
    2020.10.25【NOIP提高A组】模拟 总结
    6831. 2020.10.24【NOIP提高A组】T1.lover
    枚举一个数$n$的所有质因子
    gmoj 6832. 2020.10.24【NOIP提高A组】T2.world
    2020.10.24【NOIP提高A组】模拟 总结
    2020.10.17【NOIP提高A组】模拟 总结
    jQuery EasyUI Portal 保存拖动位置,仿谷歌DashBoard效果的
    SQLMAP注入教程-11种常见SQLMAP使用方法详解
    Windows下sqlmap的安装图解
    swap file "*.swp" already exists!的解决方法
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13862420.html
Copyright © 2011-2022 走看看