• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base;
6 
7 /** Contains various math utilities used throughout Chrome Mobile. */
8 public class MathUtils {
9     /** A minimum difference to use when comparing floats for equality. */
10     public static final float EPSILON = 0.001f;
11 
MathUtils()12     private MathUtils() {}
13 
14     /**
15      * Returns the passed in value if it resides within the specified range (inclusive).  If not,
16      * it will return the closest boundary from the range.  The ordering of the boundary values does
17      * not matter.
18      *
19      * @param value The value to be compared against the range.
20      * @param a First boundary range value.
21      * @param b Second boundary range value.
22      * @return The passed in value if it is within the range, otherwise the closest boundary value.
23      */
clamp(int value, int a, int b)24     public static int clamp(int value, int a, int b) {
25         int min = (a > b) ? b : a;
26         int max = (a > b) ? a : b;
27         if (value < min) {
28             value = min;
29         } else if (value > max) {
30             value = max;
31         }
32         return value;
33     }
34 
35     /**
36      * Returns the passed in value if it resides within the specified range (inclusive).  If not,
37      * it will return the closest boundary from the range.  The ordering of the boundary values does
38      * not matter.
39      *
40      * @param value The value to be compared against the range.
41      * @param a First boundary range value.
42      * @param b Second boundary range value.
43      * @return The passed in value if it is within the range, otherwise the closest boundary value.
44      */
clamp(long value, long a, long b)45     public static long clamp(long value, long a, long b) {
46         long min = (a > b) ? b : a;
47         long max = (a > b) ? a : b;
48         if (value < min) {
49             value = min;
50         } else if (value > max) {
51             value = max;
52         }
53         return value;
54     }
55 
56     /**
57      * Returns the passed in value if it resides within the specified range (inclusive).  If not,
58      * it will return the closest boundary from the range.  The ordering of the boundary values does
59      * not matter.
60      *
61      * @param value The value to be compared against the range.
62      * @param a First boundary range value.
63      * @param b Second boundary range value.
64      * @return The passed in value if it is within the range, otherwise the closest boundary value.
65      */
clamp(float value, float a, float b)66     public static float clamp(float value, float a, float b) {
67         float min = (a > b) ? b : a;
68         float max = (a > b) ? a : b;
69         if (value < min) {
70             value = min;
71         } else if (value > max) {
72             value = max;
73         }
74         return value;
75     }
76 
77     /**
78      * Computes a%b that is positive. Note that result of % operation is not always positive.
79      * @return a%b >= 0 ? a%b : a%b + b
80      */
positiveModulo(int a, int b)81     public static int positiveModulo(int a, int b) {
82         int mod = a % b;
83         return mod >= 0 ? mod : mod + b;
84     }
85 
86     /**
87      * Moves {@code value} forward to {@code target} based on {@code speed}.
88      * @param value  The current value.
89      * @param target The target value.
90      * @param speed  How far to move {@code value} to {@code target}.  0 doesn't move it at all.  1
91      *               moves it to {@code target}.
92      * @return       The new interpolated value.
93      */
interpolate(float value, float target, float speed)94     public static float interpolate(float value, float target, float speed) {
95         return (value + (target - value) * speed);
96     }
97 
98     /**
99      * Smooth a value between 0 and 1.
100      * @param t The value to smooth.
101      * @return  The smoothed value between 0 and 1.
102      */
smoothstep(float t)103     public static float smoothstep(float t) {
104         return t * t * (3.0f - 2.0f * t);
105     }
106 
107     /**
108      * Scales the provided dimension such that it is just large enough to fit
109      * the target width and height.
110      *
111      * @param dimensions The dimensions to scale
112      * @param targetWidth The target width
113      * @param targetHeight The target height
114      * @return The scale factor applied to dimensions
115      */
scaleToFitTargetSize(int[] dimensions, int targetWidth, int targetHeight)116     public static float scaleToFitTargetSize(int[] dimensions, int targetWidth, int targetHeight) {
117         if (dimensions.length < 2 || dimensions[0] <= 0 || dimensions[1] <= 0) {
118             throw new IllegalArgumentException(
119                     "Expected dimensions to have length >= 2 && dimensions[0] > 0 && "
120                             + "dimensions[1] > 0");
121         }
122         float scale =
123                 Math.max((float) targetWidth / dimensions[0], (float) targetHeight / dimensions[1]);
124         dimensions[0] = (int) (dimensions[0] * scale);
125         dimensions[1] = (int) (dimensions[1] * scale);
126         return scale;
127     }
128 
129     /**
130      * Flips {@code value} iff {@code flipSign} is {@code true}.
131      * @param value    The value to flip.
132      * @param flipSign Whether or not to flip the value.
133      * @return         {@code value} iff {@code flipSign} is {@code false}, otherwise negative
134      *                 {@code value}.
135      */
flipSignIf(int value, boolean flipSign)136     public static int flipSignIf(int value, boolean flipSign) {
137         return flipSign ? -value : value;
138     }
139 
140     /**
141      * Flips {@code value} iff {@code flipSign} is {@code true}.
142      * @param value    The value to flip.
143      * @param flipSign Whether or not to flip the value.
144      * @return         {@code value} iff {@code flipSign} is {@code false}, otherwise negative
145      *                 {@code value}.
146      */
flipSignIf(float value, boolean flipSign)147     public static float flipSignIf(float value, boolean flipSign) {
148         return flipSign ? -value : value;
149     }
150 
151     /**
152      * Determine if two floats are equal.
153      * @param f1 The first float to compare.
154      * @param f2 The second float to compare.
155      * @return True if the floats are equal.
156      */
areFloatsEqual(float f1, float f2)157     public static boolean areFloatsEqual(float f1, float f2) {
158         return Math.abs(f1 - f2) < MathUtils.EPSILON;
159     }
160 
161     /**
162      * Compute the distance between two points.
163      * @param x1 X of point 1.
164      * @param y1 Y of point 1.
165      * @param x2 X of point 2.
166      * @param y2 Y of point 2.
167      * @return The distance between the two points.
168      */
distance(float x1, float y1, float x2, float y2)169     public static float distance(float x1, float y1, float x2, float y2) {
170         float xDist = x2 - x1;
171         float yDist = y2 - y1;
172         return (float) Math.sqrt(xDist * xDist + yDist * yDist);
173     }
174 
175     /**
176      * Compute the distance given two coordinate vectors
177      */
distance(float distanceX, float distanceY)178     public static float distance(float distanceX, float distanceY) {
179         return (float) Math.sqrt(distanceX * distanceX + distanceY * distanceY);
180     }
181 
182     /**
183      * Maps {@code value} in [{@code fromStart}, {@code fromStop}] to
184      * [{@code toStart}, {@code toStop}].
185      *
186      * @param value A number in [{@code fromStart}, {@code fromStop}].
187      * @param fromStart Lower range of {@code value}.
188      * @param fromStop Upper range of {@code value}.
189      * @param toStart Lower range of mapped value.
190      * @param toStop Upper range of mapped value.
191      * @return mapped value.
192      */
map( float value, float fromStart, float fromStop, float toStart, float toStop)193     public static float map(
194             float value, float fromStart, float fromStop, float toStart, float toStop) {
195         return toStart + (toStop - toStart) * ((value - fromStart) / (fromStop - fromStart));
196     }
197 
198     /**
199      * Round the given value to two decimal places.
200      *
201      * @param value double The value to round.
202      * @return double The value rounded to two decimal places.
203      */
roundTwoDecimalPlaces(double value)204     public static double roundTwoDecimalPlaces(double value) {
205         return (double) Math.round(value * 100) / 100;
206     }
207 }
208