package jo.vecmath.logic; /* * Created on Dec 12, 2003 * * To change the template for this generated file go to * Window>Preferences>Java>Code Generation>Code and Comments */ /** * @author jjaquinta * * To change the template for this generated type comment go to * Window>Preferences>Java>Code Generation>Code and Comments */ public class MathUtils { public static final float DEG_TO_RAD = (float) (Math.PI / 180); public static final float RAD_TO_DEG = (float) (180 / Math.PI); public static final float Euler90 = 90 * DEG_TO_RAD; public static final float Euler180 = 180 * DEG_TO_RAD; public static double EPSILON = 1.0E-14; public static final float PI = (float) Math.PI; public static boolean epsilonEquals(float f1, float f2) { return Math.abs(f1 - f2) < EPSILON; } public static boolean isZero(float f) { return epsilonEquals(f, 0); } public static float atan2(float y, float x) { return (float) Math.atan2(y, x); } public static float cos(float a) { return (float) Math.cos(a); } public static float sin(float a) { return (float) Math.sin(a); } public static float sqrt(float v) { return (float) Math.sqrt(v); } public static double interpolate(double v, double srcLow, double srcHigh, double targLow, double targHigh) { if (v == srcLow) { return targLow; } if (v == srcHigh) { return targHigh; } double pc = (v - srcLow) / (srcHigh - srcLow); return (targHigh - targLow) * pc + targLow; } public static float interpolate(float v, float srcLow, float srcHigh, float targLow, float targHigh) { if (v == srcLow) { return targLow; } if (v == srcHigh) { return targHigh; } float pc = (v - srcLow) / (srcHigh - srcLow); return (targHigh - targLow) * pc + targLow; } public static double interpolate(double v, double[] src, double[] target) { if (v < src[0]) { return target[0]; } if (v > src[src.length - 1]) { return target[target.length - 1]; } for (int i = 0; i < src.length - 1; i++) { if ((v >= src[i]) && (v <= src[i + 1])) { return interpolate(v, src[i], src[i + 1], target[i], target[i + 1]); } } return target[0]; } public static double interpolate(double idx, double[] vals) { int low = (int) Math.floor(idx); int high = (int) Math.ceil(idx); if (low == high) { if (low < 0) { double delta = vals[1] - vals[0]; return vals[0] + low * delta; } else if (low >= vals.length) { double delta = vals[vals.length - 1] - vals[vals.length - 2]; return vals[vals.length - 1] + (low - vals.length + 1) * delta; } else { return vals[low]; } } double lowVal; double highVal; if (low < 0) { double delta = vals[1] - vals[0]; lowVal = vals[0] + low * delta; } else if (low >= vals.length) { double delta = vals[vals.length - 1] - vals[vals.length - 2]; lowVal = vals[vals.length - 1] + (low - vals.length + 1) * delta; } else { lowVal = vals[low]; } if (high < 0) { double delta = vals[1] - vals[0]; highVal = vals[0] + high * delta; } else if (high >= vals.length) { double delta = vals[vals.length - 1] - vals[vals.length - 2]; highVal = vals[vals.length - 1] + (high - vals.length + 1) * delta; } else { highVal = vals[high]; } return interpolate(idx, low, high, lowVal, highVal); } public static double interpolateSin(double v, double sLow, double sHigh, double tLow, double tHigh) { double pc = (v - sLow) / (sHigh - sLow); pc = Math.sin(pc * Math.PI / 2); double targ = (tHigh - tLow) * pc + tLow; return targ; } public static int interpolateSin(int v, int sLow, int sHigh, int tLow, int tHigh) { return (int) interpolateSin((double) v, (double) sLow, (double) sHigh, (double) tLow, (double) tHigh); } public static double interpolateCos(double v, double sLow, double sHigh, double tLow, double tHigh) { double pc = (v - sLow) / (sHigh - sLow); pc = 1.0 - Math.cos(pc * Math.PI / 2); double targ = (tHigh - tLow) * pc + tLow; return targ; } public static int interpolateCos(int v, int sLow, int sHigh, int tLow, int tHigh) { return (int) interpolateCos((double) v, (double) sLow, (double) sHigh, (double) tLow, (double) tHigh); } public static double tableLookup(int col1, double v1, int col2, double[][] table) { int low = 0; int high = table.length - 1; if (v1 <= table[low][col1]) { return table[low][col2]; } if (v1 >= table[high][col1]) { return table[high][col2]; } while (high - low > 1) { int mid = (high + low) / 2; if (v1 < table[mid][col1]) { high = mid; } else if (v1 > table[mid][col1]) { low = mid; } else { return table[mid][col2]; } } double pc = (v1 - table[low][col1]) / (table[high][col1] - table[low][col1]); double ret = (table[high][col2] - table[low][col2]) * pc + table[low][col2]; return ret; } public static double bind(double value, double low, double high) { if (value < low) { return low; } if (value > high) { return high; } return value; } /** * Calculate Log base 10. * * @param v value * @return double log */ public static double log10(double v) { return Math.log(v) / 2.302585092994; } public static double min(double[] range) { double min = range[0]; for (int i = 1; i < range.length; i++) { if (range[i] < min) { min = range[i]; } } return min; } public static double max(double[] range) { double max = range[0]; for (int i = 1; i < range.length; i++) { if (range[i] > max) { max = range[i]; } } return max; } public static int sgn(double d) { if (d < 0) { return -1; } if (d > 0) { return 1; } return 0; } public static double dist(double x1, double y1, double x2, double y2) { double dx = x1 - x2; double dy = y1 - y2; return Math.sqrt(dx * dx + dy * dy); } public static double dist(double x1, double y1, double z1, double x2, double y2, double z2) { double dx = x1 - x2; double dy = y1 - y2; double dz = z1 - z2; return Math.sqrt(dx * dx + dy * dy + dz * dz); } public static double area(double x1, double y1, double x2, double y2, double x3, double y3) { double a = dist(x1, y1, x2, y2); double b = dist(x2, y2, x3, y3); double c = dist(x3, y3, x1, y1); double d = .25 * Math.sqrt( (a + b + c) * (b + c - a) * (c + a - b) * (a + b - c) ); return d; } public static double area(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3) { double a = dist(x1, y1, z1, x2, y2, z2); double b = dist(x2, y2, z2, x3, y3, z3); double c = dist(x3, y3, z3, x1, y1, z1); double d = .25 * Math.sqrt( (a + b + c) * (b + c - a) * (c + a - b) * (a + b - c) ); return d; } public static boolean equals(double v1, double v2) { return Math.abs(v1 - v2) < EPSILON; } public static boolean isColinear(double x1, double y1, double x2, double y2, double x3, double y3) { // trivial colinear test if (equals(y1, y2) && equals(y2, y3)) { return true; } if (equals(x1, x2) && equals(x2, x3)) { return true; } // if one slope is infinity, can't be colinear since we've already tested trivial case above if (equals(x1, x2) || equals(x2, x3)) { return false; } // now compare slopes double slope1 = (y1 - y2) / (x1 - x2); double slope2 = (y1 - y3) / (x1 - x3); return equals(slope1, slope2); } // http://www.vb-helper.com/howto_segments_intersect.html public static double[] isLineSegmentsIntersect(double l1p1x, double l1p1y, double l1p2x, double l1p2y, double l2p1x, double l2p1y, double l2p2x, double l2p2y) { double dx = l1p2x - l1p1x; double dy = l1p2y - l1p1y; double da = l2p2x - l2p1x; double db = l2p2y - l2p1y; if ((da * dy - db * dx) == 0) { return null; // The segments are parallel. } double s = (dx * (l2p1y - l1p1y) + dy * (l1p1x - l2p1x)) / (da * dy - db * dx); double t = (da * (l1p1y - l2p1y) + db * (l2p1x - l1p1x)) / (db * dx - da * dy); boolean intersect = (s >= 0) && (s <= 1) && (t >= 0) && (t <= 1); if (intersect) { return new double[]{l1p1x + t * dx, l1p1y + t * dy}; } else { return null; } } public static int stride(int val, int span) { if (val > 0) { return val / span; } else { return -((-val - 1) / span + 1); } } public static int positiveMod(int val, int modulus) { int m = val % modulus; if (m >= 0) { return m; } else { return modulus + m; } } }