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

Author Topic: FS#82 - Add functions to sf::Vector2  (Read 8501 times)

0 Members and 1 Guest are viewing this topic.

kolofsson

  • Full Member
  • ***
  • Posts: 100
    • View Profile
FS#82 - Add functions to sf::Vector2
« on: April 25, 2010, 01:41:41 pm »
Hello, I've got a question about this ticket. Does it mean that it will soon be possible to use sf::Vector2f like a euclidean vector?

http://en.wikipedia.org/wiki/Euclidean_vector

Will it be possible to declare a vector not only by its XY coordinates, but with angle and magnitude as well?

If the vector is declared by XY coords, will it be possible to read its angle and magnitude, and vice versa?

Will it be possible to change the vector after it is declared?

Will the operators be overloaded so that we can add, substract or even multiply vectors? (http://en.wikipedia.org/wiki/Cross_product)

I'm asking, because I'd like to use the sf::vector in my physical equations, and not have to create a separate class for that.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: FS#82 - Add functions to sf::Vector2
« Reply #1 on: April 25, 2010, 02:04:10 pm »
Quote from: "kolofsson"
Will it be possible to declare a vector not only by its XY coordinates, but with angle and magnitude as well?

If the vector is declared by XY coords, will it be possible to read its angle and magnitude, and vice versa?
I don't think Laurent is going to implement this soon, but you have to ask him. The history of this ticket begins in these discussions. But as far as I remember, the status quo is kept up for the next time, since there is no generic and yet easy to use solution around.

Quote from: "kolofsson"
Will it be possible to change the vector after it is declared?

Will the operators be overloaded so that we can add, substract [...] vectors?
These things are already possible.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
FS#82 - Add functions to sf::Vector2
« Reply #2 on: April 25, 2010, 04:13:05 pm »
sf::Vector2 is not going to be a physics vector. Its purpose is to easily manipulate a (x, y) pair, nothing else.

But I think that most of the functions that you're mentionning (magnitude, angle, operators) should be implemented as free functions on top of a simple class like sf::Vector2, they shouldn't be part of the class itself anyway. At least that's how I would design them.
Laurent Gomila - SFML developer

TyRoXx

  • Newbie
  • *
  • Posts: 5
    • View Profile
FS#82 - Add functions to sf::Vector2
« Reply #3 on: July 12, 2010, 01:56:25 pm »
Quote from: "Laurent"
sf::Vector2 is not going to be a physics vector. Its purpose is to easily manipulate a (x, y) pair, nothing else.

Why do you call it vector if its only a pair of coordinates?  You should rename your pseudo vector to sf::Point2 or something. Methods like getLength(), getLengthSq() and normalize() are necessary for serious game programming.

Quote from: "Laurent"
But I think that most of the functions that you're mentionning (magnitude, angle, operators) should be implemented as free functions on top of a simple class like sf::Vector2, they shouldn't be part of the class itself anyway. At least that's how I would design them.

I thought SFML would be a C++ library...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
FS#82 - Add functions to sf::Vector2
« Reply #4 on: July 12, 2010, 03:40:31 pm »
Quote
Why do you call it vector if its only a pair of coordinates? You should rename your pseudo vector to sf::Point2 or something

Because it can represent a point, but also a distance or anything else with two coordinates. Thus, Vector is the only name which is abstract enough to match this definition.

Quote
Methods like getLength(), getLengthSq() and normalize() are necessary for serious game programming.

Of course. But "should it be integrated to SFML?" is a different question.

Quote
I thought SFML would be a C++ library...

C++ doesn't mean "everything is an object". Would you say that the standard library, with all its generic non-member functions, is not C++? In C++, free functions can be part of a class API and are sometimes a better/clever design choice.

By the way, this topic has already been debated, so please don't start a new endless discussion ;)
Laurent Gomila - SFML developer

TyRoXx

  • Newbie
  • *
  • Posts: 5
    • View Profile
FS#82 - Add functions to sf::Vector2
« Reply #5 on: July 12, 2010, 04:12:42 pm »
Quote from: "Laurent"
Quote
Methods like getLength(), getLengthSq() and normalize() are necessary for serious game programming.

Of course. But "should it be integrated to SFML?" is a different question.

There is no reason not to integrate it.

Quote from: "Laurent"
Quote
I thought SFML would be a C++ library...

C++ doesn't mean "everything is an object". Would you say that the standard library, with all its generic non-member functions, is not C++? In C++, free functions can be part of a class API and are sometimes a better/clever design choice.

I would not say that and I did not say it. Free functions CAN be in an API, but they should not if there is an alternative. Generic algorithms like std::for_each have to be global, but a function for calculating a vector's length is not generic only because Vector2 is a template. Just do not pollute the sf namespace with specific functions for this and that. Classes are not only for combining variables into a single one.

Why is
Code: [Select]

cout << getVectorLength(Vector2f(10, 20)) << endl;

better than
Code: [Select]

cout << Vector2f(10, 20).getLength() << endl;

?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
FS#82 - Add functions to sf::Vector2
« Reply #6 on: July 12, 2010, 09:33:38 pm »
Quote from: "TyRoXx"
There is no reason not to integrate it.
There are many reasons, although they may be not obvious to the average user, who doesn't have to care about designing a consistent, well-thought API. If you take a look at the discussions at my link posted above, you'll find a lot of explanations.

Quote from: "TyRoXx"
Free functions CAN be in an API, but they should not if there is an alternative.
Why should they not?

Quote from: "TyRoXx"
Generic algorithms like std::for_each have to be global, but a function for calculating a vector's length is not generic only because Vector2 is a template.
The decision between global and member functions doesn't primarily depend on the use of templates. Reusability is just one criterion (and can also be achieved by other abstraction features).

Quote from: "TyRoXx"
Why is [a free function] better than [a member function]?
To give you a general answer, you have more flexibility in many cases. To count some of them:
  • Global functions aren't limited to classes, they can be used for scalar types as well.
  • They can be overloaded for different object types.
  • They take implicit object conversions into account.
  • They increase encapsulation since they don't have direct access to all class members.
  • They can be written as templates once and be reused for multiple classes.
  • They can interact with argument dependent lookup.
  • They can be declared separate from the class definition.
Now it's your turn to tell me when member functions are the better choice (as long as free functions are still an alternative, i.e. when neither virtual nor non-public member access is required). ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

TyRoXx

  • Newbie
  • *
  • Posts: 5
    • View Profile
FS#82 - Add functions to sf::Vector2
« Reply #7 on: July 12, 2010, 10:18:07 pm »
(for simplicity I will only mention the getLength() function/method)

Quote from: "Nexus"
Quote from: "TyRoXx"
There is no reason not to integrate it.
There are many reasons, although they may be not obvious to the average user, who doesn't have to care about designing a consistent, well-thought API. If you take a look at the discussions at my link posted above, you'll find a lot of explanations.

I did not find a single argument. Only "Vector2<int> would be a problem".

Quote from: "Nexus"
Quote from: "TyRoXx"
Free functions CAN be in an API, but they should not if there is an alternative.
Why should they not?

Quoting myself:
Quote from: "TyRoXx"
Just do not pollute the sf namespace with specific functions for this and that. Classes are not only for combining variables into a single one.

Additionally (for example) Visual C++ lists all the methods when hitting . or -> which is not available for globals.

Quote from: "Nexus"
Quote from: "TyRoXx"
Generic algorithms like std::for_each have to be global, but a function for calculating a vector's length is not generic only because Vector2 is a template.

The decision between global and member functions doesn't primarily depend on the use of templates. Reusability is just one criterion (and can also be achieved by other abstraction features).

Are there any other criteria? In this case reusability does not matter anyway. The function would not be used for anything else that calculating that length.

    [*]Global functions aren't limited to classes, they can be used for scalar types as well. Does not matter, I only want to get a vector's length and nothing else
    [*]They can be overloaded for different object types. Several classes can have a same-looking method as well
    [*]They take implicit object conversions into account. I do not want anything to be converted into a vector implicitly
    [*]They increase encapsulation since they don't have direct access to all class members. Vector2 has only public members, is not even close to an argument btw
    [*]They can be written as templates once and be reused for multiple classes. Vector2 is already a template
    [*]They can interact with argument dependent lookup. Methods behave similarly
    [*]They can be declared separate from the class definition. Why should someone want that? Would be confusing to have vector functions in a different header than the vector itself
    [/list]

    Quote from: "Nexus"
    Now it's your turn to tell me when member functions are the better choice (as long as free functions are still an alternative, i.e. when neither virtual nor non-public member access is required). ;)

    If you want to use globals a lot, I would recommend C.

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    FS#82 - Add functions to sf::Vector2
    « Reply #8 on: July 12, 2010, 11:08:04 pm »
    Quote from: "TyRoXx"
    (for simplicity I will only mention the getLength() function/method)
    Note that some of my points refer to the advantages of global functions in general. I think we agree that not all the advantages can be applied  always. So, claiming that some of my arguments don't apply to sf::Vector2 in particular doesn't render them less good reasons to use member functions in other situations.

    Quote from: "TyRoXx"
    I did not find a single argument. Only "Vector2<int> would be a problem".
    You didn't search enough. For example, consider this thread.

    Quote from: "TyRoXx"
    Just do not pollute the sf namespace with specific functions for this and that.
    I don't see in how far this is a problem of practical relevance. It's not the global namespace, and there is no danger of name collisions.

    Quote from: "TyRoXx"
    Classes are not only for combining variables into a single one.
    I didn't say member functions should be avoided. I wanted to show that, in some cases, global functions are the better choice. However, sf::Vector2<T> is a particular example, since it only has two public member variables and some constructors. All the vector operators are global as well.

    Quote from: "TyRoXx"
    They can be overloaded for different object types. Several classes can have a same-looking method as well
    I expected that to come. However, this brings two restrictions: You must use classes (no other types are possible), and the classes must have a consistent interface, which is hard to achieve when dealing with different libraries (i.e. impossible without modifying library code). Global functions can work as adapters.

    Quote from: "TyRoXx"
    They take implicit object conversions into account. I do not want anything to be converted into a vector implicitly
    Maybe you don't. Others do. I even have a good example of an own class PolarVector2<T> which stores polar instead of cartesian coordinates. To work seamlessly with SFML, an implicit conversion may be desired:
    Code: [Select]
    PolarVector2<float> v;
    sf::GetLength(v); // possible
    v.GetLength();    // not possible

    Quote from: "TyRoXx"
    They increase encapsulation since they don't have direct access to all class members. Vector2 has only public members, is not even close to an argument btw
    Again, this is meant in general. And I don't think it's completely wrong if Scott Meyers propagates it.

    Quote from: "TyRoXx"
    They can interact with argument dependent lookup. Methods behave similarly
    Wrong, they do not. Do you know ADL? It's a namespace-related feature which can obviously not apply to member functions. The ability to abstract from types becomes less powerful if the types are restricted to classes. Consider the following code. You cannot achieve those semantics with member functions.
    Code: [Select]
    swap(a, b); // calls the correct function independent of
                // the type and namespace of a and b

    Quote from: "TyRoXx"
    They can be declared separate from the class definition. Why should someone want that? Would be confusing to have vector functions in a different header than the vector itself
    Because the header might be not accessible? What if I plan to expand the interface with a GetSquaredLength() function? It wouldn't be possible as a member without modifying SFML's code. For a global function, in contrast, this task becomes really easy.

    Quote from: "TyRoXx"
    If you want to use globals a lot, I would recommend C.
    Please be serious. I hope you see the difference between global functions and global variables. I don't know in how far your C++ becomes more idiomatic, modern or just "better" only because you use member functions instead of global ones without thinking about the implications. Remember: OOP doesn't mean to put everything into classes.
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development:

    TyRoXx

    • Newbie
    • *
    • Posts: 5
      • View Profile
    FS#82 - Add functions to sf::Vector2
    « Reply #9 on: July 12, 2010, 11:25:50 pm »
    Quote from: "Nexus"

    Quote from: "TyRoXx"
    They can interact with argument dependent lookup. Methods behave similarly
    Wrong, they do not. Do you know ADL? It's a namespace-related feature which can obviously not apply to member functions. The ability to abstract from types becomes less powerful if the types are restricted to classes. Consider the following code. You cannot achieve those semantics with member functions.
    Code: [Select]
    swap(a, b); // calls the correct function independent of
                // the type and namespace of a and b


    "similarly" = does in fact not matter because you always have an object when calling the method -> you do not have to tell the compiler where to look for the function.

    Now I would like to know why you don't want those methods in the vector. I do not understand your argumentation in the posts you linked.

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    FS#82 - Add functions to sf::Vector2
    « Reply #10 on: July 13, 2010, 12:21:00 am »
    Quote from: "TyRoXx"
    "similarly" = does in fact not matter because you always have an object when calling the method -> you do not have to tell the compiler where to look for the function.
    You're not always dealing with class instances. Here, the only thing you can tell is that two strings are swapped twice. If bla::MyString is for example a char*, the exchange still works (given std::swap() is accessible).
    Code: [Select]
    bla::MyString a, b;
    std::string c, d;

    swap(a, b);
    swap(c, d);


    Quote from: "TyRoXx"
    Now I would like to know why you don't want those methods in the vector. I do not understand your argumentation in the posts you linked.
    Okay, let's put the member/global discussion aside. ;)

    It's not that I wouldn't find a Length() function useful. The issue is, it doesn't easily integrate into the current SFML design, as far as I have understood Laurent. The main problem is probably genericity: How can the function template Length() know how it has to calculate the square root of the corresponding type? Using std::sqrt() is no option, because the vector can hold types other than float, double or long double. The proposed traits classes would be a solution, but metaprogramming in the public API doesn't seem to fit into SFML's "easy to use, even for beginners" philosophy.

    One has to realize that the requirements on a type T are very strict in order to compute the length of sf::Vector2<T>. It can't be an integral type because the root cannot be computed exactly. But there is even an official typedef sf::Vector2i, and it's not immediately clear why Length(Vector2i) is not meaningful, as both constructs are delivered together. Laurent would have to specify rules for the template argument T, possibly spreading further confusion and seeming to constrain the SFML vector functionality (now, almost every type can be used as a vector component).

    A further point is that Length() can't come alone. As soon as there is one function, there will be request for more. Does SFML need angle computation? Normalizing? Dot and cross products? That functionality implies further dependencies (for example, trigonometric functions). It's not easy to place the border. Especially if the part of users needing advanced vector functionality seems to be rather small, it might be not the worst idea to keep the status quo and leave the possibility to add features later, which is much better than removing them because of a design mistake.
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development:

    TyRoXx

    • Newbie
    • *
    • Posts: 5
      • View Profile
    FS#82 - Add functions to sf::Vector2
    « Reply #11 on: July 13, 2010, 01:38:26 am »
    Quote from: "Nexus"
    It's not that I wouldn't find a Length() function useful.

    You mean essential.

    Quote from: "Nexus"
    The issue is, it doesn't easily integrate into the current SFML design

    .. and the design is - of couse - more important than usability.

    What's wrong with:
    Code: [Select]

    T GetLength() const
    {
    using namespace std; //make custom sqrt overloads work
    return static_cast<T>(sqrt(X * X + Y * Y));
    }

    I do not see there any problems. Since the length of an Vector2i does not make much sense, no one will use GetLength() on it. If someone still needs that value he can use the method because integers implicitly convert to float or double. Even std::complex<T> should work because sqrt has an overload for it. If someone uses his own number class he can overload sqrt is his own namespace and ADL will do the rest.
    A traits template would be far too overcomplicated. Every graphics library does it more or less like above.
    And you do not have to treat the users like complete idiots.

    Nexus

    • SFML Team
    • Hero Member
    • *****
    • Posts: 6287
    • Thor Developer
      • View Profile
      • Bromeon
    FS#82 - Add functions to sf::Vector2
    « Reply #12 on: July 14, 2010, 09:22:59 pm »
    You have to know that I'm just attempting to show you possible reasons why the vector functions have not been integrated yet. But I'm not the developper of SFML, so it's just my interpretation.

    Quote from: "TyRoXx"
    A traits template would be far too overcomplicated. Every graphics library does it more or less like above.
    I don't understand why you're suddenly argumenting for free functions and against member ones. With traits, you have more control and don't need to enlarge the existing interface (for example, if there's already a Sqrt() instead of sqrt() function) or to break into the object's namespace to make ADL apply. But actually, I just wanted to show one option, there are certainly more with all their advantages and drawbacks.

    Quote from: "TyRoXx"
    and the design is - of couse - more important than usability.  [...] And you do not have to treat the users like complete idiots.
    Usability and design are strongly connected. You might imagine it too easy, library writing is not just adding a feature and it's there. It contains maintenance in the long term, and a lot of aspects have to fit other parts and the scope/intention of the library. SFML wouldn't have become a well-written, intuitive-to-use library (you hear that of many users in the forum) if it had just provided features because they might be useful, while spending no thought about how they're provided. I don't agree with everything in SFML either, but I try to understand the decisions (not at least since they don't concern only me, but a lot of other users as well).

    Anyway, Laurent has already said he might think about vector functions in the future. I don't believe blaming him for treating his users as idiots is very helpful hereby. I hope you can now reconstruct some of the current design choices, at least I tried to make them clear. I actually don't feel like endlessly continuing this discussion, the important things have been mentioned.
    Zloxx II: action platformer
    Thor Library: particle systems, animations, dot products, ...
    SFML Game Development: