GitHub - carlomilanesi/cpp-measures: Header-only C++11 library to handle physical measures (original) (raw)

cpp-measures

Header-only C++11 library to handle physical measures

License: This project is released under the Mozilla Public License 2.0.

Purpose

This library is aimed at those who use C++11 language to write software which uses values provided of unit of measurement, like, for example, lengths measured in meters, inches, or kilometers, durations measured in seconds, hours, or days, angles measured in degrees, radians, or turns, but also derived units, like revolutions per minute.

Specifically, it addresses software for technical drafting (CAD), engineering simulation (CAE), industrial automation planning (CAM), embedded or real-time industrial automation, and also several kinds of vector graphics applications, like computer games.

On the other side, this library does not address:

Such library is useful for:

The main features of this library are shown in the examples.

Examples of use

To define a variable named "a", representing a length of 6 millimeters, and keeping it in a "double" primitive object, it can be written:

"vect" indicates that such value is a mathematical vector, i.e. it may be added to or subtracted from another object of the same type, and it may be multiplied or divided by a number; "1" indicates that such measure in one-dimensional; "mm" is the unit of measurement.

To define a variable named "b" representing a point in 3D space having cartesian coordinates x=7, y=8, z=9, expressed in inches, and stored in three "float" primitive objects, it can be written:

point3<inches,float> b(7, 8, 9);

"point" indicates that such measure is an element of an affine space, and not of a vector space, i.e. it cannot be added to or subtracted from another object of the same type, and it cannot be multiplied or divided by a number.

In mechanics, the physical work performed by a constant force moved by a displacement is by definition the dot product between such force and such displacement. Assuming we are constrained in a plane, we can write:

vect1<joules> work = vect2<newtons>(12, 13) * vect2<metres>(3, 5);

Here, no numeric type is specified, and so the default "double" is used. The "*" operator performs the dot product. The type "vect2" represents a force laying in a plane, measured in Newtons. The type "vect2" represents a displacement in a plane, measured in metres. The resulting value should be a scalar (i.e. a one-dimensional vect), measured in Joules. I wrote "should" as such units of measurement are not part of the library, but are defined by the application programmer according with the needs of the application software.

To convert between thermometric scales, the following statements can be written:

vect1<celsius> t = convert<celsius>(vect1<fahrenheit>(90));
point1<celsius> t = convert<celsius>(point1<fahrenheit>(90));

The first one of such statements converts temperature changes, and therefore it does not takes into account the difference between the scale zeros, but only the ratio between the degrees. The resulting value is a change of 50 Celsius degrees.

Conversely, the second statement converts temperature points, and therefore it takes into account both the ratio between the degrees and the difference between the scale zeros. The resulting value is a temperature of 32.222 Celsius degrees.

Particular attention is devoted to angles. Actually, differing from other magnitudes and units, that must be defined by the application programmer, the Angle magnitude is predefined, and also one of its units is, radians. In addition, beyond arbitrary-valued angles, both of "vect1" and of "point1" kinds, the following two statements may be written:

signed_azimuth<radians> a(2);
unsigned_azimuth<radians> b(3);

Both of them define angular positions modulo one turn, i.e. plane directions, or positions on a circumpherence; but the first statement forces its value to lay between minus half turn and plus half turn, and so it is "signed", while the second statement forces its value to lay between zero and one turn, and so it is "unsigned".

Guarantees for resource-limited applications

This library provides optional overloads of the>> and << operators of C++ stream, for logging or debugging purposes. If such operators are used, the requirements of the application become those of supporting the cin and coutstandard console streams.

As long as its I/O functions are not used, this library does not introduces nor requires:

Limitations

This library has the following limitations by design:

Documentation

The documentation provided is the following: