问题
自绘图元放到左边和上边之外,部分在内进行拉伸后,拉伸多余的区域无法碰撞
示意图
解决后的目标效果
解决方法
变换之前或之后一定要调用一次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); }