Eduardo VasquezSep 26, 2022Liked by Casey MuratoriJust keep in mind, though, that all those formulas of derivatives and primitives of trig functions in standard calculus books assume that arguments are expressed in radians. Say, the derivative of sin x w.r.t. x is cos x --- that is only true if x is in radians. Otherwise, you would get an extra factor, due to the chain rule. So, if the mathematical expression you are working with happens to come, somehow, from derivatives or primitives, chances are that you will miss those extra factors, by simply deleting every ocurrence of pi or tau.Expand full comment
 This is a good point. I have not had that kind of code in anything radian-free yet, so I haven't thought through what you want to do. Since the radian alternative is to divide out the pi on each call, it may be that there is still some way to be more efficient than that if you look at what tends to happen in that kind of code.Expand full comment
 Yes, that is what I suggest. But what I took Eduardo to be saying is just "please be careful, anyone who reads this, that you cannot do derivatives _of code_ that you read and expect it to work the same as if _the code_ had been in radians". Maybe they weren't saying that, but that's what I took them to be saying, and I think that's a good cautionary statement, just in case someone wasn't aware of the fact that sine/cosine in radians are "optimized" in the math sense because they don't produce a chain rule term for the angle, but any other parameterization of angle would.Expand full comment
 Miguel ReisSep 27, 2022·edited Sep 27, 2022Right so what I would add to that is to keep in mind that if in the code you see :sin ( x )where x is in turns. You have to be careful to know if you can derive "the usual way" but maybe (probably I would say) you can!Because the sin function can still be the same mathematical function. And so it will still have the same derivatives regardless of how the parameter is represented. So you can get the best of both worlds. :)I assume this is the case of sincospif for instance.Expand full comment
 Sep 27, 2022·edited Sep 27, 2022AuthorNo, I think the point of this comment thread is just to point out you can't make that assumption. If you have sin_radians(x), then its derivative is cos_radians(x) _specifically because_ radians is the unit where that is true. For any other angle measure (turns or otherwise), a constant will pop out of the derivative.So if you have sin_turns(x), the derivative is not cos_turns(x), it's c*cos_turns(x). And specifically c is going to contain pi, so you're going to have pi come back again. Does that make sense?A more math-oriented person can step in here and explain better than I can, but suffice to say the whole reason people like using radians as angles in math is _because_ they have simplifying properties when doing derivations. They're the "natural unit" for doing algebraic math with angles. And this derivative-doesn't-require-a-constant aspect is just one of the places where that is true.Expand full comment
 Gaurav GautamGaurav’s Substack Jan 31, 2023·edited Jan 31, 2023I think this warning assumes that whatever functions I'm using are so complicated that the angle variable `x` is appearing both inside the trigonometric function and outside it. I rarely ever see those kinds of functions. What I'm saying is, can't I just make sure I do the derivative with respect to the turn variable? Then I shouldn't have to worry about this kind of chain rule complication. Also, if its a function of two variables where the angle variable is independent of all other variables I should still be safe right? Is this warning just unduly scary? Although, I guess in the scientific applications where representing the values of PI to a high degree of accuracy is important, these kinds of functions are just commonplace. Even the first PDE we learn (the wave equation) is like that.And I would shamelessly put the wave equation in functions I find complex.Expand full comment
 Ah! Yes totally agree.I was making the mistake of only considering trivial cases so I was not understanding what you were saying by "derivatives in the code".Makes total sense now.CheersExpand full comment
 If you need accurate derivatives (as you may do in engineering and physics), then this certainly matters a lot. But in graphics, remember that constant factors in derivatives may not matter as much as you think.Think of local/Frenet frame vectors (tangent/bitangent/normal), for example. They typically get normalised before you use them, so any extra constant factor on derivatives makes no practical difference.Expand full comment
 wouldn't you just treat it like it's a normal sine/cosine? afaik it's not that it's stretching the sine over a different range, and more that it's stretching the number line to differently measure the same sine.Expand full comment
 Yea, I suspect his is why most libraries have trig functions done in radians. Back in the day, most applications, especially those were runtimes were a serious concern, were scientific and had a lot of derivatives running around, so avoiding the extra constants made sense.Expand full comment
 pico-8 does it this way: https://pico-8.fandom.com/wiki/CosExpand full comment
 Awesome! Another reason to like PICO-8 :)Expand full comment
 Felice EnellenOct 25, 2022·edited Oct 25, 2022Yup, after playing with PICO-8 for five or six years, I really wish I'd had turn-based sin/cos during my real gamedev career. So many things would have been simpler and, I suspect, more efficient under the hood because converting back to quadrants or octants for the computation or table lookup would be trivial. Not to mention there would be no error propagation at the lowest bits because there'd be no multiply or divide by an almost-irrational number. Radians have their place and I'd still want versions for that, but 99% of the time I'd want turns. I suspect the radians version would simply divide by n*pi and pass through to the turn-based version, too.Expand full comment
 If we don't care about legacy then we don't need to call them cos and sin either, right? Maybe call these new functions turnX and turnY?Expand full comment
 Yes. In fact, I woild strongly recommend NOT calling them sin and cos because that will confuse people who expect them to take radians! Picking new names is definitely the right thing to do.Expand full comment
 Martin2Sep 28, 2022·edited Sep 28, 2022Is there any good C/C++ (preferably single header) math library out there that does this? Or do I have to roll my own?(Took a look at avx_mathfun.h for something to start with maybe, but want non-SIMD as well.)Expand full comment
 Ijon TichySep 27, 2022·edited Sep 27, 2022Have you ever heard of Rational Trigonometry? It doesn't use angles or turns, but instead uses spread. I've always wondered how a game engine would look like if it used those primitives.https://www.youtube.com/watch?v=0gWWDUtmf-wExpand full comment
 I watched some of these videos and hey were definitely interesting. My first thought, however, is that it might be difficult to apply the rational geometry approach to, for example, replacing sine and cosine as I am discussing in this article.In the rational geometry framework, it sounds like they parameterize circles as a function of the y intercept, which would not be useful for generating rotations and such, because the output would move at a nonlinear speed around the circle relative to the input parameter.That said, that is just my first thought having watched the videos. Probably it would take someone who really spent a lot of time with rational geometry to say for sure if there is a win to be had there.Thanks for the pointer to the videos though, either way!Expand full comment
 I haven't, no. I will take a look.Expand full comment
 In the AVX exapmle, I don't understand why sin(x) is equals to 4 / PI * x? If x equals to TAU then wouldn't the function return 8?Expand full comment
 Sep 26, 2022·edited Sep 26, 2022AuthorIt's not. That is merely the first line of the implementation. You can click on the associated hyperlink to see the rest of it if you're curious.Expand full comment
 I totally thought this article was going to be something about inductorsNice article! GLSL/HLSL should provide a turn version of trig funcsExpand full comment
 Just mentioning that we ALREADY do that for exp() and log(), having multiple variants (base-e, base-10 and base-2) in the same lib, makes me wonder why we still don't have ""base-1"" and ""base-tau"" trig alongside the regular ""base-pi"" trig in so many libs.Expand full comment
 This reminds me of the utopian 'gradians' button (technically DRG) I see on calculators and always wish we could switch to.Expand full comment
 If I understand the suggestion correctly, this wasn't overlooked, it was suggested here for instance:http://thomascool.eu/Papers/Math/TrigRerigged.pdf "Abstract: Didactic issues in trigonometry concern the opaque names of sine and cosine and the cluttering of questions with p or 360 whereas a simple 1 suffices. (Linked from here: https://en.wikipedia.org/wiki/Turn_(angle) )Astronomer Fred Hoyle proposed a decimal system with "milliturns". :-)However, computing essentially re-parametrized basic functions (X(t), Y(t)) = (cos 2pi t, sin 2pi t) instead of (cos t, sin t) that was suggested there, and seems to be the suggestion here too, might be natural "conceptually" (that's the point of tau and the manifesto, to use fractions of the whole circle rather than half as reference), but computationally they are not friendly.A great (definitive) recent book on mathematical function computation is:https://link.springer.com/content/pdf/bfm:978-3-319-64110-2/1.pdf"Nelson H.F. Beebe The Mathematical-Function Computation Handbook"The beauty of the existing functions (and radian measure) is that they are arc-length or "unit speed" parametrizations of the circle, so as someone else pointed out, all of the series coefficients are 1, 0, -1, 0, and many other computational conveniences and mathematical relationships would be lost.The circle constant 6.28... was never proposed for computational considerations, but for mathematical conceptual ones, to make the parametrization portions of 1 rather than of 2. So that a quarter turn replaces "pi over 2" for what every child gets is a quarter of an hour. Of the videos, Phil Moriarty's Numberphile segment.https://www.youtube.com/watch?v=83ofi_L6eAois probably the best at explaining the point. He has a great fun book on quantum mechanics too: https://www.goodreads.com/en/book/show/34196224 Expand full comment
 You consider turns where a full circle is [0,1] or half turns, where a full circle is [0, 2].How about full turns where a full turn is [0,360] and half turns are [0,180]?Expand full comment
 That is doable, but normalized values (i.e., 0.0-1.0) are so common that you would end up multiplying by 360 most of the time. And then you'd just have to divide by 360 in the trig function.Expand full comment
 For speed: use a (limited term) Taylor series.MUCH faster.Expand full comment
 What are you talking about? How does this pertain to the content of this article in any way whatsoever?Expand full comment
 You're talking about speed increases for trig functions. Yet you still use trig functions instead of Taylor/Maclaurin series or using the Chebyshev polynomial.Screw radian substitution for 'turns': use a better/faster algo which can match your required accuracy.Maybe you should have at the very least googled and/or read wikipedia about Taylor series approximation wrt trig functions before you wrote that.Expand full comment
 I'm really not sure how to reply to this. We'll try some questions:1) Did you look at the actual "trig function" I referenced? It has a hotlink there, below the code snippet, that says "from this commonly referenced AVX2 implementation of sin". Did you read that code? Does it look familiar? What does that code look like it is doing to you?2) Have you ever implemented your own sine function (using any method - Taylor, Chebyshev, Pade, etc.)? What is the first step that you did in that implementation?3) When you say I still "use trig functions instead of ... polynomial", I'm very curious: how did you think these magical "trig functions" I'm using compute sine, exactly, without one of those polynomials you mentioned?4) You don't by any chance post comments on Hacker News regularly, do you?Expand full comment
 Andrew BromageSep 28, 2022·edited Sep 28, 2022Just to underline Casey's point #2 here, I have implemented sine and cosine. The first step is range reduction. Look up Handmade Hero episode 440 if you want an explanation of what the code linked below is and how to design it, but the important point for now is that k1+k2+k3 is a higher-precision approximation to 2pi than will fit in a 32-bit float.I took that range reduction code (as originally written in my own style rather than HMH style) and rewrote it to use half turns instead of radians. Here, the number you would need to "approximate" is not 2pi, but 2, which is exactly representable in a single float.You be the judge as to which is better/faster.https://gist.github.com/Deguerre/8d589c8a7cf3bf103126e255b333dde6Expand full comment
 Of course !!, all the code is faster, my math lib using this.https://github.com/phreda4/r3/blob/main/r3/lib/math.r3Expand full comment
 Yes, turns are better than radians in many cases. But in a lot of those cases degrees are even better. 360 is a superior highly composite number (https://en.wikipedia.org/wiki/Superior_highly_composite_number) and we can get exact representations for many more common and useful angles than with turns. Want to split a circle into 6 equal parts? 1/6 doesn't have exact representation in float. 360/6 is not only exact in float32 but also an integer.Expand full comment
 No. If you used degrees, you'd replace the multiply by tau with a multiply by 360, _and then you would immediately have to divide by 360_ in the math routine, thus losing bits of precision for absolutely no reason whatsoever. The only place degrees make sense is when storing things if you really need to be exact for 3rd's or 6th's, and that's something you would only see in CAD or something similar. You would not use degrees in the general case unless you really knew that behavior was important.Expand full comment
 Yes, I was thinking more about CAD applications. For general-purpose gamedev or rigid body dynamics angles represented in turns will be a more direct way.Expand full comment
 Thanks, man. I learned a few things here. Expand full comment
 ty caseyExpand full comment