1 package net.sf.openrocket.util;
3 public class MathUtil {
4 public static final double EPSILON = 0.00000001; // 10mm^3 in m^3
7 * The square of x (x^2). On Sun's JRE using this method is as fast as typing x*x.
11 public static double pow2(double x) {
16 * The cube of x (x^3).
20 public static double pow3(double x) {
24 public static double pow4(double x) {
29 * Clamps the value x to the range min - max.
30 * @param x Original value.
31 * @param min Minimum value to return.
32 * @param max Maximum value to return.
33 * @return The clamped value.
35 public static double clamp(double x, double min, double max) {
43 public static float clamp(float x, float min, float max) {
51 public static int clamp(int x, int min, int max) {
61 * Maps a value from one value range to another.
63 * @param value the value to map.
64 * @param fromMin the minimum of the starting range.
65 * @param fromMax the maximum of the starting range.
66 * @param toMin the minimum of the destination range.
67 * @param toMax the maximum of the destination range.
68 * @return the mapped value.
69 * @throws IllegalArgumentException if fromMin == fromMax, but toMin != toMax.
71 public static double map(double value, double fromMin, double fromMax,
72 double toMin, double toMax) {
73 if (equals(toMin, toMax))
75 if (equals(fromMin, fromMax)) {
76 throw new IllegalArgumentException("from range is singular an to range is not.");
78 return (value - fromMin)/(fromMax-fromMin) * (toMax - toMin) + toMin;
82 * Compute the minimum of two values. This is performed by direct comparison.
83 * However, if one of the values is NaN and the other is not, the non-NaN value is
86 public static double min(double x, double y) {
89 return (x < y) ? x : y;
93 * Compute the maximum of two values. This is performed by direct comparison.
94 * However, if one of the values is NaN and the other is not, the non-NaN value is
97 public static double max(double x, double y) {
100 return (x < y) ? y : x;
104 * Compute the minimum of three values. This is performed by direct comparison.
105 * However, if one of the values is NaN and the other is not, the non-NaN value is
108 public static double min(double x, double y, double z) {
109 if (x < y || Double.isNaN(y)) {
117 * Compute the maximum of three values. This is performed by direct comparison.
118 * However, if one of the values is NaN and the other is not, the non-NaN value is
121 public static double max(double x, double y, double z) {
122 if (x > y || Double.isNaN(y)) {
130 * Calculates the hypotenuse <code>sqrt(x^2+y^2)</code>. This method is SIGNIFICANTLY
131 * faster than <code>Math.hypot(x,y)</code>.
133 public static double hypot(double x, double y) {
134 return Math.sqrt(x*x + y*y);
138 * Reduce the angle x to the range 0 - 2*PI.
139 * @param x Original angle.
140 * @return The equivalent angle in the range 0 ... 2*PI.
142 public static double reduce360(double x) {
143 double d = Math.floor(x / (2*Math.PI));
144 return x - d*2*Math.PI;
148 * Reduce the angle x to the range -PI - PI.
150 * Either -PI and PI might be returned, depending on the rounding function.
152 * @param x Original angle.
153 * @return The equivalent angle in the range -PI ... PI.
155 public static double reduce180(double x) {
156 double d = Math.rint(x / (2*Math.PI));
157 return x - d*2*Math.PI;
161 public static boolean equals(double a, double b) {
162 double absb = Math.abs(b);
164 if (absb < EPSILON/2) {
166 return Math.abs(a) < EPSILON/2;
168 return Math.abs(a-b) < EPSILON*absb;
171 public static double sign(double x) {
172 return (x<0) ? -1.0 : 1.0;
175 /* Math.abs() is about 3x as fast as this:
177 public static double abs(double x) {
178 return (x<0) ? -x : x;
183 public static void main(String[] arg) {
184 double nan = Double.NaN;
185 System.out.println("min(5,6) = " + min(5, 6));
186 System.out.println("min(5,nan) = " + min(5, nan));
187 System.out.println("min(nan,6) = " + min(nan, 6));
188 System.out.println("min(nan,nan) = " + min(nan, nan));
189 System.out.println();
190 System.out.println("max(5,6) = " + max(5, 6));
191 System.out.println("max(5,nan) = " + max(5, nan));
192 System.out.println("max(nan,6) = " + max(nan, 6));
193 System.out.println("max(nan,nan) = " + max(nan, nan));
194 System.out.println();
195 System.out.println("min(5,6,7) = " + min(5, 6, 7));
196 System.out.println("min(5,6,nan) = " + min(5, 6, nan));
197 System.out.println("min(5,nan,7) = " + min(5, nan, 7));
198 System.out.println("min(5,nan,nan) = " + min(5, nan, nan));
199 System.out.println("min(nan,6,7) = " + min(nan, 6, 7));
200 System.out.println("min(nan,6,nan) = " + min(nan, 6, nan));
201 System.out.println("min(nan,nan,7) = " + min(nan, nan, 7));
202 System.out.println("min(nan,nan,nan) = " + min(nan, nan, nan));
203 System.out.println();
204 System.out.println("max(5,6,7) = " + max(5, 6, 7));
205 System.out.println("max(5,6,nan) = " + max(5, 6, nan));
206 System.out.println("max(5,nan,7) = " + max(5, nan, 7));
207 System.out.println("max(5,nan,nan) = " + max(5, nan, nan));
208 System.out.println("max(nan,6,7) = " + max(nan, 6, 7));
209 System.out.println("max(nan,6,nan) = " + max(nan, 6, nan));
210 System.out.println("max(nan,nan,7) = " + max(nan, nan, 7));
211 System.out.println("max(nan,nan,nan) = " + max(nan, nan, nan));
212 System.out.println();