1a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy/*
2a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * Copyright (C) 2009 The Android Open Source Project
3a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy *
4a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * you may not use this file except in compliance with the License.
6a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * You may obtain a copy of the License at
7a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy *
8a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy *
10a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * Unless required by applicable law or agreed to in writing, software
11a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * See the License for the specific language governing permissions and
14a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * limitations under the License.
15a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy */
16a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
17a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guypackage android.util;
18a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
19a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guyimport java.util.Random;
20a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
21a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy/**
22a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * A class that contains utility methods related to numbers.
239af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui *
24a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy * @hide Pending API council approval
25a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy */
26a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guypublic final class MathUtils {
27a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    private static final float DEG_TO_RAD = 3.1415926f / 180.0f;
28a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    private static final float RAD_TO_DEG = 180.0f / 3.1415926f;
29a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
30a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    private MathUtils() {
31a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
32a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
33a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float abs(float v) {
349af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui        return v > 0 ? v : -v;
35a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
36a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
37a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static int constrain(int amount, int low, int high) {
38a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return amount < low ? low : (amount > high ? high : amount);
39a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
40a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
41ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    public static long constrain(long amount, long low, long high) {
42ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        return amount < low ? low : (amount > high ? high : amount);
43ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    }
44ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey
45a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float constrain(float amount, float low, float high) {
46a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return amount < low ? low : (amount > high ? high : amount);
47a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
48a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
49a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float log(float a) {
50a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.log(a);
51a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
52a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
53a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float exp(float a) {
54a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.exp(a);
55a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
56a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
57a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float pow(float a, float b) {
58a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.pow(a, b);
59a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
60a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
61a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float max(float a, float b) {
62a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return a > b ? a : b;
63a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
64a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
65a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float max(int a, int b) {
66a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return a > b ? a : b;
67a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
68a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
69a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float max(float a, float b, float c) {
70a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return a > b ? (a > c ? a : c) : (b > c ? b : c);
71a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
72a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
73a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float max(int a, int b, int c) {
74a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return a > b ? (a > c ? a : c) : (b > c ? b : c);
75a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
76a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
77a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float min(float a, float b) {
78a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return a < b ? a : b;
79a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
80a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
81a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float min(int a, int b) {
82a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return a < b ? a : b;
83a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
84a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
85a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float min(float a, float b, float c) {
86a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return a < b ? (a < c ? a : c) : (b < c ? b : c);
87a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
88a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
89a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float min(int a, int b, int c) {
90a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return a < b ? (a < c ? a : c) : (b < c ? b : c);
91a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
92a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
93a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float dist(float x1, float y1, float x2, float y2) {
94a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        final float x = (x2 - x1);
95a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        final float y = (y2 - y1);
9633253a4baa6279f81a73425b49dfb6abe5f5416eNeil Fuller        return (float) Math.hypot(x, y);
97a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
98a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
99a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) {
100a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        final float x = (x2 - x1);
101a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        final float y = (y2 - y1);
102a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        final float z = (z2 - z1);
103a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.sqrt(x * x + y * y + z * z);
104a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
105a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
106a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float mag(float a, float b) {
10733253a4baa6279f81a73425b49dfb6abe5f5416eNeil Fuller        return (float) Math.hypot(a, b);
108a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
109a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
110a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float mag(float a, float b, float c) {
111a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.sqrt(a * a + b * b + c * c);
112a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
113a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
114a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float sq(float v) {
115a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return v * v;
116a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
117a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
1189af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui    public static float dot(float v1x, float v1y, float v2x, float v2y) {
1199af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui        return v1x * v2x + v1y * v2y;
1209af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui    }
1219af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui
1229af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui    public static float cross(float v1x, float v1y, float v2x, float v2y) {
1239af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui        return v1x * v2y - v1y * v2x;
1249af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui    }
1259af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui
126a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float radians(float degrees) {
127a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return degrees * DEG_TO_RAD;
128a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
129a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
130a9d2d5ed2840bc3331e1a387b26efc44c6211623Romain Guy    public static float degrees(float radians) {
131a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return radians * RAD_TO_DEG;
132a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
133a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
134a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float acos(float value) {
135a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.acos(value);
136a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
137a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
138a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float asin(float value) {
139a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.asin(value);
140a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
141a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
142a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float atan(float value) {
143a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.atan(value);
144a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
145a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
146a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float atan2(float a, float b) {
147a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.atan2(a, b);
148a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
149a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
150a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float tan(float angle) {
151a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return (float) Math.tan(angle);
1529af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui    }
153a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy
154a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    public static float lerp(float start, float stop, float amount) {
155a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy        return start + (stop - start) * amount;
156a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy    }
1579af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui
1582b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette    /**
1592b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * Returns an interpolated angle in degrees between a set of start and end
1602b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * angles.
1612b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * <p>
1622b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * Unlike {@link #lerp(float, float, float)}, the direction and distance of
1632b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * travel is determined by the shortest angle between the start and end
1642b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * angles. For example, if the starting angle is 0 and the ending angle is
1652b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * 350, then the interpolated angle will be in the range [0,-10] rather
1662b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * than [0,350].
1672b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     *
1682b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * @param start the starting angle in degrees
1692b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * @param end the ending angle in degrees
1702b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * @param amount the position between start and end in the range [0,1]
1712b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     *               where 0 is the starting angle and 1 is the ending angle
1722b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     * @return the interpolated angle in degrees
1732b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette     */
1742b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette    public static float lerpDeg(float start, float end, float amount) {
1752b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette        final float minAngle = (((end - start) + 180) % 360) - 180;
1762b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette        return minAngle * amount + start;
1772b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette    }
1782b4dc1156695ae0a7498bf8fe7cd6b82941026d3Alan Viverette
179e85c5aa67ea27f930b573c0c6662ef6bd6314d54Romain Guy    public static float norm(float start, float stop, float value) {
180e85c5aa67ea27f930b573c0c6662ef6bd6314d54Romain Guy        return (value - start) / (stop - start);
181e85c5aa67ea27f930b573c0c6662ef6bd6314d54Romain Guy    }
1829af77a4ce22540726fbddd275f89e65fd1a1edf8ztenghui
183e85c5aa67ea27f930b573c0c6662ef6bd6314d54Romain Guy    public static float map(float minStart, float minStop, float maxStart, float maxStop, float value) {
184e85c5aa67ea27f930b573c0c6662ef6bd6314d54Romain Guy        return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
185e85c5aa67ea27f930b573c0c6662ef6bd6314d54Romain Guy    }
186e85c5aa67ea27f930b573c0c6662ef6bd6314d54Romain Guy
1871619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski    /**
1881619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski     * Returns the sum of the two parameters, or throws an exception if the resulting sum would
1891619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski     * cause an overflow or underflow.
1901619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski     * @throws IllegalArgumentException when overflow or underflow would occur.
1911619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski     */
1921619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski    public static int addOrThrow(int a, int b) throws IllegalArgumentException {
1931619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski        if (b == 0) {
1941619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski            return a;
1951619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski        }
1961619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski
1971619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski        if (b > 0 && a <= (Integer.MAX_VALUE - b)) {
1981619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski            return a + b;
1991619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski        }
2001619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski
2011619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski        if (b < 0 && a >= (Integer.MIN_VALUE - b)) {
2021619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski            return a + b;
2031619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski        }
2041619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski        throw new IllegalArgumentException("Addition overflow: " + a + " + " + b);
2051619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski    }
206a32d100b34d048cf0c765d8f31d87b81ab88d1ebRomain Guy}
207