Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Transform::operator()  (Read 3490 times)

0 Members and 1 Guest are viewing this topic.

korczurekk

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • Email
sf::Transform::operator()
« on: March 17, 2017, 04:49:22 pm »
Hi,
Transforming some container with points inside is know pretty harsh:
std::transform(points.begin(), points.end(), points.begin(), [&t](sf::Vector2f p) {
        return t.transformPoint(p);
});
It would be a lot nicer if sf::Transform provided () operators for both points and rectangles:
std::transform(points.begin(), points.end(), points.begin(), t);

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: sf::Transform::operator()
« Reply #1 on: March 17, 2017, 05:07:02 pm »
I've got something even shorter with the current API:

for (auto& p : points) p = t * p;
Laurent Gomila - SFML developer

korczurekk

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • Email
Re: sf::Transform::operator()
« Reply #2 on: March 17, 2017, 05:16:18 pm »
It woks well unless I want to keep vertices in one container, std::transform lets me choose where to store it. And TBH, multiplying vector by transform is nowhere near being readable for some outsider that reads my code, especially if he isn't familiar with OpenGL and underlying maths.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: sf::Transform::operator()
« Reply #3 on: March 17, 2017, 09:00:46 pm »
Quote
It woks well unless I want to keep vertices in one container, std::transform lets me choose where to store
... points2.push_back(t * p);
With std::transform you have to either points2.resize() before the call, or std::back_inserter(points2) so it's not less verbose.

Quote
And TBH, multiplying vector by transform is nowhere near being readable for some outsider that reads my code, especially if he isn't familiar with OpenGL and underlying maths.
I think that (if we forget transformPoint of course) operator* is more intuitive than operator() because it sticks to the mathematical definition of what is done -- here we really multiply the transform and the point.
Laurent Gomila - SFML developer

korczurekk

  • Full Member
  • ***
  • Posts: 150
    • View Profile
    • Email
Re: sf::Transform::operator()
« Reply #4 on: March 17, 2017, 10:13:56 pm »
Quote
It woks well unless I want to keep vertices in one container, std::transform lets me choose where to store
... points2.push_back(t * p);
With std::transform you have to either points2.resize() before the call, or std::back_inserter(points2) so it's not less verbose.
At this point it's either slow or I have to write more code to reserve memory, it may be surprising, but I really know 'bout push_back method.  ;)

Quote
And TBH, multiplying vector by transform is nowhere near being readable for some outsider that reads my code, especially if he isn't familiar with OpenGL and underlying maths.
I think that (if we forget transformPoint of course) operator* is more intuitive than operator() because it sticks to the mathematical definition of what is done -- here we really multiply the transform and the point.
operator() is not meant for manual use, in this case ofc operator* is better, I just want it so it can be passed to all those STL functions that take callable objects as parameters. TBH some additional proxy class and method callable() that'd return it from sf::Transformable would also be nice, from some points of view even cleaner and would ensure that beginners won't misuse that operator(). However it would generate wayyy more code for SFML devs to maintain, so I didn't really think seriously about suggesting it.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: sf::Transform::operator()
« Reply #5 on: March 19, 2017, 01:34:06 pm »
Quote
At this point it's either slow or I have to write more code to reserve memory, it may be surprising, but I really know 'bout push_back method.
What's your point exactly? You want to be able to use std::transform, because it is supposed to be less verbose, but I try to show you that the loop it tries to hide can now be even less verbose with C++11 syntax and the multiply operator. So what now? :D

Quote
operator() is not meant for manual use, in this case ofc operator* is better, I just want it so it can be passed to all those STL functions that take callable objects as parameters. TBH some additional proxy class and method callable() that'd return it from sf::Transformable would also be nice, from some points of view even cleaner and would ensure that beginners won't misuse that operator(). However it would generate wayyy more code for SFML devs to maintain, so I didn't really think seriously about suggesting it.
We can't put operator() in all classes just so that they can be used directly as the last argument of standard algorithms. You need to adapt the syntax, and that's why lambdas exist ;)
Laurent Gomila - SFML developer