简体   繁体   中英

I'm working on SFML and I really want to know deeply about Transformation that is about: position, rotation, scale and origin, of an object

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!!!

Maybe, this two links can help you:

The doc of sf::Transform

The github source code

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 -aka vectors- by a transform matrix. Those matrices have particular values.

Scaling

To scale from the origin by a factor k , the matrix will be like this:

k 0 
0 k 

Rotation

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, ie 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.

Translation

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM