- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-package org.oscim.utils.math;
-
-import java.util.Random;
-
-/**
- * Utility and fast math functions.
- *
- * Thanks to Riven on JavaGaming.org for the basis of sin/cos/atan2/floor/ceil.
- *
- * @author Nathan Sweet
- */
-public class MathUtils {
- static public final float nanoToSec = 1 / 1000000000f;
-
- static public final float PI = 3.1415927f;
- public static final float PI2 = PI * 2;
-
- static private final int SIN_BITS = 13; // Adjust for accuracy.
- static private final int SIN_MASK = ~(-1 << SIN_BITS);
- static private final int SIN_COUNT = SIN_MASK + 1;
-
- static private final float radFull = PI * 2;
- static private final float degFull = 360;
- static private final float radToIndex = SIN_COUNT / radFull;
- static private final float degToIndex = SIN_COUNT / degFull;
-
- static public final float radiansToDegrees = 180f / PI;
- static public final float radDeg = radiansToDegrees;
- static public final float degreesToRadians = PI / 180;
- static public final float degRad = degreesToRadians;
-
- static private class Sin {
- static final float[] table = new float[SIN_COUNT];
- static {
- for (int i = 0; i < SIN_COUNT; i++)
- table[i] = (float) Math.sin((i + 0.5f) / SIN_COUNT * radFull);
- for (int i = 0; i < 360; i += 90)
- table[(int) (i * degToIndex) & SIN_MASK] = (float) Math.sin(i * degreesToRadians);
- }
- }
-
- static private class Cos {
- static final float[] table = new float[SIN_COUNT];
- static {
- for (int i = 0; i < SIN_COUNT; i++)
- table[i] = (float) Math.cos((i + 0.5f) / SIN_COUNT * radFull);
- for (int i = 0; i < 360; i += 90)
- table[(int) (i * degToIndex) & SIN_MASK] = (float) Math.cos(i * degreesToRadians);
- }
- }
-
- /** Returns the sine in radians. */
- static public final float sin(float radians) {
- return Sin.table[(int) (radians * radToIndex) & SIN_MASK];
- }
-
- /** Returns the cosine in radians. */
- static public final float cos(float radians) {
- return Cos.table[(int) (radians * radToIndex) & SIN_MASK];
- }
-
- /** Returns the sine in radians. */
- static public final float sinDeg(float degrees) {
- return Sin.table[(int) (degrees * degToIndex) & SIN_MASK];
- }
-
- /** Returns the cosine in radians. */
- static public final float cosDeg(float degrees) {
- return Cos.table[(int) (degrees * degToIndex) & SIN_MASK];
- }
-
- // ---
-
- static private final int ATAN2_BITS = 7; // Adjust for accuracy.
- static private final int ATAN2_BITS2 = ATAN2_BITS << 1;
- static private final int ATAN2_MASK = ~(-1 << ATAN2_BITS2);
- static private final int ATAN2_COUNT = ATAN2_MASK + 1;
- static final int ATAN2_DIM = (int) Math.sqrt(ATAN2_COUNT);
- static private final float INV_ATAN2_DIM_MINUS_1 = 1.0f / (ATAN2_DIM - 1);
-
- static private class Atan2 {
- static final float[] table = new float[ATAN2_COUNT];
- static {
- for (int i = 0; i < ATAN2_DIM; i++) {
- for (int j = 0; j < ATAN2_DIM; j++) {
- float x0 = (float) i / ATAN2_DIM;
- float y0 = (float) j / ATAN2_DIM;
- table[j * ATAN2_DIM + i] = (float) Math.atan2(y0, x0);
- }
- }
- }
- }
-
- /** Returns atan2 in radians from a lookup table. */
- static public final float atan2(float y, float x) {
- float add, mul;
- if (x < 0) {
- if (y < 0) {
- y = -y;
- mul = 1;
- } else
- mul = -1;
- x = -x;
- add = -PI;
- } else {
- if (y < 0) {
- y = -y;
- mul = -1;
- } else
- mul = 1;
- add = 0;
- }
- float invDiv = 1 / ((x < y ? y : x) * INV_ATAN2_DIM_MINUS_1);
- int xi = (int) (x * invDiv);
- int yi = (int) (y * invDiv);
- return (Atan2.table[yi * ATAN2_DIM + xi] + add) * mul;
- }
-
- // ---
-
- static public Random random = new Random();
-
- /**
- * Returns a random number between 0 (inclusive) and the specified value
- * (inclusive).
- */
- static public final int random(int range) {
- return random.nextInt(range + 1);
- }
-
- /** Returns a random number between start (inclusive) and end (inclusive). */
- static public final int random(int start, int end) {
- return start + random.nextInt(end - start + 1);
- }
-
- /** Returns a random boolean value. */
- static public final boolean randomBoolean() {
- return random.nextBoolean();
- }
-
- /** Returns random number between 0.0 (inclusive) and 1.0 (exclusive). */
- static public final float random() {
- return random.nextFloat();
- }
-
- /**
- * Returns a random number between 0 (inclusive) and the specified value
- * (exclusive).
- */
- static public final float random(float range) {
- return random.nextFloat() * range;
- }
-
- /** Returns a random number between start (inclusive) and end (exclusive). */
- static public final float random(float start, float end) {
- return start + random.nextFloat() * (end - start);
- }
-
- // ---
-
- /**
- * Returns the next power of two. Returns the specified value if the value
- * is already a power of two.
- */
- static public int nextPowerOfTwo(int value) {
- if (value == 0)
- return 1;
- value--;
- value |= value >> 1;
- value |= value >> 2;
- value |= value >> 4;
- value |= value >> 8;
- value |= value >> 16;
- return value + 1;
- }
-
- static public boolean isPowerOfTwo(int value) {
- return value != 0 && (value & value - 1) == 0;
- }
-
- // ---
-
- static public int clamp(int value, int min, int max) {
- if (value < min)
- return min;
- if (value > max)
- return max;
- return value;
- }
-
- static public short clamp(short value, short min, short max) {
- if (value < min)
- return min;
- if (value > max)
- return max;
- return value;
- }
-
- static public float clamp(float value, float min, float max) {
- if (value < min)
- return min;
- if (value > max)
- return max;
- return value;
- }
-
- // ---
-
- static private final int BIG_ENOUGH_INT = 16 * 1024;
- static private final double BIG_ENOUGH_FLOOR = BIG_ENOUGH_INT;
- static private final double CEIL = 0.9999999;
- static private final double BIG_ENOUGH_CEIL = Double.longBitsToDouble(Double.doubleToLongBits(BIG_ENOUGH_INT + 1) - 1);
- static private final double BIG_ENOUGH_ROUND = BIG_ENOUGH_INT + 0.5f;
-
- /**
- * Returns the largest integer less than or equal to the specified float.
- * This method will only properly floor floats from
- * -(2^14) to (Float.MAX_VALUE - 2^14).
- */
- static public int floor(float x) {
- return (int) (x + BIG_ENOUGH_FLOOR) - BIG_ENOUGH_INT;
- }
-
- /**
- * Returns the largest integer less than or equal to the specified float.
- * This method will only properly floor floats that are
- * positive. Note this method simply casts the float to int.
- */
- static public int floorPositive(float x) {
- return (int) x;
- }
-
- /**
- * Returns the smallest integer greater than or equal to the specified
- * float. This method will only properly ceil floats from
- * -(2^14) to (Float.MAX_VALUE - 2^14).
- */
- static public int ceil(float x) {
- return (int) (x + BIG_ENOUGH_CEIL) - BIG_ENOUGH_INT;
- }
-
- /**
- * Returns the smallest integer greater than or equal to the specified
- * float. This method will only properly ceil floats that
- * are positive.
- */
- static public int ceilPositive(float x) {
- return (int) (x + CEIL);
- }
-
- /**
- * Returns the closest integer to the specified float. This method will only
- * properly round floats from -(2^14) to
- * (Float.MAX_VALUE - 2^14).
- */
- static public int round(float x) {
- return (int) (x + BIG_ENOUGH_ROUND) - BIG_ENOUGH_INT;
- }
-
- /**
- * Returns the closest integer to the specified float. This method will only
- * properly round floats that are positive.
- */
- static public int roundPositive(float x) {
- return (int) (x + 0.5f);
- }
-}
+/*******************************************************************************
+ * Copyright 2011 Mario Zechner
+ * Copyright 2011 Nathan Sweet
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+package org.oscim.utils.math;
+
+import java.util.Random;
+
+/**
+ * Utility and fast math functions.
+ *
+ * Thanks to Riven on JavaGaming.org for the basis of sin/cos/atan2/floor/ceil.
+ *
+ * @author Nathan Sweet
+ */
+public class MathUtils {
+ static public final float nanoToSec = 1 / 1000000000f;
+
+ static public final float PI = 3.1415927f;
+ public static final float PI2 = PI * 2;
+
+ static private final int SIN_BITS = 13; // Adjust for accuracy.
+ static private final int SIN_MASK = ~(-1 << SIN_BITS);
+ static private final int SIN_COUNT = SIN_MASK + 1;
+
+ static private final float radFull = PI * 2;
+ static private final float degFull = 360;
+ static private final float radToIndex = SIN_COUNT / radFull;
+ static private final float degToIndex = SIN_COUNT / degFull;
+
+ static public final float radiansToDegrees = 180f / PI;
+ static public final float radDeg = radiansToDegrees;
+ static public final float degreesToRadians = PI / 180;
+ static public final float degRad = degreesToRadians;
+
+ static private class Sin {
+ static final float[] table = new float[SIN_COUNT];
+ static {
+ for (int i = 0; i < SIN_COUNT; i++)
+ table[i] = (float) Math.sin((i + 0.5f) / SIN_COUNT * radFull);
+ for (int i = 0; i < 360; i += 90)
+ table[(int) (i * degToIndex) & SIN_MASK] = (float) Math.sin(i * degreesToRadians);
+ }
+ }
+
+ static private class Cos {
+ static final float[] table = new float[SIN_COUNT];
+ static {
+ for (int i = 0; i < SIN_COUNT; i++)
+ table[i] = (float) Math.cos((i + 0.5f) / SIN_COUNT * radFull);
+ for (int i = 0; i < 360; i += 90)
+ table[(int) (i * degToIndex) & SIN_MASK] = (float) Math.cos(i * degreesToRadians);
+ }
+ }
+
+ /** Returns the sine in radians. */
+ static public final float sin(float radians) {
+ return Sin.table[(int) (radians * radToIndex) & SIN_MASK];
+ }
+
+ /** Returns the cosine in radians. */
+ static public final float cos(float radians) {
+ return Cos.table[(int) (radians * radToIndex) & SIN_MASK];
+ }
+
+ /** Returns the sine in radians. */
+ static public final float sinDeg(float degrees) {
+ return Sin.table[(int) (degrees * degToIndex) & SIN_MASK];
+ }
+
+ /** Returns the cosine in radians. */
+ static public final float cosDeg(float degrees) {
+ return Cos.table[(int) (degrees * degToIndex) & SIN_MASK];
+ }
+
+ // ---
+
+ static private final int ATAN2_BITS = 7; // Adjust for accuracy.
+ static private final int ATAN2_BITS2 = ATAN2_BITS << 1;
+ static private final int ATAN2_MASK = ~(-1 << ATAN2_BITS2);
+ static private final int ATAN2_COUNT = ATAN2_MASK + 1;
+ static final int ATAN2_DIM = (int) Math.sqrt(ATAN2_COUNT);
+ static private final float INV_ATAN2_DIM_MINUS_1 = 1.0f / (ATAN2_DIM - 1);
+
+ static private class Atan2 {
+ static final float[] table = new float[ATAN2_COUNT];
+ static {
+ for (int i = 0; i < ATAN2_DIM; i++) {
+ for (int j = 0; j < ATAN2_DIM; j++) {
+ float x0 = (float) i / ATAN2_DIM;
+ float y0 = (float) j / ATAN2_DIM;
+ table[j * ATAN2_DIM + i] = (float) Math.atan2(y0, x0);
+ }
+ }
+ }
+ }
+
+ /** Returns atan2 in radians from a lookup table. */
+ static public final float atan2(float y, float x) {
+ float add, mul;
+ if (x < 0) {
+ if (y < 0) {
+ y = -y;
+ mul = 1;
+ } else
+ mul = -1;
+ x = -x;
+ add = -PI;
+ } else {
+ if (y < 0) {
+ y = -y;
+ mul = -1;
+ } else
+ mul = 1;
+ add = 0;
+ }
+ float invDiv = 1 / ((x < y ? y : x) * INV_ATAN2_DIM_MINUS_1);
+ int xi = (int) (x * invDiv);
+ int yi = (int) (y * invDiv);
+ return (Atan2.table[yi * ATAN2_DIM + xi] + add) * mul;
+ }
+
+ // ---
+
+ static public Random random = new Random();
+
+ /**
+ * Returns a random number between 0 (inclusive) and the specified value
+ * (inclusive).
+ */
+ static public final int random(int range) {
+ return random.nextInt(range + 1);
+ }
+
+ /** Returns a random number between start (inclusive) and end (inclusive). */
+ static public final int random(int start, int end) {
+ return start + random.nextInt(end - start + 1);
+ }
+
+ /** Returns a random boolean value. */
+ static public final boolean randomBoolean() {
+ return random.nextBoolean();
+ }
+
+ /** Returns random number between 0.0 (inclusive) and 1.0 (exclusive). */
+ static public final float random() {
+ return random.nextFloat();
+ }
+
+ /**
+ * Returns a random number between 0 (inclusive) and the specified value
+ * (exclusive).
+ */
+ static public final float random(float range) {
+ return random.nextFloat() * range;
+ }
+
+ /** Returns a random number between start (inclusive) and end (exclusive). */
+ static public final float random(float start, float end) {
+ return start + random.nextFloat() * (end - start);
+ }
+
+ // ---
+
+ /**
+ * Returns the next power of two. Returns the specified value if the value
+ * is already a power of two.
+ */
+ static public int nextPowerOfTwo(int value) {
+ if (value == 0)
+ return 1;
+ value--;
+ value |= value >> 1;
+ value |= value >> 2;
+ value |= value >> 4;
+ value |= value >> 8;
+ value |= value >> 16;
+ return value + 1;
+ }
+
+ static public boolean isPowerOfTwo(int value) {
+ return value != 0 && (value & value - 1) == 0;
+ }
+
+ // ---
+
+ static public int clamp(int value, int min, int max) {
+ if (value < min)
+ return min;
+ if (value > max)
+ return max;
+ return value;
+ }
+
+ static public short clamp(short value, short min, short max) {
+ if (value < min)
+ return min;
+ if (value > max)
+ return max;
+ return value;
+ }
+
+ static public float clamp(float value, float min, float max) {
+ if (value < min)
+ return min;
+ if (value > max)
+ return max;
+ return value;
+ }
+
+ // ---
+
+ static private final int BIG_ENOUGH_INT = 16 * 1024;
+ static private final double BIG_ENOUGH_FLOOR = BIG_ENOUGH_INT;
+ static private final double CEIL = 0.9999999;
+ static private final double BIG_ENOUGH_CEIL = Double.longBitsToDouble(Double.doubleToLongBits(BIG_ENOUGH_INT + 1) - 1);
+ static private final double BIG_ENOUGH_ROUND = BIG_ENOUGH_INT + 0.5f;
+
+ /**
+ * Returns the largest integer less than or equal to the specified float.
+ * This method will only properly floor floats from
+ * -(2^14) to (Float.MAX_VALUE - 2^14).
+ */
+ static public int floor(float x) {
+ return (int) (x + BIG_ENOUGH_FLOOR) - BIG_ENOUGH_INT;
+ }
+
+ /**
+ * Returns the largest integer less than or equal to the specified float.
+ * This method will only properly floor floats that are
+ * positive. Note this method simply casts the float to int.
+ */
+ static public int floorPositive(float x) {
+ return (int) x;
+ }
+
+ /**
+ * Returns the smallest integer greater than or equal to the specified
+ * float. This method will only properly ceil floats from
+ * -(2^14) to (Float.MAX_VALUE - 2^14).
+ */
+ static public int ceil(float x) {
+ return (int) (x + BIG_ENOUGH_CEIL) - BIG_ENOUGH_INT;
+ }
+
+ /**
+ * Returns the smallest integer greater than or equal to the specified
+ * float. This method will only properly ceil floats that
+ * are positive.
+ */
+ static public int ceilPositive(float x) {
+ return (int) (x + CEIL);
+ }
+
+ /**
+ * Returns the closest integer to the specified float. This method will only
+ * properly round floats from -(2^14) to
+ * (Float.MAX_VALUE - 2^14).
+ */
+ static public int round(float x) {
+ return (int) (x + BIG_ENOUGH_ROUND) - BIG_ENOUGH_INT;
+ }
+
+ /**
+ * Returns the closest integer to the specified float. This method will only
+ * properly round floats that are positive.
+ */
+ static public int roundPositive(float x) {
+ return (int) (x + 0.5f);
+ }
+}