Overview
Units and measures are common in engineering data, so the rosemath library provides definitions to identify and convert between the most frequently used units. Application-specific code build upon these definitions to process the more extensive data models found in STEP, IFC, CIS/2, and others.
All definitions are in the rose_unit.h header file.
The RoseUnit enum provides a simple value for commonly used units. The RoseMeasureType enum characterizes different types of quantites. The RoseUnitSet class holds a collection of units for each of the different types of quantities.
The rose_unit_convert() function changes a numeric value from one unit to another. You can get the name of a unit with rose_unit_get_name() or the kind of quantity with rose_unit_get_measure_name().
RoseUnit (enum)
enum RoseUnit { roseunit_unknown=0, roseunit_as_is, // no conversion /* length */ roseunit_mm, // millimeters roseunit_cm, // centimeters roseunit_m, // meters roseunit_in, // inches roseunit_ft, // feet roseunit_micrometre, // millionth of a meter roseunit_nanometre, // billionth of a meter roseunit_milliinch, // thousandth of an inch roseunit_microinch, // millionth of an inch /* area */ roseunit_mm2, // square millimeters roseunit_cm2, // square centimeters roseunit_m2, // square meters roseunit_in2, // square inches roseunit_ft2, // square feet /* volume */ roseunit_mm3, // cubic millimeters roseunit_cm3, // cubic centimeters roseunit_m3, // cubic meters roseunit_in3, // cubic inches roseunit_ft3, // cubic feet /* angle */ roseunit_deg, // degrees roseunit_rad, // radians /* solid angle */ roseunit_steradian, // steradian /* time */ roseunit_sec, // seconds roseunit_min, // minutes roseunit_hour, // hours /* feedrates - linear speed */ roseunit_mmps, // millimeters per second roseunit_mmpm, // millimeters per minute roseunit_cmps, // centimeters per second roseunit_mps, // meters per second roseunit_ips, // inches per second roseunit_ipm, // inches per minute roseunit_fps, // feet per second roseunit_fpm, // feet per minute /* feed per revolution */ roseunit_mmprev, // millimeters per revolution roseunit_iprev, // inches per revolution /* feed per tooth */ roseunit_mmptooth, // millimeters per tooth roseunit_iptooth, // inches per tooth /* spinspeeds - rotational speed */ roseunit_hertz, // revolutions per second (hz) roseunit_rpm, // revolutions per minute // change to use a revolution context dependent unit /* pressure */ roseunit_pa, // pascals roseunit_kpa, // kilopascal roseunit_mpa, // megapascal roseunit_psi, // pounds per square inch /* force */ roseunit_newton, // newtons roseunit_lbf, // pound force /* power */ roseunit_watt, // watts roseunit_kw, // kilowatts roseunit_hp, // horsepower /* torque - full names to avoid confusion with nanometers */ roseunit_newton_meter, // newton meters roseunit_pound_foot, // pound foot /* temperature */ roseunit_celsius, // degree Celsius roseunit_kelvin, // degree Kelvin roseunit_fahrenheit, // degree Fahrenheit roseunit_rankine, // degree Rankine /* symbolic units */ roseunit_count, roseunit_parameter, roseunit_ratio, roseunit_revolution, roseunit_tooth, /* COMING NEXT RELEASE */ /* mass units */ roseunit_mg, roseunit_gram, roseunit_kg, roseunit_tonne, // megagram, aka metric ton roseunit_ounce, roseunit_pound, roseunit_ton, // short ton 907.18474 kg roseunit_long_ton, // long ton 1016.0469088 kg // other si base units roseunit_ampere, roseunit_becquerel, roseunit_candela, roseunit_coulomb, roseunit_farad, roseunit_gray, roseunit_henry, roseunit_joule, roseunit_lumen, roseunit_lux, roseunit_mole, roseunit_ohm, roseunit_siemens, roseunit_sievert, roseunit_tesla, roseunit_volt, roseunit_weber, // Extra units roseunit_kN, // force, kilonewtons /* mass density */ roseunit_kg_per_m3, roseunit_g_per_cm3, roseunit_oz_per_in3, roseunit_lb_per_in3, roseunit_lb_per_ft3, /* area density */ roseunit_kg_per_m2, roseunit_g_per_cm2, roseunit_oz_per_in2, roseunit_lb_per_in2, // not roseunit_psi, which is force / area roseunit_lb_per_ft2, /* maximum number of elements defined, used for creating arrays, * bounds checking when cast to an int and such */ ROSEUNIT_MAX_VALUE };
The RoseUnit enumeration identifies common units. Application-specific code can process the general definitions from STEP, IFC, CIS/2 or others into these enums for easier processing.
RoseMeasureType (enum)
enum RoseMeasureType { rosemeasure_unknown = 0, rosemeasure_accel, // linear acceleration rosemeasure_angle, rosemeasure_ang_accel, // angular acceleration rosemeasure_ang_speed, // angular frequency rosemeasure_area, rosemeasure_count, rosemeasure_force, rosemeasure_length, rosemeasure_mass, rosemeasure_parameter, rosemeasure_power, rosemeasure_pressure, rosemeasure_ratio, rosemeasure_revolution, rosemeasure_solid_angle, rosemeasure_speed, // linear velocity rosemeasure_temp, rosemeasure_time, rosemeasure_tooth, rosemeasure_torque, rosemeasure_volume, /* COMING NEXT RELEASE */ rosemeasure_amtofsubstance, rosemeasure_capacitance, rosemeasure_charge, rosemeasure_conductance, rosemeasure_current, rosemeasure_resistance, rosemeasure_voltage, rosemeasure_energy, rosemeasure_frequency, // temporal frequency rosemeasure_illuminance, rosemeasure_inductance, rosemeasure_lumflux, rosemeasure_lumintensity, rosemeasure_magfluxdensity, rosemeasure_magflux, rosemeasure_absorbdose, rosemeasure_equivdose, rosemeasure_radioactivity, rosemeasure_massdensity, // mass per volume rosemeasure_areadensity, // mass per area /* maximum number of elements defined, used for creating * arrays, bounds checking when cast to an int and such */ ROSEMEASURE_MAX_VALUE };
The RoseMeasureType enumeration identifies kinds of quantities which can simplify reasoning with units and measures.
rose_unit_convert()
double rose_unit_convert( double val, RoseUnit as_is, RoseUnit to_be );
The rose_unit_convert() function converts a value between two units and returns the result. The conversion may be a constant factor returned by rose_unit_get_conversion() or more complex conversions like °Fahrenheit to °Celsius. The function returns ROSE_NULL_REAL if no conversion exists or the input is null.
double val; // 10in, returns 254mm val = rose_unit_convert (10, roseunit_in, roseunit_mm); // 5cm, returns 50mm val = rose_unit_convert (5, roseunit_cm, roseunit_mm); // 63.5cm, returns 25in val = rose_unit_convert (63.5, roseunit_cm, roseunit_in); // freezing point, returns 32F val = rose_unit_convert (0, roseunit_celsius, roseunit_fahrenheit); // boiling point, return 212F val = rose_unit_convert (100, roseunit_celsius, roseunit_fahrenheit);
rose_unit_find()
RoseUnit rose_unit_find (const char * lookup_by_name);
The rose_unit_find() function returns the RoseUnit enum value identifying a unit. The function takes a string name and finds the unit matching a known long or short name, regardless of case.
RoseUnit u; // the following all return roseunit_in u = rose_unit_find(inch); u = rose_unit_find(in); u = rose_unit_find(INCH); u = rose_unit_find(IN); // the following returns roseunit_unknown u = rose_unit_find(foobar);
rose_unit_find_rational()
RoseUnit rose_unit_find_rational( RoseUnit num, RoseUnit denom );
The rose_unit_find_rational() function returns the unit corresponding to the "num" unit over the "denom" parameter, if it exists. If the result is not an element of RoseUnit, the function returns roseunit_unknown.
The rose_unit_get_numerator() and rose_unit_get_denominator() functions are used to find values in the opposite direction.
RoseUnit u; // inches per second, returns roseunit_ips u = rose_unit_find_rational(roseunit_in, roseunit_sec); // revolutions per second, returns roseunit_hertz u = rose_unit_find_rational(roseunit_revolution, roseunit_sec); // nonsense, returns roseunit_unknown u = rose_unit_find_rational(roseunit_kpa, roseunit_rpm);
rose_unit_find_related_by_factor()
RoseUnit rose_unit_find_related_by_factor( RoseUnit base, double factor );
The rose_unit_find_related_by_factor() function searches the known conversions for a unit that when multiplied by the conversion factor results in the given unit. The function will first try to match the conversion factor to within ROSE_EPSILON. If that fails, it will try to match conversion factors within 1%. This function is used with STEP data to help identify units given as general conversion values. The function returns roseunit_unknown if no match can be found.
This finds (returned unit) * factor = base
RoseUnit u; // will return roseunit_in for inch u = rose_unit_find_related_by_factor(roseunit_mm, 25.4); // will also return inch u = rose_unit_find_related_by_factor(roseunit_cm, 2.54);
rose_unit_get_conversion()
double rose_unit_get_conversion ( RoseUnit as_is, RoseUnit to_be );
The rose_unit_get_conversion() function returns the floating
point conversion factor that relates two units. The function
returns ROSE_NULL_REAL
if no conversion exists between
the units. It returns zero if a conversion may exist but requires
custom action.
The following code fragment shows the behavior of the conversion factor.
RoseUnit asis; RoseUnit tobe; double cf = rose_unit_get_conversion (asis, tobe); if (ROSE_FLOAT_IS_NULL(cf)) printf (no conversion exists\n); else if (cf == 0) printf (CUSTOM\n); else printf (%s == %g * %s\n, rose_unit_get_name(tobe), cf, rose_unit_get_name(asis) );
Calling this code produces the following output
// asis = roseunit_in // tobe = roseunit_mm mm == 25.4 * in // asis = roseunit_m // tobe = roseunit_mm mm == 1000 * m // asis = roseunit_deg // tobe = roseunit_rad radian == 0.0174533 * deg // asis = roseunit_celsius // tobe = roseunit_fahrenheit CUSTOM // asis = roseunit_mm // tobe = roseunit_rad no conversion exists
rose_unit_get_denominator()
RoseUnit rose_unit_get_denominator (RoseUnit u);
The rose_unit_get_denominator() function is the companion of the rose_unit_find_rational() and rose_unit_get_numerator() functions. Together, these functions can be used for simple reasoning on units.
The function returns the denominator of a rational unit. For example, calling this on meters per second (roseunit_mps) will return second (roseunit_sec). If the input is not a rational unit, the function returns roseunit_unknown.
rose_unit_get_fullname()
const char * rose_unit_get_fullname (RoseUnit u);
The rose_unit_get_fullname() function returns a formal name
for the unit, such as millimetere
.
The rose_unit_get_name() function
returns the common abbreviation.
rose_unit_get_measure_name()
const char * rose_unit_get_measure_name (RoseMeasureType vt);
The rose_unit_get_measure_name() function returns a descriptive name for a given value type.
rose_unit_get_measure_type()
RoseMeasureType rose_unit_get_measure_type (RoseUnit u); RoseMeasureType rose_unit_get_measure_type (const char * lookup_by_name);
The rose_unit_get_measure_type() function returns the RoseMeasureType enum value describing the type of quantity for a unit.
The version that takes a string name finds the value type matching a known name, regardless of case. These functions return rosemeasure_unknown if the unit enum is unknown or the measure name is not recognized.
rose_unit_get_name()
const char * rose_unit_get_name (RoseUnit u);
The rose_unit_get_name() function returns a concise name for
the unit, such
as mm
. The rose_unit_get_fullname()
returns a formal name for the unit, such as millimetere
.
rose_unit_get_numerator()
RoseUnit rose_unit_get_numerator (RoseUnit u);
The rose_unit_get_numerator function is the companion of the rose_unit_find_rational() and rose_unit_get_denominator() functions.
The function returns the numerator of a rational unit. For example, calling this on meters per second (roseunit_mps) will return meter (roseunit_m). If the input is not a rational unit, the function returns the original input value.