Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sf::Transform tutorial -- clarify transform order #135

Merged
merged 1 commit into from
Dec 21, 2021

Conversation

Bromeon
Copy link
Member

@Bromeon Bromeon commented Dec 7, 2019

Clarify order of transforms, as highlighted by pvigier in SFML/SFML#1608.

Once people agree with the wording, we can backport it to older tutorials.

@Bromeon Bromeon changed the title [wip] sf::Transform tutorial -- clarify transform order sf::Transform tutorial -- clarify transform order Dec 7, 2019
@@ -160,7 +160,7 @@
sf::Transform t4 = t1 * t2 * t3;
</code></pre>
<p>
You can apply several predefined transformations to the same transform as well. They will all be combined sequentially:
You can apply several predefined transformations to the same transform as well. They will all be combined sequentially, in reverse order: the last operation (here <code>scale</code>) is applied first, and will be affected by operations above it in code (second would be <code>translate(-10.f, 50.f)</code>, for example).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it always in reverse order or just reverse order for the listed provided here?

Personally, I still don't understand why it is applied in reverse. 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple example: you start with a rectangle (black) as shown in the left graphic. The vector v represents each vertex' position -- the transformed rectangle is a result of transforming each vertex.

  • First, you rotate v using the rotation matrix R. The result (blue) is R * v, which we call w.
  • Now, you apply a translation T to w.
    Same as before, the result (green) is T * w, which is T * (R * v).
    Matrix multiplication is associative; this is the same as T * R * v.
  • Applying an additional scale transform S will yield S * T * R * v (red).

grafik

You see that even though the first transform was R, it's the rightmost expression in the equation -- or the last statement in code. In other words, R is written closest to v, and R * v can be understood as an intermediate vector, which is then further transformed by T, and last S.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this topic (order of transform) is something that we should elaborate in the tutorial, or if it's out of scope.

Any other feedback to the PR?

@Bromeon
Copy link
Member Author

Bromeon commented Mar 22, 2020

Is this blocked by the missing translation?

@Bromeon
Copy link
Member Author

Bromeon commented Oct 31, 2020

Anyone wanting to translate this to French? :)
(not sure it ends well if I try...)

Also, would it make sense to add something like this example to the doc?
https://github.com/SFML/SFML-Website/pull/135/files#r356254486

Simple example: you start with a rectangle (black) as shown in the left graphic. The vector v represents each vertex' position -- the transformed rectangle is a result of transforming each vertex.

  • First, you rotate v using the rotation matrix R. The result (blue) is R * v, which we call w.
  • Now, you apply a translation T to w.
    Same as before, the result (green) is T * w, which is T * (R * v).
    Matrix multiplication is associative; this is the same as T * R * v.
  • Applying an additional scale transform S will yield S * T * R * v (red).

grafik

@Bromeon Bromeon marked this pull request as ready for review September 29, 2021 17:57
@Bromeon
Copy link
Member Author

Bromeon commented Sep 29, 2021

Even if no one has the time/motivation to translate it to French, might be still worth adding it to the English docs.

@kimci86
Copy link
Contributor

kimci86 commented Sep 30, 2021

Hello,
I think it is wrong to say that operations (i.e. transformations) are combined (i.e. matrices are multiplied) in reverse order.
Transforming a vector with the combination of transformations T1 and T2 indeed is equivalent to first transforming the vector with T2 and then T1, but the combination still is in the given order T1 * T2.
Matrix multiplication is equivalent to function composition. The composition of functions g and f, noted g ∘ f, first applies f and then g when applied to an argument.

So I suggest this wording (not sure when to use the word "transformation" or "operation"):

You can apply several predefined transformations to the same transform as well. They will all be combined sequentially.
Note that transforming an object with a combination of transformations is equivalent to applying each operation in reverse order. The last operation (here scale) is applied first, and will be affected by operations above it in code (second would be translate(-10.f, 50.f), for example).

@eXpl0it3r
Copy link
Member

@Bromeon what do you think of kimci86's suggestion?

@Bromeon
Copy link
Member Author

Bromeon commented Oct 19, 2021

I think kimci86's suggestion makes sense. I wonder if we should even include the example picture that I made, to clarify the order.

@kimci86
Copy link
Contributor

kimci86 commented Oct 19, 2021

About the picture, I find it confusing because R is not only a rotation and S is not only a scale transform. R and S on the picture also include a translation. For example, if R was only a rotation, the bottom left corner of the blue rectangle would still be at the origin (0,0).

@Bromeon
Copy link
Member Author

Bromeon commented Oct 20, 2021

Adjusted it.

@kimci86
Copy link
Contributor

kimci86 commented Oct 20, 2021

In French, it can be:

Remarquez que transformer un objet en combinant plusieurs transformations est équivalent à effectuer chaque opération dans l'ordre inverse. La dernière opération (ici scale) est appliquée en premier, et sera affectée par les opérations en amont dans le code (la deuxième serait translate(-10.f, 50.f), par exemple).

Co-authored-by: kimci86 <kimci86@hotmail.fr>
@Bromeon
Copy link
Member Author

Bromeon commented Nov 2, 2021

Integrated @kimci86's translation, credited him/her/them via Co-authored-by.

@Bromeon
Copy link
Member Author

Bromeon commented Dec 21, 2021

Can we merge this? 🙂

@eXpl0it3r eXpl0it3r merged commit 5e81b02 into master Dec 21, 2021
@eXpl0it3r
Copy link
Member

Woops, forgot about this 🙂

@eXpl0it3r eXpl0it3r deleted the bugfix/transform_tutorial branch December 21, 2021 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants