nholthaus / units

a compile-time, header-only, dimensional analysis and unit conversion library built on c++14 with no dependencies.
http://nholthaus.github.io/units/
MIT License
938 stars 134 forks source link

Cast away dimension #236

Closed deathwishdave closed 3 years ago

deathwishdave commented 4 years ago

Version v2.3.1, on GNU++17

I am doing solar calculations, and one of my functions is adding an hour_t to radian_t, and the result expected is an hour_t.

How do I force a resulting dimension? or how do I remove the radian_t dimension in this calculation so the result is hour_t?

burnpanck commented 4 years ago

You cannot "add a hour to a radian2". You shouldn't "force a resulting dimension", that's the whole point of using physical units. Physically, there is no sensible definition the addition between two quantities with incompatible units. What you need is an angular speed (rotation speed of the earth = 360°/day, orbital speed of the moon around the earth = 360°/month, orbital speed of the earth around the sun = 360°/year), which determines what you actually mean by "adding radians to hours". This package cannot guess which orbit you are asking for. So do the physically correct thing, and add time + angle/angular_speed, which this package will happily do for you.

nholthaus commented 3 years ago

You'll probably be interested in this Physics Stack Exchange QA.

Radians are generally a ratio of units of length in 2-dimensions (e.g. a curved line) to 1-dimensional length. Mathematics generally treats such units as dimensionless, but pedantically speaking, they aren't, and it shows in things like units when you try to apply the general calculus of dimensional analysis to them.

In such cases, I'd usually do the following:

radian_t a;
hour_t t;

hour_t result = t * a.to<double>();

The to function does what you imagine a unit_cast function would... namely return a non-safe, underlying arithmetic type.