Operating system or device, Godot version, GPU Model and driver (if graphics related):
Windows 10 Godot 3.0 beta
Issue description:
I'm trying to rotate some normalized Vector2 (and trying to normalize some rotated Vector2) by 0 phi. The result of some of the vectors is Vector2(x, -0) or (-0, y), this absolutely mess with my logic because I need to compare this vectors for some validations. E.g. I need to connect 2 nodes in a grid, but they can only connect if the input direction of the current objects matches the output direction of the objects it is trying to connect to. So let's say an object has a connection direction of Vector2(0,-1) so objects coming from below would be able to connect to it. But let's say this object is rotated 90 degrees (i don't know the maths but the connection vector will change, maybe to Vector2(1,0)) so I'm using Vector2.rotatedto normalize this connection vector. BUT the problem is that it is overwriting the 0s with -0 so even if the connection was supposed to happen it doesn't because Vector2(1,0) is different from Vector2(1,-0).
This happens even when rotating the vector by 0 radians or 0 degrees.
Steps to reproduce:
Vector2Link to minimal example project:
Test the TestScene.tscn and look at the debugger (try to connect 2 instances of the first object of the list in the left panel by dragging and dropping one and then instancing another right below it)
source.zip
Also, maybe a related bug.
if you hardcode a Vector2 with -0 it is overwriten by 0, but for some reason if you just reference it (????) it isn't overwritten and therefore a verification comparing -0 and 0 will return false
Steps to reproduce:
Vector2Now try this
Vector2Now print a comparison between the two Vectors ((0, 1) and (-0, 1))
And also print a test using the -0 vector:
print(Vector2.x == -0 and print(Vector2.x == 0 both return false
From what I tested, it looks like the problem is not the -0.0f specifically (it is a valid floating point number, and in most cases Godot correctly assumes it equals 0.0f); if you test other Vectors like Vector2(1.0,-1.0) and rotate it by 0.0 phi, it also won't be equal to the original vector without rotation.
Vector2(1.0,-1.0) rotated by 0.0 phi and Vector2(1.0,-1.0) without rotation had different lengths (printing it gave me 1.414213 1.414214), so this is a floating point error caused by rotation (probably).
But rotating a vector by 0 phi should return a vector equal to the used for rotation, shouldn't it?
Yeah, as I expected, it is just a floating number approximation error. In the case of Vector2(0.0,-1.0), rotating it by 0.0 phi actually equals to:
Vector2.x: -0.00000004371100000000000000000000
Vector2.y: -1.00000000000000000000000000000000
So that's why it shows as a -0.0, but it's actually a different number (just very close to -0.0), and different than 0.0f.
Can this kind of error be corrected? It looks like a normal floating number operation gimmick, and the edge case (rotation by 0.0 phi) can be avoided by the user calling the function (just don't rotate by 0.0phi if you want to avoid floating number voodoo, or maybe just floor both x and y of your Vector2 by 3 decimals at most after rotating).
EDIT: @henriiquecampos technically yes, but the rotation itself is a floating number operation that will result in this kind of behavior. That's why I'm not sure if this is a valid edge case to test on rotation, or if this is the expected behavior and the user should be aware of that.
Seems like "flooring" them would be the workaround. But this is kinda strange:
Seems like entropy acting or being denied :P
@henriquelalves bu if the problem is the floating precision, why multiplying 2 integers would be related to that?
I mean, if you test:
var v = Vector2(0,1)
v.x *= -1
print(v)
it will also return (-0, 1)
@henriiquecampos Vector2 components are always float numbers (real_t on the source code, I'm guessing to change the precision [32-64 bits] according to the availability); it is only converting your integers.
We have now entered release freeze for Godot 3.0 and want to focus only on release critical issues for that milestone. Therefore, we're moving this issue to the 3.1 milestone, though a fix may be made available for a 3.0.x maintenance release after it has been tested in the master branch during 3.1 development. If you consider that this issue is critical enough to warrant blocking the 3.0 release until fixed, please comment so that we can assess it more in-depth.
This will not be fixed, sorry. -0 is a valid number and we are dealing with floating point here. Adding more code to make the output prettier will always hamper performance.
Floating point should work as expected, these small hacks may break other things eventually if added,