godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.15k stars 97 forks source link

Add a `PI/2` constant #1051

Closed lukostello closed 4 years ago

lukostello commented 4 years ago

Describe the project you are working on: 3d sokoban-like with twisty puzzle mechanics

Describe the problem or limitation you are having in your project: I keep using making my own PI/2 constant in each script

Describe the feature / enhancement and how it helps to overcome the problem or limitation: make a global PI/2 constant Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams: I call it DI but there is probably some other convention that other people have followed.

If this enhancement will not be used often, can it be worked around with a few lines of script?: Easy to overcome with lines of code but its so ubiquitous it shouldn't be necessary

Is there a reason why this should be core and not an add-on in the asset library?: Seems like something everyone would use

vnen commented 4 years ago

Why don't you just use PI/2? You don't need to define a new constant for that. If I saw DI in a code I would have to look up the definition, whereas with PI/2 I can just see what it is.

I don't know if there's a common math name for that. We have TAU which is the same as PI * 2 but that's already has widespread usage. C has the M_PI_2 constant but I think that's just confusing (is it PI/2 or PI*2?) when PI/2 can be used.

lukostello commented 4 years ago

Cuz I use it so often that I think I save a bit of computation from getting it from memory instead of having to divide by 2 every time I use it. Maybe there is a way to have PI/2 resolve to a constant rather than do math in the background, that would resolve the naming issue.

vnen commented 4 years ago

Any constant calculation is resolved at compile time. If you use 2 * 2 the GDScript compiler will use a 4 instead. Same applies to PI / 2. It won't run the calculations at runtime so there's no penalty in performance.

lukostello commented 4 years ago

even when its not set to a variable? for example if I did this:

_physics_process(delta):
      rotation.y = other_object.rotation.y * PI / 2

It would already have PI / 2 calculated during the original compilation?

vnen commented 4 years ago

even when its not set to a variable? for example if I did this:

_physics_process(delta):
      rotation.y = other_object.rotation.y * PI / 2

It would already have PI / 2 calculated during the original compilation?

Well, I guess it might depend on operator precedence. Since * and / have the same precedence, it would evaluate other_object.rotation.y * PI first and the / 2 later, so it wouldn't be able to optimize this case. But then you can use parentheses to force it: other_object.rotation.y * (PI / 2). A bit more annoying to write, but still easier to understand than a custom constant.

Honestly this is not super relevant optimization, unless you're doing it many times per frame.

lukostello commented 4 years ago

some frames I'm using it at least 20 times per frame

SIsilicon commented 4 years ago

Then why don't you just define it as a global constant?

const PI_2 = PI / 2
Jummit commented 4 years ago

I use PI / 2 a lot, since it's 90 degrees, which is one of the most used angles in game development. There's already PI * 2, so why not add a constant for PI / 2.

I do agree finding a good name would be difficult.

If I saw DI in a code I would have to look up the definition

I think HPI would be at least a little readable.

lukostello commented 4 years ago

how about BI as in BIsected PI

lukostello commented 4 years ago

Then why don't you just define it as a global constant?

const PI_2 = PI / 2

Because I use it in all of my classes not just one.

SIsilicon commented 4 years ago

So make a Singleton then with the constant.

aaronfranke commented 4 years ago

@lukostello Perhaps you should consider writing something similar to the Tau Manifesto but for Pi/2. Show us that this constant makes logical sense to use and that its uses are common.

Also, Pi/2 can also be written as Tau/4 (or TAU/4 in GDScript), which has the advantage of semantically meaning "a fourth of a turn", if you want your code to semantically make sense.

@vnen Well, I guess it might depend on operator precedence. Since * and / have the same precedence, it would evaluate other_object.rotation.y * PI first and the / 2 later, so it wouldn't be able to optimize this case.

Well... technically, when it comes to floats, multiplying or dividing by powers of two just means shifting the exponent around, except for edge cases like infinity and denormalized numbers. @vnen I don't know how much magic you want in GDScript, but technically we could optimize this case.

lukostello commented 4 years ago

Well I'm working on a grid based game with a lot of quarter turns. I keep track of what direction things face using ints 0-4: 0 being right going counter clockwise to 3 as down. For example when I initialize the variety of objects which can be placed in any of those 4 directions. I take their position in an array and multiply it by Pi/2 to set their rotation.y. I've got a lot of things of this variety happening in my game: ezgif com-video-to-gif I can only speak from my personal experience. It would really only be a treat to people who make grid based games same way you could include TAU/6 for hexagonally tiled games.

Calinou commented 4 years ago

Closing due to lack of support. This feature can be provided by adding a single line at the top of a script:

const PI_2 = PI / 2

You could also create a singleton with a PI_2 constant and reference it in your other scripts.

aaronfranke commented 2 years ago

I had a random thought and remembered this proposal. If you did make a TAU/4 or PI/2 constant in your own projects, you could call it RIGHT because it represents a right angle in radians, or something similar like RIGHT_ANGLE. Another option would be to call it QUARTER_TURN or similar because it represents a quarter turn in radians.