Trax3 3.1.0
trax track library
Loading...
Searching...
No Matches
Dimensionated Values

Introduction

Calculations in physics not only deal with stark naked numbers (for tranquility of mind we call them 'values'), but they are generally also connected with two other aspects: dimension and unit. The dimension is the quality that is dealt with, be it a length in space, a time span or an inertial mass or any combination of these. The units on the other hand specify the quantity we are measuring, telling us that 1000 are actually 1000_kg, not 1000_t. If you do physics calculation it is wise to check the dimensions of your result and then reason about its magnitude. For the trax library the dim library automates both.

Basics

To define a length of 2 meters, with dim we would write (the code can be found in /Test/dim/TestDimDocu.cpp):

Length length = 2_m;

Note that we can use the literal operator '_m' to denote a length in meters. We also can use other operators like '_cm' for centimeters or '_km' for kilometers:

Length width = 300_cm;

We are not confined to the metric system, we can also use imperial units:

Length height = 6_ft + 3_in;
BOOST_CHECK( height < length );

Note the check that uses the operator '<' between two Length values. With stark naked numbers we would have to take care of the units ourselves, but with dim this is done automatically and safely. You'll never need to care about what unit a value has, ever again. Also note our first arithmetic operation with dimensionated values: the addition of two Length values, even with different units.

Multiplication also works:

Area area = width * length; // area has dimension Length^2
Volume volume = area * height; // volume has dimension Length^3
std::cout << "Volume is " << volume << std::endl; // prints "Volume is 11.43m3"

The dim library deals with three base dimensions: Length, Mass and Time. From these three base dimensions several other physical dimensions can be constructed:

Mass mass = 7.874_t;
BOOST_CHECK( mass == 7874_kg );
Density DensityOfIron = mass / 1_m3; // density has dimension Mass / Volume
BOOST_CHECK( DensityOfIron == 7.874_gIcm3 );

Note that division in units we symbolize by a capital 'I' in the unit literal.

Length distance = 100_m;
Time dt = 9.58_s // Usain Bolt's 100m world record
Velocity vUsain = distance / dt; // velocity has dimension Length / Time
std::cout << "Usain's velocity was " << vUsain << std::endl; // prints "Usain's average velocity was 37.58km/h"

If we wanted the velocity in m/s we would write:

std::cout << "Usain's velocity was " << _mIs << vUsain << std::endl; // prints "Usain's average velocity was 10.44m/s"

If g is the acceleration due to gravity, we can calculate the time to fall from s = 1/2 * g * t * t; -> t = sqrt(2*s/g):

Acceleration g = 9.81_mIs2; // acceleration due to gravity.
Time tJump = sqrt(2 * distance / g);
std::cout << "Time to fall " << _m << distance << ": " << _ms << tJump << std::endl; // prints "Time to fall 100m: 4515ms"
Velocity v = g * tJump;
std::cout << "Velocity when hitting the ground: " << v << std::endl; // prints "Velocity when hitting the ground: 44.29m/s"

You might have noticed that all of a sudden we get the velocity always in m/s. This is because we permanently specified this unit for the streaming target std::cout. To get km/h again we need:

std::cout << _kmIh << "Velocity when hitting the ground: " << v << std::endl; // prints "Velocity when hitting the ground: 159.46km/h"

Compiler Errors

The dim library is designed to prevent you from making mistakes with dimensions and units. If you try to add two values with different dimensions, e.g. a Length and a Time, the compiler will complain. The same happens if you try to assign a value with wrong dimension to a variable.

One might think that the dim library is providing conversions of units and maybe a certain clarity on method parameter definitions; but that is not its primary goal. The main purpose of the dim library is to provide a type-safe way to work with physical quantities and their units, preventing common mistakes and ensuring correct calculations. It is actually the main purpose of the dim library to produce compiler errors: if a complicated formula compiles without errors, be assured it is mathematically correct with respect to dimensions and units.

Conversions

If you have a stark naked number 'lengthInCentimeters' and happen to know it to be centimeters, assign it like this:

float lengthInCentimeters = 250.0f;
Length length = _cm(lengthInCentimeters);
std::cout << "Length is " << _m << length << std::endl; // prints "Length is 2.5m"

If you want to get a value in meters from a dim::Length length, do this:

float lengthInMeters = _m(length);
std::cout << "Length in meters: " << lengthInMeters << std::endl; // prints "Length in meters: 2.5"

The other units of course work accordingly.

Dimension One and Angles

A Dimensionated Value with no dimension is still a Dimensionated Value (One ) and is to be distinguished conceptionally from a stark naked number like float, int or double. Angles are of dimension one as well. Both convert seamlessly to each other and to stark naked numbers, but are still different types:

AngularVelocity w = 1_radIs; // 1 radian per second
Time dt = 2_s;
One sina = sin( w * dt ); // sin expects a dimension One or Angle value

Limits

The limits of numerical calculations. E.g. for EEP, the smallest value in length that would make a difference to the user, trax::epsilon__length, would be something about 1_cm. From this the trax::plausible_maximum_length can be estimated to be about 10_km for 32bit trax::Real values. At that distance from the origin, the calculations would start to produce inaccurate results with respect to the 1_cm difference. It is not accidential, that the biggest layouts ever build in EEP are about 20_km in diameter. For optimal results, the trax::meters_per_unit should not be 0.01 nor 1 but rather something like 15.

Output Streams

This section documents the output stream operators for dimensionated values.

Input Streams

This section documents the input stream operators for dimensionated values.

XML Support

The dim library provides support for reading and writing dimensionated values in XML format, using the Boost Property Tree library.