Home | History | Annotate | Download | only in utils
      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      */
     32     inline static bool isZero(float value) {
     33         return (value >= -NON_ZERO_EPSILON) && (value <= NON_ZERO_EPSILON);
     34     }
     35 
     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      */
     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      */
     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      */
     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 
     80     inline static bool areEqual(float valueA, float valueB) {
     81         return isZero(valueA - valueB);
     82     }
     83 
     84     template<typename T>
     85     static inline T max(T a, T b) {
     86         return a > b ? a : b;
     87     }
     88 
     89     template<typename T>
     90     static inline T min(T a, T b) {
     91         return a < b ? a : b;
     92     }
     93 
     94     template<typename T>
     95     static inline T clamp(T a, T minValue, T maxValue) {
     96         return min(max(a, minValue), maxValue);
     97     }
     98 
     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