/*
* $Id$
* This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc
*
* Copyright (c) 2000-2012 Stephane GALLAND.
* Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports,
* Universite de Technologie de Belfort-Montbeliard.
* Copyright (c) 2013-2016 The original authors, and other authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arakhne.afc.math.physics;
import java.util.concurrent.TimeUnit;
import org.eclipse.xtext.xbase.lib.Inline;
import org.eclipse.xtext.xbase.lib.Pure;
import org.arakhne.afc.math.MathConstants;
/**
* This class permits to manipulate measure units.
*
* <p>A foot is a unit of length, in a number of different systems,
* including English units, Imperial units, and United States
* customary units. Its size can vary from system to system,
* but in each is around a quarter to a third of a meter.
* The most commonly used foot today is the international foot.
* There are 3 feet in a yard and 12 inches in a foot.
*
* <p>An inch is the name of a unit of length in a number of
* different systems, including English units, Imperial units,
* and United States customary units. Its size can vary from system
* to system. There are 36 inches in a yard and 12 inches in a foot.
*
* <p>The fathoms is the name of a unit of length,
* in a number of different systems, including
* English units, Imperial units, and United
* States customary units. The name derives from
* the Old English word fæthm (plural) meaning
* 'outstretched arms' which was the original
* definition of the unit's measure.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @since 13.0
*/
@SuppressWarnings({"checkstyle:magicnumber", "checkstyle:methodcount", "checkstyle:parametername"})
public final class MeasureUnitUtil {
private MeasureUnitUtil() {
//
}
/** Translate m/s to km/h.
*
* @param ms the value
* @return {@code ms} * 3.6
*/
@Pure
@Inline(value = "($1) * 3.6")
public static double ms2kmh(double ms) {
//return ((ms/1000.0)*3600.0);
return ms * 3.6;
}
/** Translate km/h to m/s.
*
* @param kmh the value
* @return {@code kmh} / 3.6
*/
@Pure
@Inline(value = "($1) / 3.6")
public static double kmh2ms(double kmh) {
//return ((kmh/3600.0)*1000.0);
return kmh / 3.6;
}
/** Translate meters to kilometers.
*
* @param m the value
* @return {@code m} / 1000
*/
@Pure
@Inline(value = "($1) / 1000.")
public static double m2km(double m) {
return m / 1000.;
}
/** Translate kilometers to meters.
*
* @param km the value
* @return {@code km} * 1000
*/
@Pure
@Inline(value = "($1) * 1000.")
public static double km2m(double km) {
return km * 1000.;
}
/** Translate from "long" pixel coordinate to "system" pixel coordinate.
*
* @param pixelCoord is the pixel coordinate to translate.
* @return the given value rounded to the nearest integer.
*/
@Pure
@Inline(value = "(int) Math.round($1)", imported = {Math.class})
public static int pix2pix(double pixelCoord) {
return (int) Math.round(pixelCoord);
}
/** Translate from "long" pixel coordinate to "system" pixel coordinate.
*
* @param pixelCoord is the pixel coordinate to translate.
* @return the given value rounded to the nearest integer.
*/
@Pure
@Inline(value = "(int) ($1)")
public static int pix2pix(long pixelCoord) {
return (int) pixelCoord;
}
/** Translate from "long" pixel coordinate to "system" pixel coordinate.
*
* @param pixel_coord is the pixel coordinate to translate.
* @return the given value rounded to the nearest integer.
*/
@Pure
@Inline(value = "Math.round($1)", imported = {Math.class})
public static int pix2pix(float pixel_coord) {
return Math.round(pixel_coord);
}
/** Translate from unit (10^0) to nano (10^-9).
*
* @param unit the value
* @return {@code unit} / 1e-9
*/
@Pure
@Inline(value = "($1) / 1e-9")
public static double unit2nano(double unit) {
return unit / 1e-9;
}
/** Translate from nano (10^-9) to unit (10^0).
*
* @param nano the value
* @return {@code nano} * 1e-9
*/
@Pure
@Inline(value = "($1) * 1e-9")
public static double nano2unit(double nano) {
return nano * 1e-9;
}
/** Translate from unit (10^0) to micro (10^-6).
*
* @param unit the value
* @return {@code unit} / 1e-6
*/
@Pure
@Inline(value = "($1) / 1e-6")
public static double unit2micro(double unit) {
return unit / 1e-6;
}
/** Translate from micro (10^-6) to unit (10^0).
*
* @param micro the value
* @return {@code micro} * 1e-6
*/
@Pure
@Inline(value = "($1) * 1e-6")
public static double micro2unit(double micro) {
return micro * 1e-6;
}
/** Translate from unit (10^0) to milli (10^-3).
*
* @param unit the value
* @return {@code unit} / 1e-3
*/
@Pure
@Inline(value = "($1) / 1e-3")
public static double unit2milli(double unit) {
return unit / 1e-3;
}
/** Translate from milli (10^-3) to unit (10^0).
*
* @param milli the value
* @return {@code milli} * 1e-3
*/
@Pure
@Inline(value = "($1) * 1e-3")
public static double milli2unit(double milli) {
return milli * 1e-3;
}
/** Translate from milli (10^-3) to micro (10^-6).
*
* @param milli the value
* @return {@code milli} / 1e-3
*/
@Pure
@Inline(value = "($1) / 1e-3")
public static double milli2micro(double milli) {
return milli / 1e-3;
}
/** Translate from milli (10^-3) to nano (10^-9).
*
* @param milli the value
* @return {@code milli} / 1e-6
*/
@Pure
@Inline(value = "($1) / 1e-6")
public static double milli2nano(double milli) {
return milli / 1e-6;
}
/** Translate from micro (10^-6) to nano (10^-9).
*
* @param milli the value
* @return {@code milli} / 1e-3
*/
@Pure
@Inline(value = "($1) / 1e-3")
public static double micro2nano(double milli) {
return milli / 1e-3;
}
/** Translate from micro (10^-6) to milli (10^-3).
*
* @param micro the value
* @return {@code micro} * 1e-3
*/
@Pure
@Inline(value = "($1) * 1e-3")
public static double micro2milli(double micro) {
return micro * 1e-3;
}
/** Translate from nano (10^-9) to micro (10^-6).
*
* @param nano the value
* @return {@code nano} * 1e-3
*/
@Pure
@Inline(value = "($1) * 1e-3")
public static double nano2micro(double nano) {
return nano * 1e-3;
}
/** Translate from nano (10^-9) to milli (10^-3).
*
* @param nano the value
* @return {@code nano} * 1e-6
*/
@Pure
@Inline(value = "($1) * 1e-6")
public static double nano2milli(double nano) {
return nano * 1e-6;
}
/** Translate meters to fathoms.
*
* @param m the value
* @return {@code m} * 0.5468
*/
@Pure
@Inline(value = "($1) * 0.5468")
public static double m2fh(double m) {
return m * 0.5468;
}
/** Translate feets to fathoms.
*
* @param ft the value
* @return {@code ft} * 0.1667
*/
@Pure
@Inline(value = "($1) * 0.1667")
public static double ft2fh(double ft) {
return ft * 0.1667;
}
/** Translate inches to fathoms.
*
* @param in the value
* @return {@code in} / 72
*/
@Pure
@Inline(value = "($1) / 72.")
public static double in2fh(double in) {
return in / 72;
}
/** Translate meters to feets.
*
* @param m the value
* @return {@code m} * 0.3048
*/
@Pure
@Inline(value = "($1) * 0.3048")
public static double m2ft(double m) {
return m * 0.3048;
}
/** Translate inches to feets.
*
* @param in the value
* @return {@code in} / 12
*/
@Pure
@Inline(value = "($1 / 12)")
public static double in2ft(double in) {
return in / 12;
}
/** Translate fathoms to feets.
*
* @param fh the value
* @return {@code fh} / 0.1667
*/
@Pure
@Inline(value = "($1) / 0.1667")
public static double fh2ft(double fh) {
return fh / 0.1667;
}
/** Translate meters to inches.
*
* @param m the value
* @return {@code m} * 0.025
*/
@Pure
@Inline(value = "($1) * 0.025")
public static double m2in(double m) {
return m * 0.025;
}
/** Translate feets to inches.
*
* @param ft the value
* @return {@code ft} * 12
*/
@Pure
@Inline(value = "($1) * 12.")
public static double ft2in(double ft) {
return ft * 12;
}
/** Replies the metrics from inches.
*
* @param i the inch value
* @return a value in centimeters
*/
@Pure
@Inline(value = "($1) / 0.3937")
public static double inchToMetric(double i) {
return i / 0.3937;
}
/** Replies the inches from metrics.
*
* @param m the metric value
* @return a value in inches
*/
@Pure
@Inline(value = "($1) * 0.3937")
public static double metricToInch(double m) {
return m * 0.3937;
}
/** Convert the given value expressed in the given unit to seconds.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @return the result of the convertion.
*/
@Pure
public static double toSeconds(double value, TimeUnit inputUnit) {
switch (inputUnit) {
case DAYS:
return value * 86400.;
case HOURS:
return value * 3600.;
case MINUTES:
return value * 60.;
case SECONDS:
break;
case MILLISECONDS:
return milli2unit(value);
case MICROSECONDS:
return micro2unit(value);
case NANOSECONDS:
return nano2unit(value);
default:
throw new IllegalArgumentException();
}
return value;
}
/** Convert the given value expressed in the given unit to meters.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @return the result of the convertion.
*/
@Pure
@SuppressWarnings("checkstyle:returncount")
public static double toMeters(double value, SpaceUnit inputUnit) {
switch (inputUnit) {
case TERAMETER:
return value * 1e12;
case GIGAMETER:
return value * 1e9;
case MEGAMETER:
return value * 1e6;
case KILOMETER:
return value * 1e3;
case HECTOMETER:
return value * 1e2;
case DECAMETER:
return value * 1e1;
case METER:
break;
case DECIMETER:
return value * 1e-1;
case CENTIMETER:
return value * 1e-2;
case MILLIMETER:
return value * 1e-3;
case MICROMETER:
return value * 1e-6;
case NANOMETER:
return value * 1e-9;
case PICOMETER:
return value * 1e-12;
case FEMTOMETER:
return value * 1e-15;
default:
throw new IllegalArgumentException();
}
return value;
}
/** Convert the given value expressed in meters to the given unit.
*
* @param value is the value to convert
* @param outputUnit is the unit of the replied value.
* @return the result of the convertion.
*/
@Pure
@SuppressWarnings("checkstyle:returncount")
public static double fromMeters(double value, SpaceUnit outputUnit) {
switch (outputUnit) {
case TERAMETER:
return value * 1e-12;
case GIGAMETER:
return value * 1e-9;
case MEGAMETER:
return value * 1e-6;
case KILOMETER:
return value * 1e-3;
case HECTOMETER:
return value * 1e-2;
case DECAMETER:
return value * 1e-1;
case METER:
break;
case DECIMETER:
return value * 1e1;
case CENTIMETER:
return value * 1e2;
case MILLIMETER:
return value * 1e3;
case MICROMETER:
return value * 1e6;
case NANOMETER:
return value * 1e9;
case PICOMETER:
return value * 1e12;
case FEMTOMETER:
return value * 1e15;
default:
throw new IllegalArgumentException();
}
return value;
}
/** Convert the given value expressed in seconds to the given unit.
*
* @param value is the value to convert
* @param outputUnit is the unit of result.
* @return the result of the convertion.
*/
@Pure
public static double fromSeconds(double value, TimeUnit outputUnit) {
switch (outputUnit) {
case DAYS:
return value / 86400.;
case HOURS:
return value / 3600.;
case MINUTES:
return value / 60.;
case SECONDS:
break;
case MILLISECONDS:
return unit2milli(value);
case MICROSECONDS:
return unit2micro(value);
case NANOSECONDS:
return unit2nano(value);
default:
throw new IllegalArgumentException();
}
return value;
}
/** Convert the given value expressed in the given unit to the
* second given unit.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @param outputUnit is the unit for the replied value.
* @return the result of the convertion.
*/
@Pure
@Inline(value = "MeasureUnitUtil.fromSeconds(MeasureUnitUtil.toSeconds(($1), ($2)), ($3))",
imported = {MeasureUnitUtil.class})
public static double convert(long value, TimeUnit inputUnit, TimeUnit outputUnit) {
final double v = toSeconds(value, inputUnit);
return fromSeconds(v, outputUnit);
}
/** Convert the given value expressed in the given unit to the
* second given unit.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @param outputUnit is the unit for the replied value.
* @return the result of the convertion.
*/
@Pure
@Inline(value = "MeasureUnitUtil.fromSeconds(MeasureUnitUtil.toSeconds(($1), ($2)), ($3))",
imported = {MeasureUnitUtil.class})
public static double convert(double value, TimeUnit inputUnit, TimeUnit outputUnit) {
final double v = toSeconds(value, inputUnit);
return fromSeconds(v, outputUnit);
}
/** Convert the given value expressed in the given unit to the
* second given unit.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @param outputUnit is the unit for the replied value.
* @return the result of the convertion.
*/
@Pure
@Inline(value = "MeasureUnitUtil.fromMetersPerSecond(MeasureUnitUtil.toMetersPerSecond(($1), ($2)), ($3))",
imported = {MeasureUnitUtil.class})
public static double convert(double value, SpeedUnit inputUnit, SpeedUnit outputUnit) {
final double v = toMetersPerSecond(value, inputUnit);
return fromMetersPerSecond(v, outputUnit);
}
/** Convert the given value expressed in the given unit to the
* second given unit.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @param outputUnit is the unit for the replied value.
* @return the result of the convertion.
*/
@Pure
@Inline(value = "MeasureUnitUtil.fromRadiansPerSecond(MeasureUnitUtil.toRadiansPerSecond(($1), ($2)), ($3))",
imported = {MeasureUnitUtil.class})
public static double convert(double value, AngularUnit inputUnit, AngularUnit outputUnit) {
final double v = toRadiansPerSecond(value, inputUnit);
return fromRadiansPerSecond(v, outputUnit);
}
/** Convert the given value expressed in the given unit to the
* second given unit.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @param outputUnit is the unit for the replied value.
* @return the result of the convertion.
*/
@Pure
@Inline(value = "MeasureUnitUtil.fromMeters(MeasureUnitUtil.toMeters(($1), ($2)), ($3))",
imported = {MeasureUnitUtil.class})
public static double convert(double value, SpaceUnit inputUnit, SpaceUnit outputUnit) {
final double v = toMeters(value, inputUnit);
return fromMeters(v, outputUnit);
}
/** Convert the given value expressed in the given unit to meters per second.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @return the result of the convertion.
*/
@Pure
public static double toMetersPerSecond(double value, SpeedUnit inputUnit) {
switch (inputUnit) {
case KILOMETERS_PER_HOUR:
return 3.6 * value;
case MILLIMETERS_PER_SECOND:
return value / 1000.;
case METERS_PER_SECOND:
default:
}
return value;
}
/** Convert the given value expressed in the given unit to radians per second.
*
* @param value is the value to convert
* @param inputUnit is the unit of the {@code value}
* @return the result of the convertion.
*/
@Pure
public static double toRadiansPerSecond(double value, AngularUnit inputUnit) {
switch (inputUnit) {
case TURNS_PER_SECOND:
return value * (2. * MathConstants.PI);
case DEGREES_PER_SECOND:
return Math.toRadians(value);
case RADIANS_PER_SECOND:
default:
}
return value;
}
/** Convert the given value expressed in meters per second to the given unit.
*
* @param value is the value to convert
* @param outputUnit is the unit of result.
* @return the result of the convertion.
*/
@Pure
public static double fromMetersPerSecond(double value, SpeedUnit outputUnit) {
switch (outputUnit) {
case KILOMETERS_PER_HOUR:
return value / 3.6;
case MILLIMETERS_PER_SECOND:
return value * 1000.;
case METERS_PER_SECOND:
default:
}
return value;
}
/** Convert the given value expressed in radians per second to the given unit.
*
* @param value is the value to convert
* @param outputUnit is the unit of result.
* @return the result of the convertion.
*/
@Pure
public static double fromRadiansPerSecond(double value, AngularUnit outputUnit) {
switch (outputUnit) {
case TURNS_PER_SECOND:
return value / (2. * MathConstants.PI);
case DEGREES_PER_SECOND:
return Math.toDegrees(value);
case RADIANS_PER_SECOND:
default:
}
return value;
}
/** Compute the smallest unit that permits to have
* a metric value with its integer part positive.
*
* @param amount is the amount expressed in the given unit.
* @param unit is the unit of the given amount.
* @return the smallest unit that permits to obtain the smallest
* positive mathematical integer that corresponds to the integer
* part of the given amount after its convertion to the selected
* unit.
*/
@Pure
public static SpaceUnit getSmallestUnit(double amount, SpaceUnit unit) {
final double meters = toMeters(amount, unit);
double v;
final SpaceUnit[] units = SpaceUnit.values();
SpaceUnit u;
for (int i = units.length - 1; i >= 0; --i) {
u = units[i];
v = Math.floor(fromMeters(meters, u));
if (v > 0.) {
return u;
}
}
return unit;
}
}