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