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 #include <algorithm> 21 22 namespace android { 23 namespace uirenderer { 24 25 #define NON_ZERO_EPSILON (0.001f) 26 #define ALPHA_EPSILON (0.001f) 27 28 class MathUtils { 29 public: 30 /** 31 * Check for floats that are close enough to zero. 32 */ isZero(float value)33 inline static bool isZero(float value) { 34 return (value >= -NON_ZERO_EPSILON) && (value <= NON_ZERO_EPSILON); 35 } 36 isOne(float value)37 inline static bool isOne(float value) { 38 return areEqual(value, 1.0f); 39 } 40 isPositive(float value)41 inline static bool isPositive(float value) { return value >= NON_ZERO_EPSILON; } 42 43 /** 44 * Clamps alpha value, and snaps when very near 0 or 1 45 */ clampAlpha(float alpha)46 inline static float clampAlpha(float alpha) { 47 if (alpha <= ALPHA_EPSILON) { 48 return 0; 49 } else if (alpha >= (1 - ALPHA_EPSILON)) { 50 return 1; 51 } else { 52 return alpha; 53 } 54 } 55 56 /* 57 * Clamps positive tessellation scale values 58 */ clampTessellationScale(float scale)59 inline static float clampTessellationScale(float scale) { 60 const float MIN_SCALE = 0.0001; 61 const float MAX_SCALE = 1e10; 62 if (scale < MIN_SCALE) { 63 return MIN_SCALE; 64 } else if (scale > MAX_SCALE) { 65 return MAX_SCALE; 66 } 67 return scale; 68 } 69 70 /** 71 * Returns the number of points (beyond two, the start and end) needed to form a polygonal 72 * approximation of an arc, with a given threshold value. 73 */ divisionsNeededToApproximateArc(float radius,float angleInRads,float threshold)74 inline static int divisionsNeededToApproximateArc(float radius, float angleInRads, 75 float threshold) { 76 const float errConst = (-threshold / radius + 1); 77 const float targetCosVal = 2 * errConst * errConst - 1; 78 79 // needed divisions are rounded up from approximation 80 return (int)(ceilf(angleInRads / acos(targetCosVal) / 2)) * 2; 81 } 82 areEqual(float valueA,float valueB)83 inline static bool areEqual(float valueA, float valueB) { return isZero(valueA - valueB); } 84 85 template <typename T> clamp(T a,T minValue,T maxValue)86 static inline T clamp(T a, T minValue, T maxValue) { 87 return std::min(std::max(a, minValue), maxValue); 88 } 89 lerp(float v1,float v2,float t)90 inline static float lerp(float v1, float v2, float t) { return v1 + ((v2 - v1) * t); } 91 }; // class MathUtils 92 93 } /* namespace uirenderer */ 94 } /* namespace android */ 95 96 #endif /* MATHUTILS_H */ 97