Reputation: 35
I am looking at the "SFML/Graphics/Transform.h"
and "SFML/Graphics/Transformable.h"
headers and I can't
understand one thing. I minimize
the classes so you guys can get it easily:
// "SFML/Graphics/Transform.h"
class Transform
{
public:
// Default constructor
Transform();
// Construct a transform from a 3X3 matrix
Transform(float a00, float a01, float a02,
float a10, float a11, float a12,
float a20, float a21, float a22);
};
// "SFML/Graphics/Transformable.h"
class Transformable
{
private:
Vector2f mPosition; // Position of the object in 2D world.
float mRotation; // Orientation of the object, in degress.
Vector2f mScale; // Scale of the object.
Vector2f mOrigin; // Origin of translation, rotation and scaling.of the object.
mutable Transform mTransform; // Combined transformation of the object.
mutable bool mTransformNeedUpdate; // Does the transform need to be recomputed?
mutable Transform mInverseTransform; // Combined transformation of the object.
mutable bool mInverseTransformNeedUpdate; // Does the transform need to be recomputed?
public:
// Functions to implement transformation
void setPostion(float x, float y);
void setPosition(const Vector2f& position);
void setRotation(float angle);
void setScale(float factorX, float factorY);
void setScale(const Vector2f& factors);
void setOrigin(float x, float y);
void setOrigin(const Vector2f& orgin);
const Vector2f& getPosition() const;
float getRotation() const;
const Vector2f& getScale() const;
const Vector2f& getOrigin() const;
void move(float offsetX, float offsetY);
void move(const Vector2f& offset);
void rotate(float angle);
void scale(float factorX, float factorY);
void scale(const Vector2f& factors);
// What I don't understand
const Transform& getTransform() const;
const Transform& getInverseTransform() const;
};
In the "SFML/Graphics/Transformable.cpp"
the "getTransform()"
function
is implemented as the following code:
const Transform& Transformable::getTransform() const
{
// Recompute the combined transform if needed
if (mTransformNeedUpdate)
{
float angle = -mRotation * 3.141592654f / 180.f;
float cosine = static_cast<float>(std::cos(angle));
float sine = static_cast<float>(std::sin(angle));
float sxc = mScale.x * cosine;
float syc = mScale.y * cosine;
float sxs = mScale.x * sine;
float sys = mScale.y * sine;
float tx = -mOrigin.x * sxc - mOrigin.y * sys + mPosition.x;
float ty = mOrigin.x * sxs - mOrigin.y * syc + mPosition.y;
mTransform = Transform( sxc, sys, tx,
-sxs, syc, ty,
0.f, 0.f, 1.f);
mTransformNeedUpdate = false;
}
return mTransform;
}
My question is how they implement these values: sxc
, syc
, sxs
, sys
, tx
, ty
like that and why they put them into the 3X3 matrix by that order.
Thank you a lot!!!
Upvotes: 0
Views: 839
Reputation: 1040
It seems you're asking how geometric transformations are generally handled in computer graphics.
Be it in 2d or 3d (or n
d I guess), you can implement scaling and rotation by way of matrix multiplication. That is, you have an object -a bunch of points- and you transform it by multiplying the coordinates of each point -a.k.a vectors- by a transform matrix. Those matrices have particular values.
To scale from the origin by a factor k
, the matrix will be like this:
k 0
0 k
Rotation of angle a
around the origin:
cos(a) -sin(a)
sin(a) cos(a)
These 2x2 matrices can then be multiplied by a 2d vector. The result will be a 2d vector with the transformed coordinates.
You can also combine these two transforms, i.e. do rotation and scaling all at once, by first multiplying the two transforms together, and use the resulting 2x2 matrix to do the product with a vector.
The problem is you cannot do translation as a product in this system. You could do it by way of vector addition. But to do all transforms uniformly and efficiently, something called homogeneous coordinates are used. In that system, 2d transformations need points as 3d vectors and 3x3 matrices. 3d transforms need 4d vectors and 4x4 matrices.
The matrix you see in SFML's source is the combination (or composition) of the scale, rotation and translation information contained in the sf::Transform object, in homogeneous coordinates. The values are arranged in the matrix in the right way to do the transformations just by applying the product of the matrix to a vector. sf::Vector2 actually contains 3 components.
Upvotes: 1