159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.math;
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Random;
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>FastMath</code> provides 'fast' math approximations and float equivalents of Math
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * functions.  These are all used as static values and functions.
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Various
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @version $Id: FastMath.java,v 1.45 2007/08/26 08:44:20 irrisor Exp $
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartafinal public class FastMath {
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private FastMath() {
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** A "close to zero" double epsilon value for use*/
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final double DBL_EPSILON = 2.220446049250313E-16d;
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** A "close to zero" float epsilon value for use*/
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float FLT_EPSILON = 1.1920928955078125E-7f;
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** A "close to zero" float epsilon value for use*/
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float ZERO_TOLERANCE = 0.0001f;
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float ONE_THIRD = 1f / 3f;
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** The value PI as a float. (180 degrees) */
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float PI = (float) Math.PI;
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** The value 2PI as a float. (360 degrees) */
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float TWO_PI = 2.0f * PI;
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** The value PI/2 as a float. (90 degrees) */
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float HALF_PI = 0.5f * PI;
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** The value PI/4 as a float. (45 degrees) */
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float QUARTER_PI = 0.25f * PI;
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** The value 1/PI as a float. */
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float INV_PI = 1.0f / PI;
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** The value 1/(2PI) as a float. */
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float INV_TWO_PI = 1.0f / TWO_PI;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** A value to multiply a degree value by, to convert it to radians. */
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float DEG_TO_RAD = PI / 180.0f;
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** A value to multiply a radian value by, to convert it to degrees. */
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final float RAD_TO_DEG = 180.0f / PI;
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /** A precreated random object for random numbers. */
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static final Random rand = new Random(System.currentTimeMillis());
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns true if the number is a power of 2 (2,4,8,16...)
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * A good implementation found on the Java boards. note: a number is a power
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * of two if and only if it is the smallest number with that number of
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * significant bits. Therefore, if you subtract 1, you know that the new
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * number will have fewer bits, so ANDing the original number with anything
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * less than it will give 0.
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param number
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            The number to test.
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return True if it is a power of two.
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static boolean isPowerOfTwo(int number) {
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (number > 0) && (number & (number - 1)) == 0;
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static int nearestPowerOfTwo(int number) {
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (int) Math.pow(2, Math.ceil(Math.log(number) / Math.log(2)));
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Linear interpolation from startValue to endValue by the given percent.
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Basically: ((1 - percent) * startValue) + (percent * endValue)
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scale
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            scale value to use. if 1, use endValue, if 0, use startValue.
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param startValue
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            Begining value. 0% of f
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param endValue
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            ending value. 100% of f
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The interpolated value between startValue and endValue.
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float interpolateLinear(float scale, float startValue, float endValue) {
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (startValue == endValue) {
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return startValue;
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (scale <= 0f) {
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return startValue;
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (scale >= 1f) {
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return endValue;
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return ((1f - scale) * startValue) + (scale * endValue);
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Linear interpolation from startValue to endValue by the given percent.
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Basically: ((1 - percent) * startValue) + (percent * endValue)
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scale
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            scale value to use. if 1, use endValue, if 0, use startValue.
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param startValue
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            Begining value. 0% of f
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param endValue
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            ending value. 100% of f
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param store a vector3f to store the result
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The interpolated value between startValue and endValue.
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f interpolateLinear(float scale, Vector3f startValue, Vector3f endValue, Vector3f store) {
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new Vector3f();
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.x = interpolateLinear(scale, startValue.x, endValue.x);
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.y = interpolateLinear(scale, startValue.y, endValue.y);
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.z = interpolateLinear(scale, startValue.z, endValue.z);
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Linear interpolation from startValue to endValue by the given percent.
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Basically: ((1 - percent) * startValue) + (percent * endValue)
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scale
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            scale value to use. if 1, use endValue, if 0, use startValue.
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param startValue
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            Begining value. 0% of f
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param endValue
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            ending value. 100% of f
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The interpolated value between startValue and endValue.
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f interpolateLinear(float scale, Vector3f startValue, Vector3f endValue) {
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return interpolateLinear(scale, startValue, endValue, null);
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Linear extrapolation from startValue to endValue by the given scale.
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * if scale is between 0 and 1 this method returns the same result as interpolateLinear
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * if the scale is over 1 the value is linearly extrapolated.
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Note that the end value is the value for a scale of 1.
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scale the scale for extrapolation
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param startValue the starting value (scale = 0)
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param endValue the end value (scale = 1)
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return an extrapolation for the given parameters
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float extrapolateLinear(float scale, float startValue, float endValue) {
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        if (scale <= 0f) {
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            return startValue;
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        }
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return ((1f - scale) * startValue) + (scale * endValue);
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Linear extrapolation from startValue to endValue by the given scale.
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * if scale is between 0 and 1 this method returns the same result as interpolateLinear
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * if the scale is over 1 the value is linearly extrapolated.
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Note that the end value is the value for a scale of 1.
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scale the scale for extrapolation
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param startValue the starting value (scale = 0)
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param endValue the end value (scale = 1)
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param store an initialized vector to store the return value
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return an extrapolation for the given parameters
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f extrapolateLinear(float scale, Vector3f startValue, Vector3f endValue, Vector3f store) {
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new Vector3f();
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        if (scale <= 1f) {
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//            return interpolateLinear(scale, startValue, endValue, store);
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//        }
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.x = extrapolateLinear(scale, startValue.x, endValue.x);
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.y = extrapolateLinear(scale, startValue.y, endValue.y);
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.z = extrapolateLinear(scale, startValue.z, endValue.z);
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Linear extrapolation from startValue to endValue by the given scale.
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * if scale is between 0 and 1 this method returns the same result as interpolateLinear
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * if the scale is over 1 the value is linearly extrapolated.
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Note that the end value is the value for a scale of 1.
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scale the scale for extrapolation
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param startValue the starting value (scale = 0)
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param endValue the end value (scale = 1)
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return an extrapolation for the given parameters
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f extrapolateLinear(float scale, Vector3f startValue, Vector3f endValue) {
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return extrapolateLinear(scale, startValue, endValue, null);
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * here is the interpolation matrix
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * m = [ 0.0  1.0  0.0   0.0 ]
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [-T    0.0  T     0.0 ]
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [ 2T   T-3  3-2T  -T  ]
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [-T    2-T  T-2   T   ]
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * where T is the curve tension
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the result is a value between p1 and p2, t=0 for p1, t=1 for p2
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param u value from 0 to 1
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param T The tension of the curve
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 control point 0
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 control point 1
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 control point 2
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p3 control point 3
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return catmull-Rom interpolation
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float interpolateCatmullRom(float u, float T, float p0, float p1, float p2, float p3) {
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float c1, c2, c3, c4;
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        c1 = p1;
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        c2 = -1.0f * T * p0 + T * p2;
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        c3 = 2 * T * p0 + (T - 3) * p1 + (3 - 2 * T) * p2 + -T * p3;
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        c4 = -T * p0 + (2 - T) * p1 + (T - 2) * p2 + T * p3;
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) (((c4 * u + c3) * u + c2) * u + c1);
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * here is the interpolation matrix
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * m = [ 0.0  1.0  0.0   0.0 ]
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [-T    0.0  T     0.0 ]
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [ 2T   T-3  3-2T  -T  ]
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [-T    2-T  T-2   T   ]
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * where T is the tension of the curve
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the result is a value between p1 and p2, t=0 for p1, t=1 for p2
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param u value from 0 to 1
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param T The tension of the curve
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 control point 0
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 control point 1
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 control point 2
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p3 control point 3
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param store a Vector3f to store the result
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return catmull-Rom interpolation
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, Vector3f store) {
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new Vector3f();
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.x = interpolateCatmullRom(u, T, p0.x, p1.x, p2.x, p3.x);
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.y = interpolateCatmullRom(u, T, p0.y, p1.y, p2.y, p3.y);
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.z = interpolateCatmullRom(u, T, p0.z, p1.z, p2.z, p3.z);
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**Interpolate a spline between at least 4 control points following the Catmull-Rom equation.
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * here is the interpolation matrix
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * m = [ 0.0  1.0  0.0   0.0 ]
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [-T    0.0  T     0.0 ]
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [ 2T   T-3  3-2T  -T  ]
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [-T    2-T  T-2   T   ]
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * where T is the tension of the curve
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the result is a value between p1 and p2, t=0 for p1, t=1 for p2
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param u value from 0 to 1
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param T The tension of the curve
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 control point 0
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 control point 1
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 control point 2
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p3 control point 3
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return catmull-Rom interpolation
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f interpolateCatmullRom(float u, float T, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3) {
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return interpolateCatmullRom(u, T, p0, p1, p2, p3, null);
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**Interpolate a spline between at least 4 control points following the Bezier equation.
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * here is the interpolation matrix
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * m = [ -1.0   3.0  -3.0    1.0 ]
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [  3.0  -6.0   3.0    0.0 ]
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [ -3.0   3.0   0.0    0.0 ]
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [  1.0   0.0   0.0    0.0 ]
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * where T is the curve tension
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the result is a value between p1 and p3, t=0 for p1, t=1 for p3
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param u value from 0 to 1
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 control point 0
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 control point 1
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 control point 2
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p3 control point 3
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return Bezier interpolation
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float interpolateBezier(float u, float p0, float p1, float p2, float p3) {
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float oneMinusU = 1.0f - u;
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float oneMinusU2 = oneMinusU * oneMinusU;
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float u2 = u * u;
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return p0 * oneMinusU2 * oneMinusU
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + 3.0f * p1 * u * oneMinusU2
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + 3.0f * p2 * u2 * oneMinusU
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + p3 * u2 * u;
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**Interpolate a spline between at least 4 control points following the Bezier equation.
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * here is the interpolation matrix
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * m = [ -1.0   3.0  -3.0    1.0 ]
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [  3.0  -6.0   3.0    0.0 ]
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [ -3.0   3.0   0.0    0.0 ]
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [  1.0   0.0   0.0    0.0 ]
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * where T is the tension of the curve
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the result is a value between p1 and p3, t=0 for p1, t=1 for p3
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param u value from 0 to 1
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 control point 0
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 control point 1
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 control point 2
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p3 control point 3
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param store a Vector3f to store the result
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return Bezier interpolation
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f interpolateBezier(float u, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, Vector3f store) {
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (store == null) {
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store = new Vector3f();
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.x = interpolateBezier(u, p0.x, p1.x, p2.x, p3.x);
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.y = interpolateBezier(u, p0.y, p1.y, p2.y, p3.y);
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.z = interpolateBezier(u, p0.z, p1.z, p2.z, p3.z);
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**Interpolate a spline between at least 4 control points following the Bezier equation.
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * here is the interpolation matrix
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * m = [ -1.0   3.0  -3.0    1.0 ]
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [  3.0  -6.0   3.0    0.0 ]
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [ -3.0   3.0   0.0    0.0 ]
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *     [  1.0   0.0   0.0    0.0 ]
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * where T is the tension of the curve
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the result is a value between p1 and p3, t=0 for p1, t=1 for p3
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param u value from 0 to 1
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 control point 0
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 control point 1
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 control point 2
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p3 control point 3
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return Bezier interpolation
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f interpolateBezier(float u, Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3) {
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return interpolateBezier(u, p0, p1, p2, p3, null);
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Compute the lenght on a catmull rom spline between control point 1 and 2
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 control point 0
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 control point 1
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 control point 2
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p3 control point 3
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param startRange the starting range on the segment (use 0)
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param endRange the end range on the segment (use 1)
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param curveTension the curve tension
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the length of the segment
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float getCatmullRomP1toP2Length(Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3, float startRange, float endRange, float curveTension) {
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float epsilon = 0.001f;
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float middleValue = (startRange + endRange) * 0.5f;
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f start = p1.clone();
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (startRange != 0) {
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            FastMath.interpolateCatmullRom(startRange, curveTension, p0, p1, p2, p3, start);
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f end = p2.clone();
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (endRange != 1) {
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            FastMath.interpolateCatmullRom(endRange, curveTension, p0, p1, p2, p3, end);
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f middle = FastMath.interpolateCatmullRom(middleValue, curveTension, p0, p1, p2, p3);
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float l = end.subtract(start).length();
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float l1 = middle.subtract(start).length();
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float l2 = end.subtract(middle).length();
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float len = l1 + l2;
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (l + epsilon < len) {
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            l1 = getCatmullRomP1toP2Length(p0, p1, p2, p3, startRange, middleValue, curveTension);
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            l2 = getCatmullRomP1toP2Length(p0, p1, p2, p3, middleValue, endRange, curveTension);
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        l = l1 + l2;
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return l;
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Compute the lenght on a bezier spline between control point 1 and 2
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 control point 0
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 control point 1
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 control point 2
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p3 control point 3
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the length of the segment
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float getBezierP1toP2Length(Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3) {
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float delta = 0.02f, t = 0.0f, result = 0.0f;
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f v1 = p0.clone(), v2 = new Vector3f();
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while (t <= 1.0f) {
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            FastMath.interpolateBezier(t, p0, p1, p2, p3, v2);
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            result += v1.subtractLocal(v2).length();
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            v1.set(v2);
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            t += delta;
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return result;
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the arc cosine of an angle given in radians.<br>
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Special cases:
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <ul><li>If fValue is smaller than -1, then the result is PI.
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <li>If the argument is greater than 1, then the result is 0.</ul>
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The angle, in radians.
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return fValue's acos
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#acos(double)
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float acos(float fValue) {
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (-1.0f < fValue) {
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (fValue < 1.0f) {
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return (float) Math.acos(fValue);
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 0.0f;
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return PI;
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the arc sine of an angle given in radians.<br>
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Special cases:
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <ul><li>If fValue is smaller than -1, then the result is -HALF_PI.
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <li>If the argument is greater than 1, then the result is HALF_PI.</ul>
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The angle, in radians.
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return fValue's asin
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#asin(double)
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float asin(float fValue) {
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (-1.0f < fValue) {
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (fValue < 1.0f) {
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return (float) Math.asin(fValue);
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return HALF_PI;
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return -HALF_PI;
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the arc tangent of an angle given in radians.<br>
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The angle, in radians.
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return fValue's atan
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#atan(double)
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float atan(float fValue) {
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.atan(fValue);
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * A direct call to Math.atan2.
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fY
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fX
46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return Math.atan2(fY,fX)
46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#atan2(double, double)
47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float atan2(float fY, float fX) {
47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.atan2(fY, fX);
47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Rounds a fValue up.  A call to Math.ceil
47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The value.
47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The fValue rounded up
47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#ceil(double)
48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float ceil(float fValue) {
48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.ceil(fValue);
48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Fast Trig functions for x86. This forces the trig functiosn to stay
48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * within the safe area on the x86 processor (-45 degrees to +45 degrees)
48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The results may be very slightly off from what the Math and StrictMath
48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * trig functions give due to rounding in the angle reduction but it will be
49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * very very close.
49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * note: code from wiki posting on java.net by jeffpk
49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float reduceSinAngle(float radians) {
49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        radians %= TWO_PI; // put us in -2PI to +2PI space
49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(radians) > PI) { // put us in -PI to +PI space
49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            radians = radians - (TWO_PI);
49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(radians) > HALF_PI) {// put us in -PI/2 to +PI/2 space
50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            radians = PI - radians;
50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return radians;
50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns sine of a value.
50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * note: code from wiki posting on java.net by jeffpk
51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue
51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            The value to sine, in radians.
51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The sine of fValue.
51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#sin(double)
51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float sin2(float fValue) {
51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        fValue = reduceSinAngle(fValue); // limits angle to between -PI/2 and +PI/2
51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Math.abs(fValue) <= Math.PI / 4) {
51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return (float) Math.sin(fValue);
52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.cos(Math.PI / 2 - fValue);
52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns cos of a value.
52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue
52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            The value to cosine, in radians.
53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The cosine of fValue.
53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#cos(double)
53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float cos2(float fValue) {
53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return sin2(fValue + HALF_PI);
53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float cos(float v) {
53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.cos(v);
53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float sin(float v) {
54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.sin(v);
54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns E^fValue
54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue Value to raise to a power.
54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The value E^fValue
54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#exp(double)
55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float exp(float fValue) {
55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.exp(fValue);
55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns Absolute value of a float.
55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The value to abs.
55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The abs of the value.
55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#abs(float)
56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float abs(float fValue) {
56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (fValue < 0) {
56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return -fValue;
56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return fValue;
56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns a number rounded down.
57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The value to round
57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The given number rounded down
57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#floor(double)
57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float floor(float fValue) {
57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.floor(fValue);
57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns 1/sqrt(fValue)
58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The value to process.
58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return 1/sqrt(fValue)
58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#sqrt(double)
58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float invSqrt(float fValue) {
58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) (1.0f / Math.sqrt(fValue));
58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float fastInvSqrt(float x) {
58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float xhalf = 0.5f * x;
59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int i = Float.floatToIntBits(x); // get bits for floating value
59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        i = 0x5f375a86 - (i >> 1); // gives initial guess y0
59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        x = Float.intBitsToFloat(i); // convert bits back to float
59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        x = x * (1.5f - xhalf * x * x); // Newton step, repeating increases accuracy
59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return x;
59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the log base E of a value.
59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The value to log.
60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The log of fValue base E
60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#log(double)
60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float log(float fValue) {
60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.log(fValue);
60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the logarithm of value with given base, calculated as log(value)/log(base),
60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * so that pow(base, return)==value (contributed by vear)
61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param value The value to log.
61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param base Base of logarithm.
61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The logarithm of value with given base
61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float log(float value, float base) {
61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) (Math.log(value) / Math.log(base));
61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns a number raised to an exponent power.  fBase^fExponent
62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fBase The base value (IE 2)
62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fExponent The exponent value (IE 3)
62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return base raised to exponent (IE 8)
62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#pow(double, double)
62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float pow(float fBase, float fExponent) {
62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.pow(fBase, fExponent);
62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the value squared.  fValue ^ 2
63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The vaule to square.
63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The square of the given value.
63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float sqr(float fValue) {
63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return fValue * fValue;
63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the square root of a given value.
64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The value to sqrt.
64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The square root of the given value.
64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#sqrt(double)
64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float sqrt(float fValue) {
64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.sqrt(fValue);
64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the tangent of a value.  If USE_FAST_TRIG is enabled, an approximate value
65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * is returned.  Otherwise, a direct value is used.
65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The value to tangent, in radians.
65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The tangent of fValue.
65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see java.lang.Math#tan(double)
65459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float tan(float fValue) {
65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) Math.tan(fValue);
65759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
65859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
65959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
66059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns 1 if the number is positive, -1 if the number is negative, and 0 otherwise
66159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param iValue The integer to examine.
66259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The integer's sign.
66359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
66459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static int sign(int iValue) {
66559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (iValue > 0) {
66659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 1;
66759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
66859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (iValue < 0) {
66959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return -1;
67059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
67159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return 0;
67259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
67359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
67459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
67559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns 1 if the number is positive, -1 if the number is negative, and 0 otherwise
67659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param fValue The float to examine.
67759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The float's sign.
67859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
67959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float sign(float fValue) {
68059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return Math.signum(fValue);
68159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
68259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
68359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
68459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Given 3 points in a 2d plane, this function computes if the points going from A-B-C
68559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * are moving counter clock wise.
68659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p0 Point 0.
68759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p1 Point 1.
68859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p2 Point 2.
68959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return 1 If they are CCW, -1 if they are not CCW, 0 if p2 is between p0 and p1.
69059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
69159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static int counterClockwise(Vector2f p0, Vector2f p1, Vector2f p2) {
69259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float dx1, dx2, dy1, dy2;
69359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dx1 = p1.x - p0.x;
69459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dy1 = p1.y - p0.y;
69559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dx2 = p2.x - p0.x;
69659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dy2 = p2.y - p0.y;
69759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (dx1 * dy2 > dy1 * dx2) {
69859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 1;
69959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
70059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (dx1 * dy2 < dy1 * dx2) {
70159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return -1;
70259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
70359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if ((dx1 * dx2 < 0) || (dy1 * dy2 < 0)) {
70459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return -1;
70559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
70659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if ((dx1 * dx1 + dy1 * dy1) < (dx2 * dx2 + dy2 * dy2)) {
70759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 1;
70859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
70959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return 0;
71059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
71159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
71259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
71359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Test if a point is inside a triangle.  1 if the point is on the ccw side,
71459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * -1 if the point is on the cw side, and 0 if it is on neither.
71559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param t0 First point of the triangle.
71659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param t1 Second point of the triangle.
71759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param t2 Third point of the triangle.
71859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param p The point to test.
71959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return Value 1 or -1 if inside triangle, 0 otherwise.
72059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
72159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static int pointInsideTriangle(Vector2f t0, Vector2f t1, Vector2f t2, Vector2f p) {
72259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int val1 = counterClockwise(t0, t1, p);
72359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (val1 == 0) {
72459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 1;
72559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
72659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int val2 = counterClockwise(t1, t2, p);
72759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (val2 == 0) {
72859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 1;
72959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
73059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (val2 != val1) {
73159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 0;
73259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
73359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int val3 = counterClockwise(t2, t0, p);
73459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (val3 == 0) {
73559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 1;
73659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
73759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (val3 != val1) {
73859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 0;
73959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
74059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return val3;
74159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
74259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
74359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
74459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * A method that computes normal for a triangle defined by three vertices.
74559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param v1 first vertex
74659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param v2 second vertex
74759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param v3 third vertex
74859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a normal for the face
74959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
75059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f computeNormal(Vector3f v1, Vector3f v2, Vector3f v3) {
75159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f a1 = v1.subtract(v2);
75259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f a2 = v3.subtract(v2);
75359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return a2.crossLocal(a1).normalizeLocal();
75459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
75559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
75659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
75759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the determinant of a 4x4 matrix.
75859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
75959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float determinant(double m00, double m01, double m02,
76059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            double m03, double m10, double m11, double m12, double m13,
76159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            double m20, double m21, double m22, double m23, double m30,
76259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            double m31, double m32, double m33) {
76359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
76459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        double det01 = m20 * m31 - m21 * m30;
76559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        double det02 = m20 * m32 - m22 * m30;
76659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        double det03 = m20 * m33 - m23 * m30;
76759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        double det12 = m21 * m32 - m22 * m31;
76859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        double det13 = m21 * m33 - m23 * m31;
76959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        double det23 = m22 * m33 - m23 * m32;
77059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (float) (m00 * (m11 * det23 - m12 * det13 + m13 * det12) - m01
77159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                * (m10 * det23 - m12 * det03 + m13 * det02) + m02
77259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                * (m10 * det13 - m11 * det03 + m13 * det01) - m03
77359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                * (m10 * det12 - m11 * det02 + m12 * det01));
77459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
77559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
77659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
77759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns a random float between 0 and 1.
77859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
77959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return A random float between <tt>0.0f</tt> (inclusive) to
78059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *         <tt>1.0f</tt> (exclusive).
78159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
78259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float nextRandomFloat() {
78359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return rand.nextFloat();
78459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
78559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
78659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
78759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns a random float between min and max.
78859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
78959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return A random int between <tt>min</tt> (inclusive) to
79059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *         <tt>max</tt> (inclusive).
79159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
79259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static int nextRandomInt(int min, int max) {
79359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (int) (nextRandomFloat() * (max - min + 1)) + min;
79459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
79559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
79659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static int nextRandomInt() {
79759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return rand.nextInt();
79859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
79959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
80059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
80159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Converts a point from Spherical coordinates to Cartesian (using positive
80259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Y as up) and stores the results in the store var.
80359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
80459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f sphericalToCartesian(Vector3f sphereCoords,
80559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Vector3f store) {
80659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.y = sphereCoords.x * FastMath.sin(sphereCoords.z);
80759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float a = sphereCoords.x * FastMath.cos(sphereCoords.z);
80859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.x = a * FastMath.cos(sphereCoords.y);
80959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.z = a * FastMath.sin(sphereCoords.y);
81059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
81159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
81259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
81359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
81459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
81559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Converts a point from Cartesian coordinates (using positive Y as up) to
81659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Spherical and stores the results in the store var. (Radius, Azimuth,
81759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Polar)
81859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
81959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f cartesianToSpherical(Vector3f cartCoords,
82059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Vector3f store) {
82159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float x = cartCoords.x;
82259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (x == 0) {
82359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            x = FastMath.FLT_EPSILON;
82459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
82559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.x = FastMath.sqrt((x * x)
82659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + (cartCoords.y * cartCoords.y)
82759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + (cartCoords.z * cartCoords.z));
82859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.y = FastMath.atan(cartCoords.z / x);
82959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (x < 0) {
83059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store.y += FastMath.PI;
83159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
83259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.z = FastMath.asin(cartCoords.y / store.x);
83359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
83459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
83559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
83659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
83759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Converts a point from Spherical coordinates to Cartesian (using positive
83859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Z as up) and stores the results in the store var.
83959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
84059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f sphericalToCartesianZ(Vector3f sphereCoords,
84159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Vector3f store) {
84259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.z = sphereCoords.x * FastMath.sin(sphereCoords.z);
84359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float a = sphereCoords.x * FastMath.cos(sphereCoords.z);
84459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.x = a * FastMath.cos(sphereCoords.y);
84559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.y = a * FastMath.sin(sphereCoords.y);
84659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
84759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
84859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
84959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
85059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
85159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Converts a point from Cartesian coordinates (using positive Z as up) to
85259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Spherical and stores the results in the store var. (Radius, Azimuth,
85359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Polar)
85459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
85559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static Vector3f cartesianZToSpherical(Vector3f cartCoords,
85659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            Vector3f store) {
85759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float x = cartCoords.x;
85859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (x == 0) {
85959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            x = FastMath.FLT_EPSILON;
86059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
86159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.x = FastMath.sqrt((x * x)
86259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + (cartCoords.y * cartCoords.y)
86359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + (cartCoords.z * cartCoords.z));
86459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.z = FastMath.atan(cartCoords.z / x);
86559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (x < 0) {
86659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            store.z += FastMath.PI;
86759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
86859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        store.y = FastMath.asin(cartCoords.y / store.x);
86959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return store;
87059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
87159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
87259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
87359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Takes an value and expresses it in terms of min to max.
87459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
87559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param val -
87659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the angle to normalize (in radians)
87759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the normalized angle (also in radians)
87859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
87959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float normalize(float val, float min, float max) {
88059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.isInfinite(val) || Float.isNaN(val)) {
88159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 0f;
88259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
88359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float range = max - min;
88459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while (val > max) {
88559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            val -= range;
88659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
88759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while (val < min) {
88859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            val += range;
88959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
89059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return val;
89159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
89259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
89359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
89459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param x
89559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the value whose sign is to be adjusted.
89659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param y
89759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the value whose sign is to be used.
89859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return x with its sign changed to match the sign of y.
89959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
90059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float copysign(float x, float y) {
90159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (y >= 0 && x <= -0) {
90259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return -x;
90359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (y < 0 && x >= 0) {
90459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return -x;
90559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
90659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return x;
90759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
90859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
90959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
91059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
91159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Take a float input and clamp it between min and max.
91259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
91359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param input
91459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param min
91559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param max
91659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return clamped input
91759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
91859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float clamp(float input, float min, float max) {
91959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (input < min) ? min : (input > max) ? max : input;
92059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
92159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
92259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
92359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Clamps the given float to be between 0 and 1.
92459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
92559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param input
92659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return input clamped between 0 and 1.
92759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
92859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float saturate(float input) {
92959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return clamp(input, 0f, 1f);
93059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
93159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
93259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
93359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Converts a single precision (32 bit) floating point value
93459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * into half precision (16 bit).
93559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
93659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>Source: <a href="http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf">
93759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf</a><br><strong>broken link</strong>
93859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
93959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param half The half floating point value as a short.
94059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return floating point value of the half.
94159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
94259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static float convertHalfToFloat(short half) {
94359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        switch ((int) half) {
94459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0x0000:
94559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return 0f;
94659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0x8000:
94759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return -0f;
94859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0x7c00:
94959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return Float.POSITIVE_INFINITY;
95059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            case 0xfc00:
95159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return Float.NEGATIVE_INFINITY;
95259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // TODO: Support for NaN?
95359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            default:
95459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                return Float.intBitsToFloat(((half & 0x8000) << 16)
95559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        | (((half & 0x7c00) + 0x1C000) << 13)
95659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        | ((half & 0x03FF) << 13));
95759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
95859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
95959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
96059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public static short convertFloatToHalf(float flt) {
96159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (Float.isNaN(flt)) {
96259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new UnsupportedOperationException("NaN to half conversion not supported!");
96359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (flt == Float.POSITIVE_INFINITY) {
96459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return (short) 0x7c00;
96559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (flt == Float.NEGATIVE_INFINITY) {
96659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return (short) 0xfc00;
96759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (flt == 0f) {
96859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return (short) 0x0000;
96959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (flt == -0f) {
97059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return (short) 0x8000;
97159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (flt > 65504f) {
97259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // max value supported by half float
97359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 0x7bff;
97459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (flt < -65504f) {
97559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return (short) (0x7bff | 0x8000);
97659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (flt > 0f && flt < 5.96046E-8f) {
97759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return 0x0001;
97859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (flt < 0f && flt > -5.96046E-8f) {
97959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return (short) 0x8001;
98059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
98159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
98259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int f = Float.floatToIntBits(flt);
98359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return (short) (((f >> 16) & 0x8000)
98459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                | ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
98559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                | ((f >> 13) & 0x03ff));
98659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
98759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
988