问题
自绘图元放到左边和上边之外,部分在内进行拉伸后,拉伸多余的区域无法碰撞
示意图
解决后的目标效果
解决方法
变换之前或之后一定要调用一次prepareGeometryChange();
void RectItemBase::stretchByPoint(QPointF originPointF, QPointF fromPointF, QPointF toPointF)
{
qreal stretchX = 1.0;
qreal stretchY = 1.0;
QPointF originPointFTemp;
QPointF fromPointFTemp;
QPointF toPointFTemp;
// 步骤一:获取中心点与右领边的旋转角度(逆时钟为正)
qreal angleOffset;
QPointF anglePointF;
if(originPointF == _originLeftTopPointF)
{
anglePointF = _originRightTopPointF;
}else if(originPointF == _originLeftBottomPointF)
{
anglePointF = _originLeftTopPointF;
}else if(originPointF == _originRightBottomPointF)
{
anglePointF = _originLeftBottomPointF;
}else if(originPointF == _originRightTopPointF)
{
anglePointF = _originRightBottomPointF;
}
angleOffset = MyMath::lineReverseClockAngle(originPointF, anglePointF);
// 步骤二:已对称点先旋转正
QTransform transform;
transform.translate(originPointF.x(), originPointF.y());
transform.rotate(angleOffset);
originPointFTemp = transform.map(originPointF-originPointF) - originPointF;
fromPointFTemp = transform.map(fromPointF-originPointF)-originPointF;
toPointFTemp = transform.map(toPointF-originPointF)-originPointF;
// 步骤三:获取角度查的缩放比,得到旋转对其后的原始高宽和拉伸后的宽高
qreal distanceOrigin2From = MyMath::lineDistance(originPointF, fromPointF);
qreal distanceOrigin2To = MyMath::lineDistance(originPointF, toPointF);
qreal angleOrigin2From = MyMath::lineReverseClockAngle(originPointF, fromPointF);
qreal angleOrigin2To = MyMath::lineReverseClockAngle(originPointF, toPointF);
qreal angleFrom2Origin2AdjacentSide = angleOrigin2From - angleOffset;
qreal angleTo2Origin2AdjacentSide = angleOrigin2To - angleOffset;
qreal originWidth = distanceOrigin2From * qCos(qDegreesToRadians(angleFrom2Origin2AdjacentSide));
qreal originHeight = distanceOrigin2From * qSin(qDegreesToRadians(angleFrom2Origin2AdjacentSide));
qreal width = distanceOrigin2To * qCos(qDegreesToRadians(angleTo2Origin2AdjacentSide));
qreal height = distanceOrigin2To * qSin(qDegreesToRadians(angleTo2Origin2AdjacentSide));
#if 0
qDebug() << __FILE__ << __LINE__ << originPointF << fromPointF
<< "原来距离:" << distanceOrigin2From << "原来夹角:" << angleOrigin2From << "与逆时针邻边夹角:" << angleFrom2Origin2AdjacentSide
<< "原始宽度:" << originWidth << "原始高度:" << originHeight;
qDebug() << __FILE__ << __LINE__ << fromPointFTemp << toPointFTemp
<< "现在距离:" << distanceOrigin2To << "现在夹角:" << angleOrigin2To << "与逆时针邻边夹角:" << angleTo2Origin2AdjacentSide
<< "现在宽度:" << width << "现在高度:" << height;
#endif
// 步骤四:限制最小宽度和高度
if(qAbs(width) < _minWidth)
{
width = _minWidth;
if(width < 0)
{
width = -_minWidth;
}else{
width = _minWidth;
}
}
if(qAbs(height) < _minHeigt)
{
if(height < 0)
{
height = -_minHeigt;
}else{
height = _minHeigt;
}
}
// 限制不能反向
if(originWidth > 0 && width < 0)
{
width = _minWidth;
}else if(originWidth < 0 && width > 0)
{
width = -_minWidth;
}
if(originHeight > 0 && height < 0)
{
height = _minWidth;
}else if(originHeight < 0 && height > 0)
{
height = -_minWidth;
}
stretchX = width / originWidth;
stretchY = height / originHeight;
// 步骤五:缩放
transform.scale(stretchX, stretchY);
// 步骤六:变换回原来的角度
transform.rotate(-angleOffset);
// 一定要调用prepareGeometryChange(),否则无法更新变换后的区域
prepareGeometryChange();
// 步骤七:变换坐标
_leftTopPointF = transform.map(_originLeftTopPointF- originPointF);
_leftBottomPointF = transform.map(_originLeftBottomPointF - originPointF);
_rightTopPointF = transform.map(_originRightTopPointF - originPointF);
_rightBottomPointF = transform.map(_originRightBottomPointF - originPointF);
}