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

[raymath] Vector2LineAngle() may be giving wrong results #3387

Closed
Murlocohol opened this issue Oct 8, 2023 · 18 comments
Closed

[raymath] Vector2LineAngle() may be giving wrong results #3387

Murlocohol opened this issue Oct 8, 2023 · 18 comments

Comments

@Murlocohol
Copy link
Contributor

As far as I am aware I have done the following:

  • I tested it on latest raylib version from master branch
  • I checked there is no similar issue already reported
  • I checked the documentation on the wiki
  • My code has no errors or misuse of raylib

Issue description

Vector2Angle and Vector2LineAngle give results of different signedness. This might be intended behavior but I wasn't sure.

After looking at some other functions that use angles (Vector2Rotate() and DrawCircleSector()) it seems raylib has a clockwise bias for angles, so I am inclined to think that Vector2Angle() has the correct result of the two.

Issue Screenshot

screenrec001

Solution

In raymath.h, Simply changing "atan2f" in Vector2LineAngle() to "-atan2f" should fix the issue.

Code Example

You can test the behavior with the following program:

#include "raylib.h"

#include "raymath.h"

int main(void){

    int screenWidth = 800;
    int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "Vector Angle Test");
    SetTargetFPS(60);

    Vector2 vOrigin = { (float)screenWidth/2.0f, (float)screenHeight/2.0f };
    Vector2 v1 = Vector2Add(vOrigin, (Vector2){100.0f, 0.0f});
    Vector2 v2 = Vector2Add(vOrigin, (Vector2){-100.0f, 80.0f}); 
    int v2Flipped = 0;

    float angleVector;
    float angleLine; 

    while(!WindowShouldClose()){

        if (v2Flipped && IsKeyPressed(KEY_SPACE))
        {
            v2 = Vector2Add(vOrigin, (Vector2){-100.0f, 80.0f});
            v2Flipped = 0;
        } 
        else if (IsKeyPressed(KEY_SPACE))
        {
            v2 = Vector2Add(vOrigin, (Vector2){-100.0f, -80.0f});
            v2Flipped = 1;
        }

        Vector2 v1Normal = Vector2Normalize(Vector2Subtract(v1, vOrigin));
        Vector2 v2Normal = Vector2Normalize(Vector2Subtract(v2, vOrigin));

        angleVector = Vector2Angle(v1Normal, v2Normal)*RAD2DEG;
        angleLine = Vector2LineAngle(vOrigin, v2)*RAD2DEG;

        BeginDrawing();

            ClearBackground(RAYWHITE);

            DrawText(TextFormat("ANGLE VECTOR: %3.2f", angleVector), 20, 20, 20.0f, BLACK);
            DrawText(TextFormat("ANGLE LINE: %3.2f", angleLine), 20, 40, 20.0f, BLACK);

            DrawLineEx(vOrigin, v1, 3.0f, BLACK);
            DrawLineEx(vOrigin, v2, 3.0f, BLACK);

            DrawCircleV(vOrigin, 5.0f, LIME);
            DrawCircleV(v1, 5.0f, BLUE);
            DrawCircleV(v2, 5.0f, RED);

            DrawText("vOrigin", vOrigin.x, vOrigin.y+10, 10.0f, DARKGRAY);
            DrawText("v1", v1.x+10, v1.y, 10.0f, DARKGRAY);
            DrawText("v2", v2.x-20, v2.y, 10.0f, DARKGRAY);

        EndDrawing();

    }

    CloseWindow();

}

Apologies if this is painfully bad, it's my first time submitting an issue.

@Murlocohol Murlocohol changed the title raymath Vector2LineAngle() may be giving wrong results [raymath] Vector2LineAngle() may be giving wrong results Oct 8, 2023
@sDos280
Copy link
Contributor

sDos280 commented Oct 8, 2023

Yep, Vector2LineAngle really seem to output the wrong values...

Ray, I think it will be better to make sure there is an explanation on how raylib(raymath) defines its axis grid, so we can better argue about what is wrong and what is right.

I had seen that a lot of has been opened about the angles function, so i think adding a conversion on the outputted angle from raymath's functions would be a great way to remove any confusion in the future.
(If there is already an conversion/explanation on the raymath's axis, I think it should be much more straightforward on where we can find it, and what it really is)

p.s. sorry for the broken English.

@raysan5
Copy link
Owner

raysan5 commented Oct 9, 2023

@Murlocohol @sDos280 Yes, there is some problem with that function, you can check raymath_vector_angle example.

Help on making it working as expected is welcome.

@veins1
Copy link
Contributor

veins1 commented Oct 9, 2023

There is indeed an inconsistency between Vector2Angle and Vector2LineAngle.
If raymath is supposed to be a general math library then Vector2Angle is wrong and Vector2LineAngle is correct.
The reason it seems otherwise is because you measure angle from X+ to Y+ anti-clockwise, as we were taught in school.
But remember that Y+ is down on a screen when drawing in raylib, so from X+ to Y+ is now clockwise.

@sDos280
Copy link
Contributor

sDos280 commented Oct 9, 2023

Well, that's the problem. That why we need concrete conversation for angle output/measurement.

In my interpretation of raymath, raymath is just a mathematical tool (based on the regular angle measurement we all know and love), not one that is specifically for raylib uses, but for general purpose...

@sDos280
Copy link
Contributor

sDos280 commented Oct 9, 2023

@raysan5 what your opinion on the way angels should be measured? (Raylib space) x+ to y+ positive angle, or (raylib space) x+ to y+ positive angle (like in the regular axis grid)?

@Murlocohol
Copy link
Contributor Author

Just put up a pull request for this #3394 that fixes raymath.h and the corresponding example. I went with clockwise angles just so raylib is consistent for now. If I can throw my hat into the ring, I would vote for counter-clockwise angles, simply because I think that is what most people learn in school (and come to expect.)

Here is a gif of the updated example working, I also added the ability to move v1 around because that's fun and stuff.

screenrec001

Again, apologies if I mess anything up, this is my first pull request.

@veins1
Copy link
Contributor

veins1 commented Oct 9, 2023

The problem is in Vector2Angle, not Vector2LineAngle. I would advise against using rendering in raylib to determine the correctness of these functions. Intuition about angles is thrown off by the fact that Y+ is down in raylib. If you really want to, you can use a custom matrix that makes Y+ up and test it that way.

@sDos280
Copy link
Contributor

sDos280 commented Oct 9, 2023

First of all, You can't massed things up, in the worst case your PR wouldn't be merged, so don't worry 😉.

I agree with you, angle measurement should be (positive for) counter clockwise, but I see people disagreeing with us...

@orcmid
Copy link
Contributor

orcmid commented Oct 9, 2023

"The coordinate system in raylib is a 2D Cartesian Display coordinate system. The origin (0, 0) is located at the top-left corner of the screen, and the x-axis extends to the right, while the y-axis extends downwards. The unit of measurement is in pixels."
So sayeth Bing Chat.

This is a standard graphics arrangement for computer displays. (Also for ASCII art on line printers.) It has the advantage of placing no inherent constraint on the horizontal or vertical capacity of the display.

All of the essential stuff from InitWindow on down is based on this. The layout of objects (e.g., text lines) is based on this in accord with how it will be observed on a display.

So, when you say clockwise/counter-clockwise, are you talking about in the coordinate system (standard textbook Cartesian orientation) or as seen by the user (computer graphic orientation)? If you mean counter-clockwise in the viewer's frame of reference, that will be clockwise in the Cartesian orientation.

At some point you have to cope with window height to place and animate the images as seen by the viewer. Since raylib is predisposed to graphic orientation, I trust it is employed consistently in the raylib functions where it matters. The application can adjust and scale on that basis. Transformations for orientation and axis scale can also be done, but it can be expensive if there is much of that. I suspect that text functions presume graphical orientation, text appearing right-side-up by default.

It would be useful for raylib documentation to be emphatic about this. It's not on the cheatsheet. In the wiki perhaps?

@Murlocohol
Copy link
Contributor Author

@veins1
Right! I wasn't even thinking about that, I feel dumb now.

@sDos280
I appreciate your kindness 🙃

@orcmid

If you mean counter-clockwise in the viewer's frame of reference, that will be clockwise in the Cartesian orientation.

That is exactly what I meant and I realized my error all too late, unfortunately.

@raysan5
Copy link
Owner

raysan5 commented Oct 10, 2023

@Murlocohol Thank you very much for reviewing the issue and the example! Proposed solution looks good to me!

@raysan5 raysan5 closed this as completed Oct 10, 2023
@Murlocohol
Copy link
Contributor Author

Ahh! Sorry to reopen this, I was in the middle of fixing the edit as pointed out by @veins1 and @orcmid. I posted a new pull that should be the correct version now #3396. Sorry I wasn't faster on the draw or I could've avoided this.

I made another example that shows the newly implemented correct behavior:
screenrec001

@Murlocohol
Copy link
Contributor Author

Nevermind, I don't know how to reopen this. Hopefully @raysan5 will see this.

@raysan5
Copy link
Owner

raysan5 commented Oct 10, 2023

@Murlocohol Mmmh... I tried the PR I merged and it seemed to work as expected, what was the problem?

@raysan5 raysan5 reopened this Oct 10, 2023
@raysan5
Copy link
Owner

raysan5 commented Oct 10, 2023

@Murlocohol Now it seems to be completely broken, please, could you sync to latest master branch and review it?

@raysan5
Copy link
Owner

raysan5 commented Oct 10, 2023

@Murlocohol Nevermind, I just reviewed it.

@Murlocohol
Copy link
Contributor Author

@raysan5 Thank you! And sorry again I'm not completely used to using git so I think I messed up with the commits on my end.

@orcmid
Copy link
Contributor

orcmid commented Oct 10, 2023

@Murlocohol

If you mean counter-clockwise in the viewer's frame of reference, that will be clockwise in the Cartesian orientation.

That is exactly what I meant and I realized my error all too late, unfortunately.

This is something always worth learning to keep in mind. Don't be embarrassed. We can all slip up on this one. And learn from each other.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants