484 lines
20 KiB
C++
484 lines
20 KiB
C++
|
|
#include "mygraphicrectitem.h"
|
|||
|
|
#include <QtMath>
|
|||
|
|
#include <QDebug>
|
|||
|
|
|
|||
|
|
myGraphicRectItem::myGraphicRectItem(QGraphicsItem *parent):
|
|||
|
|
m_ShapeType(RECTANGLE),
|
|||
|
|
m_bResize(false),
|
|||
|
|
m_oldRect(0,0,100,100),
|
|||
|
|
m_bRotate(false),
|
|||
|
|
m_RotateAngle(0),
|
|||
|
|
m_StateFlag(DEFAULT_FLAG)
|
|||
|
|
{
|
|||
|
|
//setParent(parent);
|
|||
|
|
setRectSize(m_oldRect);
|
|||
|
|
setToolTip("Click and drag me!"); //提示
|
|||
|
|
setCursor(Qt::ArrowCursor); //改变光标形状,手的形状
|
|||
|
|
setFlag(QGraphicsItem::ItemIsMovable);
|
|||
|
|
pPointFofSmallRotateRect = new QPointF[4];
|
|||
|
|
SetRotate(0);
|
|||
|
|
//setFlag(QGraphicsItem::ItemIsSelectable);//
|
|||
|
|
setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QRectF myGraphicRectItem::boundingRect() const//用来控制本item绘制区域
|
|||
|
|
{
|
|||
|
|
QPainterPath path;
|
|||
|
|
path.addPolygon(m_oldRectPolygon);
|
|||
|
|
path.addPolygon(m_SmallRotatePolygon);
|
|||
|
|
return path.boundingRect();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QPainterPath myGraphicRectItem::shape() const//用来控制检测碰撞collide和鼠标点击hit响应区域
|
|||
|
|
{
|
|||
|
|
QPainterPath path;
|
|||
|
|
path.addPolygon(m_oldRectPolygon);
|
|||
|
|
path.addPolygon(m_SmallRotatePolygon);
|
|||
|
|
return path;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QPainterPath myGraphicRectItem::getCollideShape()
|
|||
|
|
{
|
|||
|
|
QPainterPath path;
|
|||
|
|
if(m_ShapeType==RECTANGLE)
|
|||
|
|
{
|
|||
|
|
path.addPolygon(m_oldRectPolygon);
|
|||
|
|
}
|
|||
|
|
else if(m_ShapeType == CIRCLE)
|
|||
|
|
{
|
|||
|
|
QPainterPath pathTemp;
|
|||
|
|
pathTemp.addEllipse(m_oldRect);
|
|||
|
|
QTransform trans;
|
|||
|
|
trans.translate(m_RotateCenter.x(),m_RotateCenter.y());
|
|||
|
|
trans.rotate(m_RotateAngle);//QTransform是绕(0,0)点旋转的,所以转之前要先平移到圆心,然后旋转,然后再平移回来
|
|||
|
|
trans.translate(-m_RotateCenter.x(),-m_RotateCenter.y());
|
|||
|
|
path = trans.map(pathTemp);
|
|||
|
|
}
|
|||
|
|
return path;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
myGraphicRectItem::~myGraphicRectItem()
|
|||
|
|
{
|
|||
|
|
delete []pPointFofSmallRotateRect;
|
|||
|
|
pPointFofSmallRotateRect = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void myGraphicRectItem::setRectSize(QRectF mrect, bool bResetRotateCenter)
|
|||
|
|
{
|
|||
|
|
m_oldRect = mrect;
|
|||
|
|
if(bResetRotateCenter)
|
|||
|
|
{
|
|||
|
|
m_RotateCenter.setX(m_oldRect.x()+m_oldRect.width()/2);
|
|||
|
|
m_RotateCenter.setY(m_oldRect.y()+m_oldRect.height()/2);
|
|||
|
|
}
|
|||
|
|
m_oldRectPolygon = getRotatePolygonFromRect(m_RotateCenter,m_oldRect,m_RotateAngle);
|
|||
|
|
|
|||
|
|
m_insicedRectf = QRectF(m_oldRect.x()+8,m_oldRect.y()+8,m_oldRect.width()-16,m_oldRect.height()-16);
|
|||
|
|
m_insicedPolygon =getRotatePolygonFromRect(m_RotateCenter,m_insicedRectf,m_RotateAngle);
|
|||
|
|
|
|||
|
|
m_leftRectf = QRectF(m_oldRect.x(),m_oldRect.y(),8,m_oldRect.height()-8);
|
|||
|
|
m_leftPolygon = getRotatePolygonFromRect(m_RotateCenter,m_leftRectf,m_RotateAngle);
|
|||
|
|
|
|||
|
|
m_topRectf = QRectF(m_oldRect.x()+8,m_oldRect.y(),m_oldRect.width()-8,8);
|
|||
|
|
m_topPolygon = getRotatePolygonFromRect(m_RotateCenter,m_topRectf,m_RotateAngle);
|
|||
|
|
|
|||
|
|
m_rightRectf = QRectF(m_oldRect.right()-8,m_oldRect.y()+8,8,m_oldRect.height()-16);
|
|||
|
|
m_rightPolygon = getRotatePolygonFromRect(m_RotateCenter,m_rightRectf,m_RotateAngle);
|
|||
|
|
|
|||
|
|
m_bottomRectf = QRectF(m_oldRect.x(),m_oldRect.bottom()-8,m_oldRect.width()-8,8);
|
|||
|
|
m_bottomPolygon = getRotatePolygonFromRect(m_RotateCenter,m_bottomRectf,m_RotateAngle);
|
|||
|
|
|
|||
|
|
m_SmallRotateRect = getSmallRotateRect(mrect.topLeft(),mrect.topRight());//矩形正上方的旋转标记矩形
|
|||
|
|
m_SmallRotatePolygon = getRotatePolygonFromRect(m_RotateCenter,m_SmallRotateRect,m_RotateAngle);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void myGraphicRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|||
|
|
{
|
|||
|
|
QPen mPen;
|
|||
|
|
// if(this->isSelected())
|
|||
|
|
// {
|
|||
|
|
// mPen= QPen(Qt::lightGray);
|
|||
|
|
// }
|
|||
|
|
// else
|
|||
|
|
// {
|
|||
|
|
mPen= QPen(Qt::yellow);
|
|||
|
|
// }
|
|||
|
|
painter->setPen(mPen);
|
|||
|
|
if(m_ShapeType == RECTANGLE)
|
|||
|
|
{
|
|||
|
|
//绘制旋转后的矩形
|
|||
|
|
painter->drawPolygon(m_oldRectPolygon);
|
|||
|
|
//绘制旋转圆形
|
|||
|
|
mPen.setWidth(2);
|
|||
|
|
mPen.setColor(Qt::green);
|
|||
|
|
painter->setPen(mPen);
|
|||
|
|
QPointF pf = getSmallRotateRectCenter(m_oldRectPolygon[0],m_oldRectPolygon[1]);
|
|||
|
|
QRectF rect = QRectF(pf.x()-10,pf.y()-10,20,20);
|
|||
|
|
painter->drawEllipse(rect);//绘制圆形
|
|||
|
|
painter->drawPoint(pf);//绘制点
|
|||
|
|
//有重叠的情况
|
|||
|
|
if(!this->scene()->collidingItems(this).isEmpty())
|
|||
|
|
{
|
|||
|
|
QPainterPath path,pathOthers;
|
|||
|
|
QList<QGraphicsItem *> lstcolliItems = this->scene()->collidingItems(this);
|
|||
|
|
int nColliNum = lstcolliItems.count();
|
|||
|
|
for(int i = 0;i<nColliNum;i++)
|
|||
|
|
{
|
|||
|
|
myGraphicRectItem* pTempItem = (myGraphicRectItem*)this->scene()->collidingItems(this)[i];
|
|||
|
|
if(pTempItem->zValue()==0)
|
|||
|
|
{
|
|||
|
|
QPainterPath tempPath = pTempItem->getCollideShape();
|
|||
|
|
tempPath.translate(pTempItem->pos());//转换到view中的坐标
|
|||
|
|
pathOthers += tempPath;//记录与本item重叠的item的路径
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
path.addPolygon(m_oldRectPolygon);
|
|||
|
|
path.translate(this->pos());//转换到view中的坐标
|
|||
|
|
path &= pathOthers;//计算重叠部分的路径path
|
|||
|
|
path.translate(-this->pos().x(),-this->pos().y());//转换回本Item中的坐标
|
|||
|
|
QBrush brush(Qt::cyan);
|
|||
|
|
mPen.setColor(Qt::blue);
|
|||
|
|
painter->setPen(mPen);
|
|||
|
|
painter->setBrush(brush);
|
|||
|
|
painter->drawPath(path);//绘制重叠区域
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if(m_ShapeType == CIRCLE)
|
|||
|
|
{
|
|||
|
|
// //绘制旋转后的矩形
|
|||
|
|
// painter->drawRect(m_oldRect);
|
|||
|
|
// painter->drawPolygon(m_oldRectPolygon);
|
|||
|
|
//绘制旋转后的圆形
|
|||
|
|
QTransform trans0;
|
|||
|
|
QPainterPath path0;
|
|||
|
|
trans0.translate(m_RotateCenter.x(),m_RotateCenter.y());
|
|||
|
|
trans0.rotate(m_RotateAngle,Qt::ZAxis);
|
|||
|
|
trans0.translate(-m_RotateCenter.x(),-m_RotateCenter.y());
|
|||
|
|
path0.addEllipse(m_oldRect);
|
|||
|
|
path0 = trans0.map(path0);//将pathTemp旋转m_RotateAngle角度
|
|||
|
|
painter->drawPath(path0);//drawPolygon(m_oldRectPolygon);
|
|||
|
|
//绘制旋转圆形标记
|
|||
|
|
mPen.setWidth(2);
|
|||
|
|
mPen.setColor(Qt::green);
|
|||
|
|
painter->setPen(mPen);
|
|||
|
|
QPointF pf = getSmallRotateRectCenter(m_oldRectPolygon[0],m_oldRectPolygon[1]);
|
|||
|
|
QRectF rect = QRectF(pf.x()-10,pf.y()-10,20,20);
|
|||
|
|
painter->drawEllipse(rect);//绘制圆形
|
|||
|
|
painter->drawPoint(pf);//绘制点
|
|||
|
|
//有重叠的情况
|
|||
|
|
if(!this->scene()->collidingItems(this).isEmpty())
|
|||
|
|
{
|
|||
|
|
QPainterPath path,pathOthers;
|
|||
|
|
QList<QGraphicsItem *> lstcolliItems = this->scene()->collidingItems(this);
|
|||
|
|
int nColliNum = lstcolliItems.count();
|
|||
|
|
for(int i = 0;i<nColliNum;i++)
|
|||
|
|
{
|
|||
|
|
myGraphicRectItem* pTempItem = (myGraphicRectItem*)this->scene()->collidingItems(this)[i];
|
|||
|
|
if(pTempItem->zValue()==0)
|
|||
|
|
{
|
|||
|
|
QPainterPath tempPath = pTempItem->getCollideShape();
|
|||
|
|
tempPath.translate(pTempItem->pos());//转换到view中的坐标
|
|||
|
|
pathOthers += tempPath;//记录与本item重叠的item的路径
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
QTransform trans;
|
|||
|
|
//旋转的时候,QTransform是绕坐标轴的(0,0)点旋转的,所以先要平移到坐标轴0,0点,然后的旋转,然后移回到原来的位置
|
|||
|
|
trans.translate(m_RotateCenter.x(),m_RotateCenter.y());
|
|||
|
|
trans.rotate(m_RotateAngle);
|
|||
|
|
trans.translate(-m_RotateCenter.x(),-m_RotateCenter.y());
|
|||
|
|
path.addEllipse(m_oldRect);
|
|||
|
|
path = trans.map(path);//将pathTemp旋转m_RotateAngle角度
|
|||
|
|
path.translate(this->pos());//转换到view中的坐标
|
|||
|
|
path &= pathOthers;//计算重叠部分的路径path
|
|||
|
|
path.translate(-this->pos().x(),-this->pos().y());//转换回本Item中的坐标
|
|||
|
|
QBrush brush(Qt::cyan);
|
|||
|
|
mPen.setColor(Qt::blue);
|
|||
|
|
painter->setPen(mPen);
|
|||
|
|
painter->setBrush(brush);
|
|||
|
|
painter->drawPath(path);//绘制重叠区域
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//scene()->update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void myGraphicRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
|
|
{
|
|||
|
|
if(event->button()== Qt::LeftButton)
|
|||
|
|
{
|
|||
|
|
//setSelected(true);
|
|||
|
|
m_startPos = event->pos();//鼠标左击时,获取当前鼠标在图片中的坐标,
|
|||
|
|
if(m_SmallRotatePolygon.containsPoint(m_startPos,Qt::WindingFill))//旋转矩形
|
|||
|
|
{
|
|||
|
|
setCursor(Qt::PointingHandCursor);
|
|||
|
|
m_StateFlag = ROTATE;
|
|||
|
|
}
|
|||
|
|
else if(m_insicedPolygon.containsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下鼠标,则可拖动图片
|
|||
|
|
{
|
|||
|
|
setCursor(Qt::ClosedHandCursor); //改变光标形状,手的形状
|
|||
|
|
m_StateFlag = MOV_RECT;//标记当前为鼠标拖动图片移动状态
|
|||
|
|
}
|
|||
|
|
else if(m_leftPolygon.containsPoint(m_startPos,Qt::WindingFill))
|
|||
|
|
{
|
|||
|
|
setCursor(Qt::SizeHorCursor);
|
|||
|
|
m_StateFlag = MOV_LEFT_LINE;//标记当前为用户按下矩形的左边界区域
|
|||
|
|
}
|
|||
|
|
else if(m_rightPolygon.containsPoint(m_startPos,Qt::WindingFill))
|
|||
|
|
{
|
|||
|
|
setCursor(Qt::SizeHorCursor);
|
|||
|
|
m_StateFlag = MOV_RIGHT_LINE;//标记当前为用户按下矩形的右边界区域
|
|||
|
|
}
|
|||
|
|
else if(m_topPolygon.containsPoint(m_startPos,Qt::WindingFill))
|
|||
|
|
{
|
|||
|
|
setCursor(Qt::SizeVerCursor);
|
|||
|
|
m_StateFlag = MOV_TOP_LINE;//标记当前为用户按下矩形的上边界区域
|
|||
|
|
}
|
|||
|
|
else if(m_bottomPolygon.containsPoint(m_startPos,Qt::WindingFill))
|
|||
|
|
{
|
|||
|
|
setCursor(Qt::SizeVerCursor);
|
|||
|
|
m_StateFlag = MOV_BOTTOM_LINE;//标记当前为用户按下矩形的下边界区域
|
|||
|
|
}
|
|||
|
|
// else if(m_rbPolygon.containsPoint(m_startPos,Qt::WindingFill))
|
|||
|
|
// {
|
|||
|
|
// setCursor(Qt::SizeFDiagCursor);
|
|||
|
|
// m_StateFlag = MOV_RIGHTBOTTOM_RECT;//标记当前为用户按下矩形的右下角
|
|||
|
|
// }
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
m_StateFlag = DEFAULT_FLAG;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
QGraphicsItem::mousePressEvent(event);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void myGraphicRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||
|
|
{
|
|||
|
|
if(m_StateFlag == ROTATE)
|
|||
|
|
{
|
|||
|
|
int nRotateAngle = atan2((event->pos().x()-m_RotateCenter.x()),(event->pos().y()-m_RotateCenter.y()))*180/M_PI;
|
|||
|
|
SetRotate(180-nRotateAngle);
|
|||
|
|
//qDebug()<<nRotateAngle;
|
|||
|
|
}
|
|||
|
|
else if(m_StateFlag == MOV_RECT)
|
|||
|
|
{
|
|||
|
|
QPointF point = (event->pos() - m_startPos);
|
|||
|
|
moveBy(point.x(), point.y());
|
|||
|
|
setRectSize(m_oldRect);
|
|||
|
|
scene()->update();
|
|||
|
|
}
|
|||
|
|
else if(m_StateFlag == MOV_LEFT_LINE)
|
|||
|
|
{
|
|||
|
|
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));
|
|||
|
|
//计算到右侧边中点的距离
|
|||
|
|
qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
|
|||
|
|
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()));
|
|||
|
|
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()));
|
|||
|
|
if(dis<16||dis2LT>dis2RT)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
QRectF newRect(m_oldRect);
|
|||
|
|
newRect.setLeft(m_oldRect.right()-dis);
|
|||
|
|
newRect.setRight(m_oldRect.right());
|
|||
|
|
setRectSize(newRect,false);
|
|||
|
|
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);
|
|||
|
|
m_oldRect.moveCenter(m_RotateCenter);
|
|||
|
|
setRectSize(m_oldRect);
|
|||
|
|
scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if(m_StateFlag == MOV_TOP_LINE)
|
|||
|
|
{
|
|||
|
|
//底边中点
|
|||
|
|
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));
|
|||
|
|
//计算到底边中点的距离
|
|||
|
|
qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
|
|||
|
|
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()));
|
|||
|
|
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()));
|
|||
|
|
if(dis<16||dis2LT>dis2LB)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
QRectF newRect(m_oldRect);
|
|||
|
|
newRect.setTop(m_oldRect.bottom()-dis);
|
|||
|
|
newRect.setBottom(m_oldRect.bottom());
|
|||
|
|
setRectSize(newRect,false);
|
|||
|
|
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);
|
|||
|
|
m_oldRect.moveCenter(m_RotateCenter);
|
|||
|
|
setRectSize(m_oldRect);
|
|||
|
|
scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if(m_StateFlag == MOV_RIGHT_LINE)
|
|||
|
|
{
|
|||
|
|
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));
|
|||
|
|
//计算到左侧边中点的距离
|
|||
|
|
qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
|
|||
|
|
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()));
|
|||
|
|
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()));
|
|||
|
|
if(dis<16||dis2LT<dis2RT)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
QRectF newRect(m_oldRect);
|
|||
|
|
newRect.setLeft(m_oldRect.left());
|
|||
|
|
newRect.setRight(m_oldRect.left()+dis);
|
|||
|
|
setRectSize(newRect,false);
|
|||
|
|
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);
|
|||
|
|
m_oldRect.moveCenter(m_RotateCenter);
|
|||
|
|
setRectSize(m_oldRect);
|
|||
|
|
scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if(m_StateFlag == MOV_BOTTOM_LINE)
|
|||
|
|
{
|
|||
|
|
//顶边中点
|
|||
|
|
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));
|
|||
|
|
//计算到底边中点的距离
|
|||
|
|
qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
|
|||
|
|
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()));
|
|||
|
|
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()));
|
|||
|
|
if(dis<16||dis2LT<dis2LB)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
QRectF newRect(m_oldRect);
|
|||
|
|
newRect.setTop(m_oldRect.top());
|
|||
|
|
newRect.setBottom(m_oldRect.top()+dis);
|
|||
|
|
setRectSize(newRect,false);
|
|||
|
|
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);
|
|||
|
|
m_oldRect.moveCenter(m_RotateCenter);
|
|||
|
|
setRectSize(m_oldRect);
|
|||
|
|
scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void myGraphicRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||
|
|
{
|
|||
|
|
setCursor(Qt::ArrowCursor);
|
|||
|
|
if(m_StateFlag == MOV_RECT)
|
|||
|
|
{
|
|||
|
|
m_StateFlag = DEFAULT_FLAG;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
QGraphicsItem::mouseReleaseEvent(event);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void myGraphicRectItem::SetRotate(qreal RotateAngle)
|
|||
|
|
{
|
|||
|
|
m_bRotate = true;
|
|||
|
|
m_RotateAngle = RotateAngle;
|
|||
|
|
setRectSize(m_oldRect);
|
|||
|
|
if(this->scene()!=nullptr)
|
|||
|
|
this->scene()->update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QPointF myGraphicRectItem::getRotatePoint(QPointF ptCenter, QPointF ptIn, qreal angle)
|
|||
|
|
{
|
|||
|
|
double dx = ptCenter.x();
|
|||
|
|
double dy = ptCenter.y();
|
|||
|
|
double x = ptIn.x();
|
|||
|
|
double y = ptIn.y();
|
|||
|
|
double xx,yy;
|
|||
|
|
xx = (x-dx)*cos(angle*M_PI/180)-(y-dy)*sin(angle*M_PI/180)+dx;
|
|||
|
|
yy = (x-dx)*sin(angle*M_PI/180)+(y-dy)*cos(angle*M_PI/180)+dy;
|
|||
|
|
|
|||
|
|
return QPointF(xx,yy);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QList<QPointF> myGraphicRectItem::getRotatePoints(QPointF ptCenter, QList<QPointF> ptIns, qreal angle)
|
|||
|
|
{
|
|||
|
|
QList<QPointF> lstPt;
|
|||
|
|
for(int i = 0;i<ptIns.count();i++)
|
|||
|
|
{
|
|||
|
|
lstPt.append(getRotatePoint(ptCenter,ptIns.at(i),angle));
|
|||
|
|
}
|
|||
|
|
return lstPt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QPolygonF myGraphicRectItem::getRotatePolygonFromRect(QPointF ptCenter, QRectF rectIn, qreal angle)
|
|||
|
|
{
|
|||
|
|
QVector<QPointF> vpt;
|
|||
|
|
QPointF pf = getRotatePoint(ptCenter,rectIn.topLeft(),angle);
|
|||
|
|
vpt.append(pf);
|
|||
|
|
pf = getRotatePoint(ptCenter,rectIn.topRight(),angle);
|
|||
|
|
vpt.append(pf);
|
|||
|
|
pf = getRotatePoint(ptCenter,rectIn.bottomRight(),angle);
|
|||
|
|
vpt.append(pf);
|
|||
|
|
pf = getRotatePoint(ptCenter,rectIn.bottomLeft(),angle);
|
|||
|
|
vpt.append(pf);
|
|||
|
|
pf = getRotatePoint(ptCenter,rectIn.topLeft(),angle);
|
|||
|
|
vpt.append(pf);
|
|||
|
|
return QPolygonF(vpt);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QRectF myGraphicRectItem::getCrtPosRectToSceen()
|
|||
|
|
{
|
|||
|
|
QRectF retRect = QRectF(m_oldRect.x()+pos().x(),m_oldRect.y()+pos().y(),m_oldRect.width(),m_oldRect.height());
|
|||
|
|
return retRect;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QPolygonF myGraphicRectItem::getCrtPolygonToScreen()
|
|||
|
|
{
|
|||
|
|
QVector<QPointF> vpt;
|
|||
|
|
for(int i = 0;i<m_oldRectPolygon.length();i++)
|
|||
|
|
{
|
|||
|
|
vpt.append(QPointF(m_oldRectPolygon[i].x()+pos().x(),m_oldRectPolygon[i].y()+pos().y()));
|
|||
|
|
}
|
|||
|
|
return QPolygonF(vpt);
|
|||
|
|
}
|
|||
|
|
QRectF myGraphicRectItem::getSmallRotateRect(QPointF ptA,QPointF ptB)
|
|||
|
|
{
|
|||
|
|
QPointF pt = getSmallRotateRectCenter(ptA,ptB);
|
|||
|
|
return QRectF(pt.x()-10,pt.y()-10,20,20);
|
|||
|
|
}
|
|||
|
|
QPointF myGraphicRectItem::getSmallRotateRectCenter(QPointF ptA,QPointF ptB)
|
|||
|
|
{
|
|||
|
|
QPointF ptCenter = QPointF((ptA.x()+ptB.x())/2,(ptA.y()+ptB.y())/2);//A,B点的中点C
|
|||
|
|
//中垂线方程式为 y=x*k + b;
|
|||
|
|
qreal x,y;//旋转图标矩形的中心
|
|||
|
|
if(abs(ptB.y()-ptA.y())<0.1)
|
|||
|
|
{
|
|||
|
|
if(ptA.x()<ptB.x())//矩形左上角在上方
|
|||
|
|
{
|
|||
|
|
x = ptCenter.x();
|
|||
|
|
y = ptCenter.y()-20;
|
|||
|
|
}
|
|||
|
|
else//矩形左上角在下方
|
|||
|
|
{
|
|||
|
|
x = ptCenter.x();
|
|||
|
|
y = ptCenter.y()+20;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if(ptB.y()>ptA.y())//顺时针旋转0-180
|
|||
|
|
{
|
|||
|
|
qreal k = (ptA.x()-ptB.x())/(ptB.y()-ptA.y());//中垂线斜率
|
|||
|
|
qreal b = (ptA.y()+ptB.y())/2-k*(ptA.x()+ptB.x())/2;
|
|||
|
|
//求AB线中垂线上离AB中点20个像素的点C的坐标
|
|||
|
|
x = 20*cos(atan(k))+ptCenter.x();
|
|||
|
|
y = k*x+b;
|
|||
|
|
}
|
|||
|
|
else if(ptB.y()<ptA.y())//顺时针旋转180-360
|
|||
|
|
{
|
|||
|
|
qreal k = (ptA.x()-ptB.x())/(ptB.y()-ptA.y());//中垂线斜率
|
|||
|
|
qreal b = (ptA.y()+ptB.y())/2-k*(ptA.x()+ptB.x())/2;
|
|||
|
|
//求AB线中垂线上离AB中点20个像素的点C的坐标
|
|||
|
|
x = -20*cos(atan(k))+ptCenter.x();
|
|||
|
|
y = k*x+b;
|
|||
|
|
}
|
|||
|
|
return QPointF(x,y);
|
|||
|
|
}
|