1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef MATHUTILS_H 17 #define MATHUTILS_H 18 19 #include <math.h> 20 21 namespace android { 22 namespace uirenderer { 23 24 #define NON_ZERO_EPSILON (0.001f) 25 #define ALPHA_EPSILON (0.001f) 26 27 class MathUtils { 28 public: 29 /** 30 * Check for floats that are close enough to zero. 31 */ isZero(float value)32 inline static bool isZero(float value) { 33 return (value >= -NON_ZERO_EPSILON) && (value <= NON_ZERO_EPSILON); 34 } 35 isPositive(float value)36 inline static bool isPositive(float value) { 37 return value >= NON_ZERO_EPSILON; 38 } 39 40 /** 41 * Clamps alpha value, and snaps when very near 0 or 1 42 */ clampAlpha(float alpha)43 inline static float clampAlpha(float alpha) { 44 if (alpha <= ALPHA_EPSILON) { 45 return 0; 46 } else if (alpha >= (1 - ALPHA_EPSILON)) { 47 return 1; 48 } else { 49 return alpha; 50 } 51 } 52 53 /* 54 * Clamps positive tessellation scale values 55 */ clampTessellationScale(float scale)56 inline static float clampTessellationScale(float scale) { 57 const float MIN_SCALE = 0.0001; 58 const float MAX_SCALE = 1e10; 59 if (scale < MIN_SCALE) { 60 return MIN_SCALE; 61 } else if (scale > MAX_SCALE) { 62 return MAX_SCALE; 63 } 64 return scale; 65 } 66 67 /** 68 * Returns the number of points (beyond two, the start and end) needed to form a polygonal 69 * approximation of an arc, with a given threshold value. 70 */ divisionsNeededToApproximateArc(float radius,float angleInRads,float threshold)71 inline static int divisionsNeededToApproximateArc(float radius, 72 float angleInRads, float threshold) { 73 const float errConst = (-threshold / radius + 1); 74 const float targetCosVal = 2 * errConst * errConst - 1; 75 76 // needed divisions are rounded up from approximation 77 return (int)(ceilf(angleInRads / acos(targetCosVal)/2)) * 2; 78 } 79 areEqual(float valueA,float valueB)80 inline static bool areEqual(float valueA, float valueB) { 81 return isZero(valueA - valueB); 82 } 83 84 template<typename T> max(T a,T b)85 static inline T max(T a, T b) { 86 return a > b ? a : b; 87 } 88 89 template<typename T> min(T a,T b)90 static inline T min(T a, T b) { 91 return a < b ? a : b; 92 } 93 94 template<typename T> clamp(T a,T minValue,T maxValue)95 static inline T clamp(T a, T minValue, T maxValue) { 96 return min(max(a, minValue), maxValue); 97 } 98 lerp(float v1,float v2,float t)99 inline static float lerp(float v1, float v2, float t) { 100 return v1 + ((v2 - v1) * t); 101 } 102 }; // class MathUtils 103 104 } /* namespace uirenderer */ 105 } /* namespace android */ 106 107 #endif /* MATHUTILS_H */ 108