forked from mpusz/mp-units
merge branch master
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
.. namespace:: units
|
||||
|
||||
Angular Units
|
||||
=============
|
||||
|
||||
Some background information
|
||||
---------------------------
|
||||
|
||||
As per today's SI, both radian and steradian are dimensionless. This forces the convention to set the angle ``1 radian``
|
||||
equal to the number ``1`` within equations (similar to what natural units system does for ``c`` constant).
|
||||
|
||||
Following `Wikipedia <https://en.wikipedia.org/wiki/Radian#Dimensional_analysis>`_:
|
||||
|
||||
Giacomo Prando says "the current state of affairs leads inevitably to ghostly appearances and disappearances of the radian
|
||||
in the dimensional analysis of physical equations." For example, a mass hanging by a string from a pulley will rise or drop
|
||||
by :math:`y=rθ`` centimeters, where :math:`r` is the radius of the pulley in centimeters and :math:`θ` is the angle
|
||||
the pulley turns in radians. When multiplying :math:`r` by :math:`θ` the unit of radians disappears from the result.
|
||||
Similarly in the formula for the angular velocity of a rolling wheel, :math:`ω=v/r`, radians appear in the units of
|
||||
:math:`ω` but not on the right hand side.
|
||||
Anthony French calls this phenomenon "a perennial problem in the teaching of mechanics". Oberhofer says that the typical
|
||||
advice of ignoring radians during dimensional analysis and adding or removing radians in units according to convention
|
||||
and contextual knowledge is "pedagogically unsatisfying".
|
||||
|
||||
At least a dozen scientists have made proposals to treat the radian as a base unit of measure defining its own dimension of "angle",
|
||||
as early as 1936 and as recently as 2022. This would bring the advantages of a physics-based, consistent, and logically-robust
|
||||
unit system, with unambiguous units for all physical quantities. At the same time the only notable changes for typical
|
||||
end-users would be: improved units for the quantities **torque**, **angular momentum** and **moment of inertia**.
|
||||
|
||||
Paul Quincey in his proposal *"Angles in the SI: a detailed proposal for solving the problem"* [Quincey]_ states:
|
||||
|
||||
The familiar units assigned to some angular quantities are based on equations that have adopted the radian convention,
|
||||
and so are missing `rad`s that would be present if the complete equation is used. The physically-correct units are
|
||||
those with the `rad`s reinstated. Numerical values would not change, and the physical meanings of all quantities would
|
||||
also be unaffected.
|
||||
|
||||
He proposes the following changes:
|
||||
|
||||
- The **radian** would become either a new base unit or a 'complementary' unit
|
||||
- The **steradian** would become a derived unit equal to :math:`1\:rad^2`
|
||||
- The SI units for
|
||||
|
||||
- **Torque** would change from :math:`N\:m` (= J) to :math:`J\:rad^{-1}`
|
||||
- **Angular momentum** would change from :math:`J\:s` to :math:`J\:s\:rad^{-1}` (i.e. :math:`J/(rad/s)`)
|
||||
- **Moment of inertia** would change from :math:`kg\:m^2` to :math:`kg\:m^2\:rad^{-2}` (i.e. :math:`J/(rad/s)^2`)
|
||||
|
||||
- The option to omit the radian from the SI units for **angle**, **angular velocity**, **angular frequency**,
|
||||
**angular acceleration**, and **angular wavenumber** would be removed, the only correct SI units being
|
||||
:math:`rad`, :math:`rad/s`, :math:`rad/s`, :math:`rad/s^2` and :math:`rad/m` respectively.
|
||||
|
||||
Paul Quincey summarizes that with the above in action:
|
||||
|
||||
However, the physical clarity this would build into the SI should be recognised very quickly. The units would tell us that
|
||||
:math:`torque \times angle = energy`, and :math:`angular\:momentum \times angle = action`, for example, in the same way that they do for
|
||||
:math:`force \times distance = energy`, :math:`linear\:momentum \times distance = action`, and
|
||||
:math:`radiant\:intensity \times solid\:angle = radiant\:flux`.
|
||||
Dimensional analysis could be used to its full extent. Software involving angular quantities would be rationalised.
|
||||
Arguments about the correct units for frequency and angular frequency, and the meaning of the unit Hz, could be left behind.
|
||||
The explanation of these changes would be considerably easier and more rewarding than explaining how a kilogram-sized mass
|
||||
can be measured in terms of the Planck constant.
|
||||
|
||||
|
||||
Angular quantities in the library
|
||||
---------------------------------
|
||||
|
||||
The mp-units library strives to define physically-correct quantities and their units to provide maximum help
|
||||
to its users. As treating angle as a dimensional quantity can lead to many "trivial" mistakes in dimensional
|
||||
analysis and calculation, it was decided to follow the above approach and treat angle as a base quantity
|
||||
with a base unit of radian and solid angle as its derived quantity.
|
||||
|
||||
As those the above (at least for now) not a part of :term:`SI`, the plain angle and solid
|
||||
angle definitions can be found in the *units/generic* subdirectory. However, in the sake of correctness,
|
||||
they are consistently used in the dimensional recipes of all angle-based :term:`SI` quantities like
|
||||
torque or angular velocity::
|
||||
|
||||
#include <units/generic/angle.h>
|
||||
#include <units/isq/si/torque.h>
|
||||
#include <units/math.h>
|
||||
#include <units/quantity_io.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace units;
|
||||
using namespace units::isq;
|
||||
using namespace units::aliases;
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
const Length auto lever = cm<>(20);
|
||||
const Force auto force = N<>(500);
|
||||
const Angle auto angle = deg<>(90);
|
||||
const Torque auto torque = lever * force * sin(angle) / cotes_angle<>;
|
||||
|
||||
std::cout << "Applying a perpendicular force of " << force << " to a "
|
||||
<< lever << " long lever results in "
|
||||
<< quantity_cast<si::newton_metre_per_radian>(torque) << " of torque.\n";
|
||||
}
|
||||
|
||||
The above program prints:
|
||||
|
||||
.. code-block::
|
||||
|
||||
Applying a perpendicular force of 500 N to a 20 cm long lever results in 100 N⋅m/rad of torque.
|
||||
|
||||
.. note::
|
||||
|
||||
`cotes_angle` is a constant which represents an angle with the value of exactly ``1 radian``.
|
||||
You can find more information about this constant in [Quincey]_.
|
||||
|
||||
|
||||
Radians and degrees support
|
||||
---------------------------
|
||||
|
||||
Thanks to :ref:`framework/magnitudes:Magnitudes` usage the library provides efficient strong types for all
|
||||
angular types. This means that with the built-in support for magnitudes of :math:`\pi` we can provide
|
||||
accurate conversions between radians and degrees. The library also provides common trigonometric functions
|
||||
for angular quantities::
|
||||
|
||||
using namespace units::aliases::isq::si;
|
||||
|
||||
auto velocity = km_per_h<>(110);
|
||||
auto rate_of_climb = m_per_s<>(-0.63657);
|
||||
auto glide_ratio = velocity / -rate_of_climb;
|
||||
auto glide_angle = asin(1 / glide_ratio);
|
||||
|
||||
std::cout << std::format("Glide ratio: {:%.1Q %q}\n", quantity_cast<units::one>(glide_ratio));
|
||||
std::cout << "Glide angle:\n";
|
||||
std::cout << std::format(" - {:%.4Q %q}\n", glide_angle);
|
||||
std::cout << std::format(" - {:%.2Q %q}\n", quantity_cast<units::degree>(glide_angle));
|
||||
std::cout << std::format(" - {:%.2Q %q}\n", quantity_cast<units::gradian>(glide_angle));
|
||||
|
||||
The above program prints:
|
||||
|
||||
.. code-block::
|
||||
|
||||
Glide ratio: 48.0
|
||||
Glide angle:
|
||||
- 0.0208 rad
|
||||
- 1.19 °
|
||||
- 1.33 ᵍ
|
||||
|
||||
.. note::
|
||||
|
||||
The above ``velocity`` and ``rate_of_climb`` in the production code should be modelled as
|
||||
:ref:`framework/quantity_kinds:Quantity Kinds`.
|
||||
A better but longer code can be found in the :ref:`examples/basics/glide_computer:glide_computer` example.
|
||||
@@ -50,6 +50,20 @@ The quantities of derived dimensions are called
|
||||
quantities. This means that they are created by multiplying or dividing
|
||||
quantities of other dimensions.
|
||||
|
||||
The [SIBrochure]_ states:
|
||||
|
||||
All other quantities, with the exception of counts, are derived quantities, which may be
|
||||
written in terms of base quantities according to the equations of physics. The dimensions of
|
||||
the derived quantities are written as products of powers of the dimensions of the base
|
||||
quantities using the equations that relate the derived quantities to the base quantities.
|
||||
In general the dimension of any quantity :math:`Q` is written in the form of a dimensional product,
|
||||
|
||||
:math:`dim Q = T^\alpha L^\beta M^\gamma I^\delta \Theta^\varepsilon N^\zeta J^\eta`
|
||||
|
||||
where the exponents :math:`\alpha`, :math:`\beta`, :math:`\gamma`, :math:`\delta`, :math:`\varepsilon`,
|
||||
:math:`\zeta` and :math:`\eta`, which are generally small integers, which can be positive,
|
||||
negative, or zero, are called the dimensional exponents.
|
||||
|
||||
Looking at the previous code snippets the area, speed, or frequency are
|
||||
the examples of such quantities. Each derived quantity can be represented
|
||||
as a unique list of exponents of base quantities. For example:
|
||||
|
||||
@@ -313,7 +313,7 @@ Quantity References vs Unit-specific Aliases
|
||||
- Unit-specific Aliases
|
||||
|
||||
As aliases are defined in terms of types rather variables no major shadowing issues were found
|
||||
so far. In case of identifiers abiguity it was always possible to disambiguate with more
|
||||
so far. In case of identifiers ambiguity it was always possible to disambiguate with more
|
||||
namespaces prefixed in front of the alias.
|
||||
|
||||
2. Adjustable verbosity
|
||||
@@ -385,7 +385,7 @@ Quantity References vs Unit-specific Aliases
|
||||
- Quantity References
|
||||
|
||||
The syntax for references uses ``*`` operator which has some predefined precedence. This operator
|
||||
always takes a magnitude or a reference as ``lhs`` and a reference as ``rhs``. All other comibnations
|
||||
always takes a magnitude or a reference as ``lhs`` and a reference as ``rhs``. All other combinations
|
||||
are not allowed. It means that in order to satisfy the operators precedence sometimes quite a lot
|
||||
of parenthesis have to be sprinkled in the code in order for the code to compile::
|
||||
|
||||
@@ -399,7 +399,7 @@ Quantity References vs Unit-specific Aliases
|
||||
|
||||
- Quantity References
|
||||
|
||||
References have only to be defined for named units. Also for the user's conveniance references are
|
||||
References have only to be defined for named units. Also for the user's convenience references are
|
||||
predefined for units raised to a specific power (e.g. ``m2``, ``km3``, etc). All other derived units
|
||||
can be constructed using the provided ones already even if they do not correspond to any predefined
|
||||
dimension::
|
||||
|
||||
@@ -49,4 +49,4 @@ Unlike `quantity`, the library provides:
|
||||
- no dimension-specific concepts, such as ``LengthPoint``
|
||||
(there's the dimension-agnostic `QuantityPoint`),
|
||||
- a more limited set of operations on quantity points
|
||||
(see the :ref:`framework/dimensions:Quantity Points` chapter)
|
||||
(see the :ref:`framework/arithmetics:Quantity Points` chapter)
|
||||
|
||||
+47
-28
@@ -203,27 +203,27 @@ complete list of all the :term:`SI` prefixes supported by the library::
|
||||
|
||||
namespace si {
|
||||
|
||||
struct yocto : prefix<yocto, "y", pow<-24>(mag<10>())> {};
|
||||
struct zepto : prefix<zepto, "z", pow<-21>(mag<10>())> {};
|
||||
struct atto : prefix<atto, "a", pow<-18>(mag<10>())> {};
|
||||
struct femto : prefix<femto, "f", pow<-15>(mag<10>())> {};
|
||||
struct pico : prefix<pico, "p", pow<-12>(mag<10>())> {};
|
||||
struct nano : prefix<nano, "n", pow<-9>(mag<10>())> {};
|
||||
struct yocto : prefix<yocto, "y", mag_power<10, -24>()> {};
|
||||
struct zepto : prefix<zepto, "z", mag_power<10, -21>()> {};
|
||||
struct atto : prefix<atto, "a", mag_power<10, -18>()> {};
|
||||
struct femto : prefix<femto, "f", mag_power<10, -15>()> {};
|
||||
struct pico : prefix<pico, "p", mag_power<10, -12>()> {};
|
||||
struct nano : prefix<nano, "n", mag_power<10, -9>()> {};
|
||||
struct micro : prefix<micro, basic_symbol_text{"\u00b5", "u"},
|
||||
pow<-6>(mag<10>())> {};
|
||||
struct milli : prefix<milli, "m", pow<-3>(mag<10>())> {};
|
||||
struct centi : prefix<centi, "c", pow<-2>(mag<10>())> {};
|
||||
struct deci : prefix<deci, "d", pow<-1>(mag<10>())> {};
|
||||
struct deca : prefix<deca, "da", pow<1>(mag<10>())> {};
|
||||
struct hecto : prefix<hecto, "h", pow<2>(mag<10>())> {};
|
||||
struct kilo : prefix<kilo, "k", pow<3>(mag<10>())> {};
|
||||
struct mega : prefix<mega, "M", pow<6>(mag<10>())> {};
|
||||
struct giga : prefix<giga, "G", pow<9>(mag<10>())> {};
|
||||
struct tera : prefix<tera, "T", pow<12>(mag<10>())> {};
|
||||
struct peta : prefix<peta, "P", pow<15>(mag<10>())> {};
|
||||
struct exa : prefix<exa, "E", pow<18>(mag<10>())> {};
|
||||
struct zetta : prefix<zetta, "Z", pow<21>(mag<10>())> {};
|
||||
struct yotta : prefix<yotta, "Y", pow<24>(mag<10>())> {};
|
||||
mag_power<10, -6>()> {};
|
||||
struct milli : prefix<milli, "m", mag_power<10, -3>()> {};
|
||||
struct centi : prefix<centi, "c", mag_power<10, -2>()> {};
|
||||
struct deci : prefix<deci, "d", mag_power<10, -1>()> {};
|
||||
struct deca : prefix<deca, "da", mag_power<10, 1>()> {};
|
||||
struct hecto : prefix<hecto, "h", mag_power<10, 2>()> {};
|
||||
struct kilo : prefix<kilo, "k", mag_power<10, 3>()> {};
|
||||
struct mega : prefix<mega, "M", mag_power<10, 6>()> {};
|
||||
struct giga : prefix<giga, "G", mag_power<10, 9>()> {};
|
||||
struct tera : prefix<tera, "T", mag_power<10, 12>()> {};
|
||||
struct peta : prefix<peta, "P", mag_power<10, 15>()> {};
|
||||
struct exa : prefix<exa, "E", mag_power<10, 18>()> {};
|
||||
struct zetta : prefix<zetta, "Z", mag_power<10, 21>()> {};
|
||||
struct yotta : prefix<yotta, "Y", mag_power<10, 24>()> {};
|
||||
|
||||
}
|
||||
|
||||
@@ -232,14 +232,14 @@ domain::
|
||||
|
||||
namespace iec80000 {
|
||||
|
||||
struct kibi : prefix<kibi, "Ki", pow<10>(mag<2>())> {};
|
||||
struct mebi : prefix<mebi, "Mi", pow<20>(mag<2>())> {};
|
||||
struct gibi : prefix<gibi, "Gi", pow<30>(mag<2>())> {};
|
||||
struct tebi : prefix<tebi, "Ti", pow<40>(mag<2>())> {};
|
||||
struct pebi : prefix<pebi, "Pi", pow<50>(mag<2>())> {};
|
||||
struct exbi : prefix<exbi, "Ei", pow<60>(mag<2>())> {};
|
||||
struct zebi : prefix<zebi, "Zi", pow<70>(mag<2>())> {};
|
||||
struct yobi : prefix<yobi, "Yi", pow<80>(mag<2>())> {};
|
||||
struct kibi : prefix<kibi, "Ki", mag_power<2, 10>()> {};
|
||||
struct mebi : prefix<mebi, "Mi", mag_power<2, 20>()> {};
|
||||
struct gibi : prefix<gibi, "Gi", mag_power<2, 30>()> {};
|
||||
struct tebi : prefix<tebi, "Ti", mag_power<2, 40>()> {};
|
||||
struct pebi : prefix<pebi, "Pi", mag_power<2, 50>()> {};
|
||||
struct exbi : prefix<exbi, "Ei", mag_power<2, 60>()> {};
|
||||
struct zebi : prefix<zebi, "Zi", mag_power<2, 70>()> {};
|
||||
struct yobi : prefix<yobi, "Yi", mag_power<2, 80>()> {};
|
||||
|
||||
}
|
||||
|
||||
@@ -260,6 +260,14 @@ example we can define ``si::kilometre`` as::
|
||||
as ``km²`` would be invalid).
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
[SIBrochure]_ states:
|
||||
|
||||
However, when prefixes are used with SI units, the resulting units are no
|
||||
longer coherent, because the prefix introduces a numerical factor other than one.
|
||||
|
||||
|
||||
Derived Units
|
||||
-------------
|
||||
|
||||
@@ -268,10 +276,21 @@ Derived Units
|
||||
names (i.e. ``N`` (newton)) or can be composed from the names of units of quantities
|
||||
used to define thier derived quantity (i.e. ``km/h``).
|
||||
|
||||
The [SIBrochure]_ states:
|
||||
|
||||
Derived units are defined as products of powers of the base units. When the numerical
|
||||
factor of this product is one, the derived units are called coherent derived units. The base
|
||||
and coherent derived units of the SI form a coherent set, designated the set of coherent SI
|
||||
units. The word “coherent” here means that equations between the numerical values of
|
||||
quantities take exactly the same form as the equations between the quantities themselves.
|
||||
|
||||
Derived Named Units
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The [SIBrochure]_ also says:
|
||||
|
||||
Some of the coherent derived units in the SI are given special names.
|
||||
|
||||
Derived named units have a unique symbol (i.e. ``N`` (newton) or ``Pa``
|
||||
(pascal)) and they are defined in the same way as base units (which
|
||||
always have to be a named unit)::
|
||||
|
||||
Reference in New Issue
Block a user