Hacker News new | ask | show | jobs
by jacobolus 1360 days ago
If you are making something like a game engine using computer hardware from the past 30 years, you should avoid angle measures to the extent possible.

It is much computationally cheaper and more robust (and easier to reason about) to use vector algebra throughout. Then you have no transcendental functions, just basic arithmetic and the occasional square root. You need the dot product and the wedge product (or combined, the geometric product), and derived concepts like vector projection and rejection.

If you need to store a rotation, you can use a unit-magnitude complex number z = x + iy, where x = cos θ, y = sin θ, without ever needing to calculate the quantity θ directly. If you need to compress it down to one parameter for whatever reason, use the stereographic projection s = y / (1 + x) = (1 – x) / y. Reverse that by x = (1 – s²) / (1 + s²), y = 2s / (1 + s²). [If starting from angle measure for whatever reason s = tan ½θ, sometimes called the "half-tangent".]

The angle measure is the logarithm of the rotation, θi = log z. In some contexts logarithms can be very convenient, but it’s not the simplest or most fundamental representation.

With units of "radians" angle measure is the logarithm of base exp(i) [related to the natural logarithm], and with units of "turns" it is the logarithm of base 1 (sort of).

1 comments

I mean that’s all well and good until you have an object in your game and you’re like “I’d like this object to be leaning at 45 degrees, oops I mean 0.70710678118 + i*0.70710678118
At a high level you should be expressing something like one of "turn this by the angle between vector (1,0) and vector (1, 1)"; "point this in the direction of vector (1, 1)"; or "turn this by the square root of the rotation i" (i = a quarter turn).

If you use angle measures (of whatever units), when you say "rotate by an eighth of a turn" you are instead going to end up with something internally like: multiply some vector by the matrix

[cos ¼π, –sin ¼π ; sin ¼π, cos ¼π]

which is ultimately the same arithmetic, except you had to compute more intermediate transcendental functions to get there.

If you just have to do this a few times, angle measures (in degrees or whatever) are a convenient human interface because most people are very familiar with it from high school. You can have your code ingest the occasional angle measure and turn it into a vector-relevant internal representation immediately.

P.S. If you write 1/√2 in your code compilers are smart enough to turn that into a floating point number at compile time. :-)

In most game engines, constructing the rotation matrix is trivial. Something like Quaternion.Euler(0, 45, 0). The ultimate position / rotation of any given object in a game is usually a compound transform computed via matrix multiplication anyway, e.g. a model view projection matrix. I'm not sure it's the best way, but that's just how most game engines work.
If your game engine is using quaternions as a canonical internal representation for rotations, it is already following my advice from above.

(Game engine developers are smart people and have lots of practical experience with the benefits of avoiding angle measures, as do developers of computer vision, computer graphics, robotics, physical simulations, aerospace flight control, GIS, etc. etc. tools.)

Yea, I see. I originally interpreted your comment as being about game developers, but you were actually talking about game engine developers. In which case, we agree :)