PDA

View Full Version : Rotation Problem



Raghaw
21st August 2012, 09:58
Hi,

I have one shape Rectangle which can be re-sized from 8 corners (eg top left ,mid left, bottom left etc)for resizing i have made small rectangles as resizing handles.For rotating this rectangle there is one line arrow handle which originates from Mid left of Rectangle.The user can put his mouse cursor on the rotation arrow handle and rotate the shape.

My problem is that i want to get untransformed shape of this arrow handle irrespective of scale factor i am using.At first when i create this rectangle with arrow its okie ..but when i rotate the rectangle the arrow handle changes the shape which should not happen.


QRectF CRectangle::getUntransformedRect(QPainter *painter, QRectF rect)
{
if (!painter->transform().isScaling()/* || scaleFactor < 1*/)
return rect;

QTransform transform = painter->transform();
QRectF transFormedRect = transform.mapRect(rect);
float scaleFactor = transFormedRect.width() / rect.width();

QRectF destRect = rect;
destRect.setWidth(rect.width() / scaleFactor);
destRect.setHeight(rect.height() / scaleFactor);
destRect.moveCenter(rect.center());
return destRect;
}

void CRectangle::updateAngleHandle()
{
if(m_ShowRotation)
{
m_RotateLine.setP1(m_Handles[7].center());
float size = m_ActualRectangle.width();
m_RotateLine.setP2(QPointF(m_Handles[7].center().x() + (size / 4), m_Handles[7].center().y()));
QPointF point = m_RotateLine.p2();

QPointF destArrowP1 = point;
destArrowP1.setY(point.y() + 8.0);
destArrowP1.setX(point.x() - 8.0);
QPointF destArrowP2 = destArrowP1;
destArrowP2.setY(point.y() - 8);

int points[] = {point.x(), point.y(), destArrowP1.x(), destArrowP1.y(), destArrowP2.x(), destArrowP2.y()};
m_AngleHandle.setPoints(3, points);
}
}


void CRectangle::drawShape(QPainter *painter)
{
if(!m_ActualRectangle.isEmpty() && m_Show)
{
painter->setPen(m_DrawingPen);
painter->setBrush(QColor(0, 0, 0, 0));
painter->save();
//painter->setTransform(m_transform);
QTransform transform = painter->transform();
QPointF centerPoint = m_transform.map(m_ActualRectangle.center());
transform.translate(centerPoint.x(), centerPoint.y());
transform.rotate(-m_Angle);
transform.translate(-centerPoint.x(), -centerPoint.y());
painter->setTransform(transform);
painter->drawRect(m_ActualRectangle);

if(m_NeedCenterCross)
{
painter->drawLines(m_CenterCrossLine);
}
if(m_ShowHandles && m_Enable)
{
//drawing resizable handles

painter->setPen(QColor(255, 255, 255));
painter->setBrush(Qt::black);

Q_FOREACH( QRectF rect , m_Handles) /// This is for drawing resizable handles
{
QRectF notTransformedRect = getUntransformedRect(painter, rect);
painter->drawRect(notTransformedRect);
}

//painter->restore();


//painter->drawText(m_Handles[i].topLeft(), QString::number(i));

if(m_ShowRotation) // For Arrow Handle
{
m_RotateLine.setP1(m_Handles[7].center());
float size = m_ActualRectangle.width();
m_RotateLine.setP2(QPointF(m_Handles[7].center().x() + (size / 4), m_Handles[7].center().y()));
QPointF point = m_RotateLine.p2();

QPointF destArrowP1 = point;
destArrowP1.setY(point.y() + 8.0);
destArrowP1.setX(point.x() - 8.0);
QPointF destArrowP2 = destArrowP1;
destArrowP2.setY(point.y() - 8);

QRectF angleRect(destArrowP2, QSizeF(point.x() - destArrowP2.x(), destArrowP1.y() - destArrowP2.y()));
QRectF angleRectUnScaled = getUntransformedRect(painter, angleRect);

point.setX(angleRectUnScaled.topRight().x());
point.setY(angleRectUnScaled.center().y());

destArrowP1 = angleRectUnScaled.bottomLeft();
destArrowP2 = angleRectUnScaled.topLeft();

int points[] = {point.x(), point.y(), destArrowP1.x(), destArrowP1.y(), destArrowP2.x(), destArrowP2.y()};
m_AngleHandle.setPoints(3, points);

QPen pen;
pen.setColor(m_DrawingPen.color());
painter->setPen(pen);
painter->setBrush(Qt::black);
painter->drawLine(m_RotateLine);
painter->drawPolygon(m_AngleHandle);
}
}
else
{
painter->restore();
}
painter->restore();

if(m_Failed)
{
painter->setPen(QColor(Qt::red));
painter->drawLine(m_transform.map(m_Handles[0].topLeft()), m_transform.map(m_Handles[4].topLeft()));
painter->drawLine(m_transform.map(m_Handles[2].topLeft()), m_transform.map(m_Handles[6].topLeft()));
}



Can you please help me out what is the exact problem? Why the Arrow Head is changing the shape during rotation.

spirit
21st August 2012, 10:15
Can you disclose you code snippet in CODE tags? It's really hard to read it.

Raghaw
21st August 2012, 10:23
QRectF CRectangle::getUntransformedRect(QPainter *painter, QRectF rect)
{
if (!painter->transform().isScaling()/* || scaleFactor < 1*/)
return rect;

QTransform transform = painter->transform();
QRectF transFormedRect = transform.mapRect(rect);
float scaleFactor = transFormedRect.width() / rect.width();

QRectF destRect = rect;
destRect.setWidth(rect.width() / scaleFactor);
destRect.setHeight(rect.height() / scaleFactor);
destRect.moveCenter(rect.center());
return destRect;
}

void CRectangle::updateAngleHandle()
{
if(m_ShowRotation)
{
m_RotateLine.setP1(m_Handles[7].center());
float size = m_ActualRectangle.width();
m_RotateLine.setP2(QPointF(m_Handles[7].center().x() + (size / 4), m_Handles[7].center().y()));
QPointF point = m_RotateLine.p2();

QPointF destArrowP1 = point;
destArrowP1.setY(point.y() + 8.0);
destArrowP1.setX(point.x() - 8.0);
QPointF destArrowP2 = destArrowP1;
destArrowP2.setY(point.y() - 8);

int points[] = {point.x(), point.y(), destArrowP1.x(), destArrowP1.y(), destArrowP2.x(), destArrowP2.y()};
m_AngleHandle.setPoints(3, points);
}
}


void CRectangle::drawShape(QPainter *painter)
{
if(!m_ActualRectangle.isEmpty() && m_Show)
{
painter->setPen(m_DrawingPen);
painter->setBrush(QColor(0, 0, 0, 0));
painter->save();
//painter->setTransform(m_transform);
QTransform transform = painter->transform();
QPointF centerPoint = m_transform.map(m_ActualRectangle.center());
transform.translate(centerPoint.x(), centerPoint.y());
transform.rotate(-m_Angle);
transform.translate(-centerPoint.x(), -centerPoint.y());
painter->setTransform(transform);
painter->drawRect(m_ActualRectangle);

if(m_NeedCenterCross)
{
painter->drawLines(m_CenterCrossLine);
}
if(m_ShowHandles && m_Enable)
{
//drawing resizable handles

painter->setPen(QColor(255, 255, 255));
painter->setBrush(Qt::black);

Q_FOREACH( QRectF rect , m_Handles) /// This is for drawing resizable handles
{
QRectF notTransformedRect = getUntransformedRect(painter, rect);
painter->drawRect(notTransformedRect);
}

//painter->restore();


//painter->drawText(m_Handles[i].topLeft(), QString::number(i));

if(m_ShowRotation) // For Arrow Handle
{
m_RotateLine.setP1(m_Handles[7].center());
float size = m_ActualRectangle.width();
m_RotateLine.setP2(QPointF(m_Handles[7].center().x() + (size / 4), m_Handles[7].center().y()));
QPointF point = m_RotateLine.p2();

QPointF destArrowP1 = point;
destArrowP1.setY(point.y() + 8.0);
destArrowP1.setX(point.x() - 8.0);
QPointF destArrowP2 = destArrowP1;
destArrowP2.setY(point.y() - 8);

QRectF angleRect(destArrowP2, QSizeF(point.x() - destArrowP2.x(), destArrowP1.y() - destArrowP2.y()));
QRectF angleRectUnScaled = getUntransformedRect(painter, angleRect);

point.setX(angleRectUnScaled.topRight().x());
point.setY(angleRectUnScaled.center().y());

destArrowP1 = angleRectUnScaled.bottomLeft();
destArrowP2 = angleRectUnScaled.topLeft();

int points[] = {point.x(), point.y(), destArrowP1.x(), destArrowP1.y(), destArrowP2.x(), destArrowP2.y()};
m_AngleHandle.setPoints(3, points);

QPen pen;
pen.setColor(m_DrawingPen.color());
painter->setPen(pen);
painter->setBrush(Qt::black);
painter->drawLine(m_RotateLine);
painter->drawPolygon(m_AngleHandle);
}
}
else
{
painter->restore();
}
painter->restore();

if(m_Failed)
{
painter->setPen(QColor(Qt::red));
painter->drawLine(m_transform.map(m_Handles[0].topLeft()), m_transform.map(m_Handles[4].topLeft()));
painter->drawLine(m_transform.map(m_Handles[2].topLeft()), m_transform.map(m_Handles[6].topLeft()));
}