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

Author Topic: sf::Rect variable names  (Read 4140 times)

0 Members and 1 Guest are viewing this topic.

Strikerklm96

  • Jr. Member
  • **
  • Posts: 74
    • View Profile
    • Email
sf::Rect variable names
« on: April 13, 2016, 10:23:39 pm »
I understand why sf::Rect uses left and top as variables, but this causes, as I just experienced, significant confusion. I wanted to use it in a standard coordinate system, and that caused strange bugs as you can imagine.
What the class actually wants is minX and minY. And what coordinate system you are in shouldn't change how you think about a class. For example, even though the vector class is in sf::namespace, and intended for the screen coordinate system, the Vector class doesn't ask for down and right instead of x and y.

Edit to clarify the problem:
A constructor of sf::Rect takes (left, top, width, height), and that's how they are stored too.
So if you want a 2x2 square surrounding (0,0), you would just do (-1,1,2,2) right? Wrong (maybe).
The left and top in a standard coordinate system with a positive width and height would be minX (left) and maxY(top), but sf::Rect took into consideration that most users would be using window coordinates where Y is negative. So (left,top) isn't actually the top left coordinate in the standard coordinate system, it's the bottom left. This through me for a loop when trying to use the class in a standard coordinate system (for it's various other functions of intersecting and contains).
« Last Edit: April 14, 2016, 07:18:44 pm by Strikerklm96 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
AW: sf::Rect variable names
« Reply #1 on: April 13, 2016, 10:40:13 pm »
I don't understand what caused you problems. Can you elaborate?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Rect variable names
« Reply #2 on: April 13, 2016, 11:22:55 pm »
I see your point. The straightforward counter-argument would be: "minX/minY" may cause confusion because SFML uses a coordinate system where "left/top" are the correct terms, and sf::Rect is intended to be used with SFML.

But let's have a closer look. One of the sf::Rect constructors takes vector parameters called "position" and "size". Following the "position" naming, the variables could be called only "x" and "y". Strictly speaking, "minX" and "minY" are wrong, since the width and height may be negative. Obviously, the same reasoning applies to "left" and "top".

This naming was introduced long before the concept of negative widths and heights (which is another debatable point, btw, but they allow for a few nice features). It is a relict of SFML 1. I have been around for almost a decade now, and in versions as early as SFML 1.2 vectors weren't part of the library -- just "left" and "top" for positioning. I guess since there was never a real problem with it, and negative sizes are a late 2.x introduction, we just left it. For backward compatibility reasons, we cannot change the naming until SFML 3, but in my opinion it can definitely be discussed.

Personally, I would even migrate from 4 scalar coordinates to 2 vectors. It makes so many things simpler and enables higher-level reasoning. Vectors are ubiquituous in SFML, yet sf::Rect is one of the few places that doesn't play well with them. Maybe also the negative size topic is worth reconsideration.
« Last Edit: April 13, 2016, 11:33:41 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Strikerklm96

  • Jr. Member
  • **
  • Posts: 74
    • View Profile
    • Email
Re: AW: sf::Rect variable names
« Reply #3 on: April 14, 2016, 07:17:43 pm »
I don't understand what caused you problems. Can you elaborate?

Sorry, I never really stated the problem  :P
A constructor of sf::Rect takes (left, top, width, height), and that's how they are stored too.
So if you want a 2x2 square surrounding (0,0), you would just do (-1,1,2,2) right? Wrong (maybe).
The left and top in a standard coordinate system with a positive width and height would be minX (left) and maxY(top), but sf::Rect took into consideration that most users would be using window coordinates where Y is negative. So (left,top) isn't actually the top left coordinate in the standard coordinate system, it's the bottom left. This through me for a loop when trying to use the class in a standard coordinate system (for it's various other functions of intersecting and contains).

"minX" and "minY" are wrong, since the width and height may be negative. Obviously, the same reasoning applies to "left" and "top".
Lol, you got me, that is totally valid.

Personally, I would even migrate from 4 scalar coordinates to 2 vectors. It makes so many things simpler and enables higher-level reasoning. Vectors are ubiquituous in SFML, yet sf::Rect is one of the few places that doesn't play well with them. Maybe also the negative size topic is worth reconsideration.
What is the point of negative dimensions other than making it go the other direction?
2 Vectors makes a lot of sense to me and was how I would think of it, even if they get stored as 4 seperate items in the class, the interface for a rectangle would make perfect sense in Vectors. Would you want to store two vectors like (minX,minY and maxX,maxY) or (position, dimensions)?
« Last Edit: April 14, 2016, 08:03:35 pm by Strikerklm96 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: sf::Rect variable names
« Reply #4 on: April 15, 2016, 11:11:03 am »
Ah okay I got it now.

As Nexus said the class was created for SFML, so it is fitted for the coordinate system that SFML.
If you put it into your own coordinate system it obviously won't comply to your system. minX/minY won't change anything because I could just as easily decide that the origin of my coordinate system it top/right and then counting up towards bottom/left and suddenly it doesn't fit my coordinate system anymore either.

For your own system (I assume your Raytracer?), it's probably better to just create your own class, that fits your naming scheme etc. sf::Rect is a rather simple class, so this should not be a problem and if you really must, you could also just copy&paste the full implementation. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Rect variable names
« Reply #5 on: April 17, 2016, 01:50:13 pm »
As Nexus said the class was created for SFML, so it is fitted for the coordinate system that SFML.
If you put it into your own coordinate system it obviously won't comply to your system.
The problem is that the naming is not even consistent within SFML itself, due to later introduced features that were not anticipated in the original design (as outlined in my post above).

What is the point of negative dimensions other than making it go the other direction?
It's mainly that. Negative rectangles can be used for flipped texture rectangles -- they are one way of mirroring sprites horizontally/vertically. We would have to look at user code to see whether it's used in other ways, maybe even in logic code.

2 Vectors makes a lot of sense to me and was how I would think of it, even if they get stored as 4 seperate items in the class, the interface for a rectangle would make perfect sense in Vectors.
I don't even think it would make sense to store 4 separate coordinates in the future, it will just add unnecessary conversions. At runtime, nothing changes if 2 coordinates are wrapped in a vector class, after all this is C++ and zero-abstraction overhead.

Would you want to store two vectors like (minX,minY and maxX,maxY) or (position, dimensions)?
Position and size. We had two positions in SFML 1 and moved away from it, mainly because it wasn't intuitive whether the second position was inside the rectangle. Also, I have personally made the experience that position + size are often easier to work with.

For SFML 3, I could imagine the following API. It wouldn't semantically be different from what we have now, just different names and vectors instead of separate coordinates. Instead of rect.left, we would have rect.position.x, while rect.width would be replaced with rect.size.x. The fact that there's a need for vectors is already apparent now, considering the vector constructor and possible getPosition()/getSize() methods.
template <typename T>
struct Rect
{
    ... // methods

    Vector2<T> position;
    Vector2<T> size;
};
« Last Edit: April 17, 2016, 01:53:55 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything