## digitalmars.D - support for various angular units in std.math

• Colin Wallace (16/16) Feb 27 2011 I've been doing a lot of opengl work in D. Opengl deals primarily
• Simen kjaeraas (10/26) Feb 27 2011 I think a better solution would be a proper units struct:
• Walter Bright (4/14) Feb 27 2011 I appreciate the suggestion, but suspect that adding a parallel set of t...
• Andrei Alexandrescu (10/24) Feb 28 2011 Agreed. What would add value is a units library that refuses calls to
• bearophile (5/11) Feb 28 2011 Have you seen Don's answer?
• KB (8/8) Feb 28 2011 For a very tidy and typesafe implementation of units I would recommend c...
• Peter Alexander (7/23) Feb 28 2011 When you start doing OpenGL properly, degrees don't show up at all. In
• Trass3r (1/4) Feb 28 2011 I think you even have to do that in OpenGL 4 (maybe even 3).
• Don (7/13) Feb 28 2011 Actually, it isn't!
• Colin Wallace (2/9) Feb 28 2011 That's a very marginal error (1e-19). For graphics, I never need that mu...
• Don (9/20) Mar 01 2011 Yes, but someone doing high school trigonometry with degrees will be
Colin Wallace <wallacoloo gmail.com> writes:
```I've been doing a lot of opengl work in D. Opengl deals primarily
(maybe even completely?) with degrees.

When using trigonometric functions, they all deal with radians. So
I've been having to do lots of converting. Converting is very
straightforward, but I still think it would be nice if there were some
built in functions for dealing with other units than radians. I think
a system that looked like what is used for the Duration struct in
core.time would make things more readable. The code for taking the
sine of a number measured in degrees could look like:
sin!"degrees"(45)
rather than
sin(45*PI/180)

It doesn't make a huge difference to me, but neither does the dur!()
function, yet somebody decided it would be helpful and it made its way
into the standard library. So I figured I would at least share this
idea to see what other people thought of it.
```
Feb 27 2011
"Simen kjaeraas" <simen.kjaras gmail.com> writes:
```Colin Wallace <wallacoloo gmail.com> wrote:

I've been doing a lot of opengl work in D. Opengl deals primarily
(maybe even completely?) with degrees.

When using trigonometric functions, they all deal with radians. So
I've been having to do lots of converting. Converting is very
straightforward, but I still think it would be nice if there were some
built in functions for dealing with other units than radians. I think
a system that looked like what is used for the Duration struct in
core.time would make things more readable. The code for taking the
sine of a number measured in degrees could look like:
sin!"degrees"(45)
rather than
sin(45*PI/180)

It doesn't make a huge difference to me, but neither does the dur!()
function, yet somebody decided it would be helpful and it made its way
into the standard library. So I figured I would at least share this
idea to see what other people thought of it.

I think a better solution would be a proper units struct:

unit!"degrees" a;

sin(a); // Automagically behaves correctly

return bar < PI;
}

foo(a); // Compile-time error: degrees not equal to radians.

--
Simen
```
Feb 27 2011
Walter Bright <newshound2 digitalmars.com> writes:
```Colin Wallace wrote:
When using trigonometric functions, they all deal with radians. So
I've been having to do lots of converting. Converting is very
straightforward, but I still think it would be nice if there were some
built in functions for dealing with other units than radians. I think
a system that looked like what is used for the Duration struct in
core.time would make things more readable. The code for taking the
sine of a number measured in degrees could look like:
sin!"degrees"(45)
rather than
sin(45*PI/180)

I appreciate the suggestion, but suspect that adding a parallel set of trig
functions that do nothing more than multiply the arg by a constant is more
cognitive load for the user than benefit.
```
Feb 27 2011
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
```On 2/28/11 12:49 AM, Walter Bright wrote:
Colin Wallace wrote:
When using trigonometric functions, they all deal with radians. So
I've been having to do lots of converting. Converting is very
straightforward, but I still think it would be nice if there were some
built in functions for dealing with other units than radians. I think
a system that looked like what is used for the Duration struct in
core.time would make things more readable. The code for taking the
sine of a number measured in degrees could look like:
sin!"degrees"(45)
rather than
sin(45*PI/180)

I appreciate the suggestion, but suspect that adding a parallel set of
trig functions that do nothing more than multiply the arg by a constant
is more cognitive load for the user than benefit.

Agreed. What would add value is a units library that refuses calls to
e.g. trig functions unless the user specifically inserts a conversion.

sin!"degrees"(x);

you'd use:

sin(to!"degrees"(x));

That way the conversion remains explicit but is hoisted out of the
multitude of math functions.

Andrei
```
Feb 28 2011
bearophile <bearophileHUGS lycos.com> writes:
```Andrei:

you'd use:

sin(to!"degrees"(x));

That way the conversion remains explicit but is hoisted out of the
multitude of math functions.

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=130757

Bye,
bearophile
```
Feb 28 2011
KB <nospam spam.com> writes:
```For a very tidy and typesafe implementation of units I would recommend checking
out the units feature in F#.

http://blogs.msdn.com/b/andrewkennedy/archive/2008/08/29/units-of-measure-in-f-part-one-introducing-units.aspx

Probably not the best link, but the compiler will flag if units are not
consistent
in computations.

Also accept they adopt a 'tagging' system to declare units, but conversely it is
very extensable to any set of defined units.

K
```
Feb 28 2011
Peter Alexander <peter.alexander.au gmail.com> writes:
```On 28/02/11 1:17 AM, Colin Wallace wrote:
I've been doing a lot of opengl work in D. Opengl deals primarily
(maybe even completely?) with degrees.

When using trigonometric functions, they all deal with radians. So
I've been having to do lots of converting. Converting is very
straightforward, but I still think it would be nice if there were some
built in functions for dealing with other units than radians. I think
a system that looked like what is used for the Duration struct in
core.time would make things more readable. The code for taking the
sine of a number measured in degrees could look like:
sin!"degrees"(45)
rather than
sin(45*PI/180)

It doesn't make a huge difference to me, but neither does the dur!()
function, yet somebody decided it would be helpful and it made its way
into the standard library. So I figured I would at least share this
idea to see what other people thought of it.

When you start doing OpenGL properly, degrees don't show up at all. In
fact, I believe all degrees functions are deprecated in the latest
version (could be wrong on this).

Really, you should be doing all the matrix calculations and rotations
yourself. If anything should come out of this, it would be a nice, small
linear algebra library.
```
Feb 28 2011
Trass3r <un known.com> writes:
``` Really, you should be doing all the matrix calculations and rotations
yourself. If anything should come out of this, it would be a nice, small
linear algebra library.

I think you even have to do that in OpenGL 4 (maybe even 3).
```
Feb 28 2011
Peter Alexander <peter.alexander.au gmail.com> writes:
```On 28/02/11 10:12 AM, Trass3r wrote:
Really, you should be doing all the matrix calculations and rotations
yourself. If anything should come out of this, it would be a nice,
small linear algebra library.

I think you even have to do that in OpenGL 4 (maybe even 3).

Yep, I'm pretty sure you're right.
```
Feb 28 2011
Don <nospam nospam.com> writes:
```Colin Wallace wrote:
I've been doing a lot of opengl work in D. Opengl deals primarily
(maybe even completely?) with degrees.

When using trigonometric functions, they all deal with radians. So
I've been having to do lots of converting. Converting is very
straightforward,

Actually, it isn't!
assert(sin(360 * PI / 180 ) == 0.0); // fails!
There are supposed to be sinPi(), cosPi(), tanPi() functions, but they
are not yet implemented (they are quite difficult to get right).

You should use:
sinPi(360/180); to get sine in degrees.
```
Feb 28 2011
Colin Wallace <wallacoloo gmail.com> writes:
```Don Wrote:

Colin Wallace wrote:
When using trigonometric functions, they all deal with radians. So
I've been having to do lots of converting. Converting is very
straightforward,

Actually, it isn't!
assert(sin(360 * PI / 180 ) == 0.0); // fails!

That's a very marginal error (1e-19). For graphics, I never need that much
precision. Besides, it has nothing to do with the conversion in this case.
sin(2*PI) results in the same value, causing the assertion to fail.
```
Feb 28 2011
Don <nospam nospam.com> writes:
```Colin Wallace wrote:
Don Wrote:

Colin Wallace wrote:
When using trigonometric functions, they all deal with radians. So
I've been having to do lots of converting. Converting is very
straightforward,

Actually, it isn't!
assert(sin(360 * PI / 180 ) == 0.0); // fails!

That's a very marginal error (1e-19). For graphics, I never need that much
precision.

Yes, but someone doing high school trigonometry with degrees will be
confused when it fails.

Besides, it has nothing to do with the conversion in this case. sin(2*PI)
results in the same value, causing the assertion to fail.

No, it's the conversion. It's because the mathematical number pi is not
precisely representable in floating point. But 360 is precisely
representable, and sin(360 degrees) is also precisely representable.
assert(sinPi(360/180) == 0) will pass.
So multiplying by PI is *not* the correct way to calculate trignometric
functions in degrees.  2*PI is not 360 degrees.
```
Mar 01 2011