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