-
-
Notifications
You must be signed in to change notification settings - Fork 403
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
Maths: struct representing an Angle #1169
Comments
@HurricanKai @Beyley thoughts? |
i personally would like it to at least have both a float and a double version, or even generic with all the math types being possible to shove in there, if feasable |
I think generic would not make much sense, because integer values would be unusable, due to the values ranging around PI values and requiring high precission. This leaves single and double. again, since the values would be around PI, a float has plenty of precission. doubles would only make sense for insane precission, or for counting a very large number of "turns" while retaining precission. Personally, I think a float implementation would cover most use cases, but if double is requested, then I would do AngleS[ingle] and AngleD[ouble] |
im just being hopeful for the day of halfs being less jank in c# :^) |
|
I think this is one for the working group to debate about actual API intricacies (i.e. what we want to expose) but the concept here is sound. Concur with generic maths, there are lots of places where the generic APIs are useless without floating point but the ability to specify the floating point precision is valuable nonetheless. |
My reasoning to use "Angle" instead of "Radians" is because Angle is a concept, and "Radians" is a specific unit of measurement which yes, it happens to be hardware supported in some architectures. It would be like using "Metres" instead of "Scalar"... The same reasoning as to why TimeSpan is not called "Ticks" even if ticks is the internal representation. So, although the internal representation is in Radians, I didn't want to favour too much radians over degrees, because degrees are more "human friendly" Also, I think it's nicer: But it's also true that the implicit conversion would be to Radians, because it's what most math libraries expect, so to avoid ambiguities, I am not sure what would be nicer: Math.Cos( Angle.InDegrees(90) ); // my current implementation
or
Math.Cos( Angle.InDegrees(90).Radians ); // avoiding ambiguity
or
Math.Cos( Radians.InDegrees(90) ); |
I would prefer that this would be
Maybe Some other stuff that would also be nice to have:
|
There's also the question of what do we store the value as - if we convert there is a possible loss of precision when round-tripping (e.g. if we store the angle as degrees, |
just for reference, this is the structure I am using at work: https://gist.github.com/vpenades/3d0b52e1bfc046191e685473ad006ab7 Some of the methods were a bit rushed because I added them when I needed them, so don't take it as rock solid knowledge. @Perksey I think the internal representation should be one that can be used straight away with MathF.Cos(value); so the internal representation would be unconstrained radians. I think clamping an angle to the 0-360 range is equivalent to normalizing a quaternion, so it's something that should be explicitly set by the developer, not something automatic. In my code is called "Normalize360", because an angle could also be normalized in the range of -180 to 180 , I don't know which might be better. To some degree (no put intended), Angle is similar to TimeSpan, in which you have "Seconds" and "TotalSeconds", the equivalent with Angle would be: Angle.TotalRadians (unbounded) (internal representation) |
|
TimeSpan internal representation is Ticks, equivalent to Radians, But it also has Hour Minutes and Seconds, so you can have 14:25:10 ... but also TotalMinutes, TotalSeconds and so on. If we take the analogy to Angle, we could split the value in two parts: Direction (like a compass) and Number of Turns
Don't know exactly how to call this one: it essentially applies the modulus of PI to the value... effectively leaving the "compass direction" and resetting the number of turns to zero. This is usually useful when you have an object state representing the direction to which the object is facing, and you update the direction continuously. You don't want to keep the number of turns to preserve precission, |
FYI here's the discussion recording, the notes probably don't go into all of the details of our discussion: https://youtu.be/gjneerMeRVU?t=3720 |
I've watched the video, and looks like there's a preference to keep the Angle always normalized. But there's some key use cases where it's important to define angles beyond the -pi to pi range. Which is Angular Velocities Consider simulating a spinning fan. You need it's current angle state and it's angular velocity, which happens to be quite high: Angle FanAngle;
Angle FanAngularV = Angle.FromDegrees(11880); // angular velocity
void UpdateFan(TimeSpan step)
{
FanAngle += FanAngularV * step.TotalSeconds;
FanAngle = FanAngle.Normalize();
} There's lots of things that spin at very high angular velocities: fans, propellers, saws, gears, engine parts, wheels, black holes, etc Just the wheel of a car racing at top speed is already spinning several times per second... |
Couldn't these be static methods instead? Like in Godot there's |
This is not just for conversion, its for explicit typing of a concept, with more than just 'degrees to radians' and 'radians to degrees' |
I think the sentiment during the meeting was the majority of cases are better off with consistent float accuracy, and the cases it being used for rotational velocity are lower, (and can just be handled by an overload of the |
I see. But would this impact memory usage? for example there's 50k objects each have it's own Transform. But now there will be Transform and Angle |
Well as seen in the original proposal these are not objects, they are structures |
So structures are actually smaller than classes in size? |
Google can best explain the nuances, but yes, generally a struct will always be smaller |
This has been assigned to @HurricanKai to make a formal proposal for WG discussion |
@HurricanKai WG meeting feels like it might be getting close, any progress on this? :) |
Summary of feature
In geometry, I work with angles quite often, so I ended having an Angle structure which has proven a lot more useful than I imagined, because it handles stuff like:
Once you think about it, angles have their own mathematical domain that has always been very underrated.
Taken from my code, it would be something like this:
Comments
The biggest advantage I had by using such a structure is that it greatly reduces the extremely common case of using radians in place of degrees or the other way around, in other words: it makes the concept of an angle value strong typed.
And it makes the code a lot more pleasant:
Does this have a proposal?
Check the documentation/proposals folder. If it doesn't have one, you may need to create one if you're making massive breaking changes.
The text was updated successfully, but these errors were encountered: