PDA

View Full Version : Problem with multiple scalings and rotations



qlands
28th July 2010, 14:14
Hi,

I am making an graphical application were users can sale and rote objects in a canvas in an arbitrary way. It uses hot-points in the screen (boxes that appear around the object) for scaling and rotation. I don't know much about transformation matrices, thus I don't know what I need to code to make it work. Currently it works if the user for example, Rotate then Scale Then Scale or if the user Scale, then rotate, then rotate. But if the user alternate Rotation and scaling, for example Rotate, Scale, Rotate the result is not the expected. For sure I am missing something because I don't know much about transformation matrices.

Here is the code:


//This gets the transformation point for scaling and rotation.
void tnkitemcontainer::setTransformationPoint(QPointF point)
{
TransformationPoint = this->mapFromScene(point);
if ((TransformationPoint.x() != 0) || (TransformationPoint.y() != 0))
translationApplied = true;
else
translationApplied = false;
currentTrans = this->transform();
}

//This rotate an object based on an angle. Angles are for example -45 or 45 degrees
void tnkitemcontainer::tnkRotate(float angle)
{
rotated = true;
QTransform trans;
currentRotation = formerRotation + angle;
if (translationApplied == false)
{
trans = trans.rotate(currentRotation);
}
else
{
trans.translate(TransformationPoint.x(),Transforma tionPoint.y());
trans.rotate(currentRotation);
trans.translate(-TransformationPoint.x(),-TransformationPoint.y());
}
trans = trans.scale(formerXFactor,formerYFactor); //Apply the last scale if any
setTransform(trans,false);

}

//This fuction will update the former rotation. If translation is used in the rotation
// this means that the object will move in the canvas due to transformation. This fuction will also move the object
// to its final localtion just like the transformation did.
void tnkitemcontainer::finishRotation()
{
rotated = false;
formerRotation = currentRotation;
if (translationApplied) //If translation was applied the object would move position in the scene
{
float currentX;
float currentY;
//Gets the current position in the scene;
currentX = scenePos().x();
currentY = scenePos().y();
//Override the transformation with the current values of scale and rotation
QTransform trans;
trans = trans.rotate(formerRotation); //Apply rotation
trans = trans.scale(formerXFactor,formerYFactor); //Apply the last scale if any
setTransform(trans,false);
//Move the object to its new position
setPos(currentX,currentY);
translationApplied = false;
}
}

//This scale an object based on X and Y factors. Examples of factors are 1, 1.5 and 2.
bool tnkitemcontainer::tnkScale(float xFactor,float yFactor)
{
scaled = true;
currentXFactor = formerXFactor * xFactor; //This will get the proportion from the former factor.
currentYFactor = formerYFactor * yFactor;
QTransform trans;
if (translationApplied == false)
{
trans = trans.scale(currentXFactor,currentYFactor);
}
else
{
trans = trans.translate(TransformationPoint.x(),Transforma tionPoint.y());
trans = trans.scale(currentXFactor,currentYFactor);
trans = trans.translate(-TransformationPoint.x(),-TransformationPoint.y());
}
trans = trans.rotate(formerRotation); //Applies the final rotation if any
setTransform(trans,false);
}

//This function will update the former rotation factors. If translation was applied, it means that the
// centre of the object will move in the canvas, so we move the object to its last position
void tnkitemcontainer::finishScale()
{
scaled = false;
formerXFactor = currentXFactor;
formerYFactor = currentYFactor;

if (translationApplied)
{
float currentX;
float currentY;
//Gets the current position in the scene;
currentX = scenePos().x();
currentY = scenePos().y();
//Override the transformation with the current values of scale and rotation
QTransform trans;
trans = trans.scale(formerXFactor,formerYFactor);
trans = trans.rotate(formerRotation);
setTransform(trans,false);
//Move the object to its new position
setPos(currentX,currentY);
translationApplied = false;
}
}


What do I need to take into consideration when user alternate scaling and rotation?

Many thanks,
QLands