OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2012 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 #ifndef SkPathOpsTypes_DEFINED |
| 8 #define SkPathOpsTypes_DEFINED |
| 9 |
| 10 #include <float.h> // for FLT_EPSILON |
| 11 #include <math.h> // for fabs, sqrt |
| 12 |
| 13 #include "SkFloatingPoint.h" |
| 14 #include "SkPathOps.h" |
| 15 #include "SkPathOpsDebug.h" |
| 16 #include "SkScalar.h" |
| 17 |
| 18 // FIXME: move these into SkTypes.h |
| 19 template <typename T> inline T SkTMax(T a, T b) { |
| 20 if (a < b) |
| 21 a = b; |
| 22 return a; |
| 23 } |
| 24 |
| 25 template <typename T> inline T SkTMin(T a, T b) { |
| 26 if (a > b) |
| 27 a = b; |
| 28 return a; |
| 29 } |
| 30 |
| 31 // FIXME: move this into SkFloatingPoint.h |
| 32 #define sk_double_isnan(a) sk_float_isnan(a) |
| 33 |
| 34 enum SkPathOpsMask { |
| 35 kWinding_PathOpsMask = -1, |
| 36 kNo_PathOpsMask = 0, |
| 37 kEvenOdd_PathOpsMask = 1 |
| 38 }; |
| 39 |
| 40 extern bool AlmostEqualUlps(float A, float B); |
| 41 inline bool AlmostEqualUlps(double A, double B) { |
| 42 return AlmostEqualUlps(SkDoubleToScalar(A), SkDoubleToScalar(B)); |
| 43 } |
| 44 |
| 45 // FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23) |
| 46 // DBL_EPSILON == 2.22045e-16 |
| 47 const double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON; |
| 48 const double FLT_EPSILON_HALF = FLT_EPSILON / 2; |
| 49 const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON; |
| 50 const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON); |
| 51 const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON; |
| 52 const double DBL_EPSILON_ERR = DBL_EPSILON * 4; // FIXME: tune -- allow a few b
its of error |
| 53 const double ROUGH_EPSILON = FLT_EPSILON * 64; |
| 54 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256; |
| 55 |
| 56 inline bool approximately_zero(double x) { |
| 57 return fabs(x) < FLT_EPSILON; |
| 58 } |
| 59 |
| 60 inline bool precisely_zero(double x) { |
| 61 return fabs(x) < DBL_EPSILON_ERR; |
| 62 } |
| 63 |
| 64 inline bool approximately_zero(float x) { |
| 65 return fabs(x) < FLT_EPSILON; |
| 66 } |
| 67 |
| 68 inline bool approximately_zero_cubed(double x) { |
| 69 return fabs(x) < FLT_EPSILON_CUBED; |
| 70 } |
| 71 |
| 72 inline bool approximately_zero_half(double x) { |
| 73 return fabs(x) < FLT_EPSILON_HALF; |
| 74 } |
| 75 |
| 76 inline bool approximately_zero_squared(double x) { |
| 77 return fabs(x) < FLT_EPSILON_SQUARED; |
| 78 } |
| 79 |
| 80 inline bool approximately_zero_sqrt(double x) { |
| 81 return fabs(x) < FLT_EPSILON_SQRT; |
| 82 } |
| 83 |
| 84 inline bool approximately_zero_inverse(double x) { |
| 85 return fabs(x) > FLT_EPSILON_INVERSE; |
| 86 } |
| 87 |
| 88 // OPTIMIZATION: if called multiple times with the same denom, we want to pass 1
/y instead |
| 89 inline bool approximately_zero_when_compared_to(double x, double y) { |
| 90 return x == 0 || fabs(x / y) < FLT_EPSILON; |
| 91 } |
| 92 |
| 93 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger
and smaller) use |
| 94 // AlmostEqualUlps instead. |
| 95 inline bool approximately_equal(double x, double y) { |
| 96 return approximately_zero(x - y); |
| 97 } |
| 98 |
| 99 inline bool precisely_equal(double x, double y) { |
| 100 return precisely_zero(x - y); |
| 101 } |
| 102 |
| 103 inline bool approximately_equal_half(double x, double y) { |
| 104 return approximately_zero_half(x - y); |
| 105 } |
| 106 |
| 107 inline bool approximately_equal_squared(double x, double y) { |
| 108 return approximately_equal(x, y); |
| 109 } |
| 110 |
| 111 inline bool approximately_greater(double x, double y) { |
| 112 return x - FLT_EPSILON >= y; |
| 113 } |
| 114 |
| 115 inline bool approximately_greater_or_equal(double x, double y) { |
| 116 return x + FLT_EPSILON > y; |
| 117 } |
| 118 |
| 119 inline bool approximately_lesser(double x, double y) { |
| 120 return x + FLT_EPSILON <= y; |
| 121 } |
| 122 |
| 123 inline bool approximately_lesser_or_equal(double x, double y) { |
| 124 return x - FLT_EPSILON < y; |
| 125 } |
| 126 |
| 127 inline double approximately_pin(double x) { |
| 128 return approximately_zero(x) ? 0 : x; |
| 129 } |
| 130 |
| 131 inline float approximately_pin(float x) { |
| 132 return approximately_zero(x) ? 0 : x; |
| 133 } |
| 134 |
| 135 inline bool approximately_greater_than_one(double x) { |
| 136 return x > 1 - FLT_EPSILON; |
| 137 } |
| 138 |
| 139 inline bool precisely_greater_than_one(double x) { |
| 140 return x > 1 - DBL_EPSILON_ERR; |
| 141 } |
| 142 |
| 143 inline bool approximately_less_than_zero(double x) { |
| 144 return x < FLT_EPSILON; |
| 145 } |
| 146 |
| 147 inline bool precisely_less_than_zero(double x) { |
| 148 return x < DBL_EPSILON_ERR; |
| 149 } |
| 150 |
| 151 inline bool approximately_negative(double x) { |
| 152 return x < FLT_EPSILON; |
| 153 } |
| 154 |
| 155 inline bool precisely_negative(double x) { |
| 156 return x < DBL_EPSILON_ERR; |
| 157 } |
| 158 |
| 159 inline bool approximately_one_or_less(double x) { |
| 160 return x < 1 + FLT_EPSILON; |
| 161 } |
| 162 |
| 163 inline bool approximately_positive(double x) { |
| 164 return x > -FLT_EPSILON; |
| 165 } |
| 166 |
| 167 inline bool approximately_positive_squared(double x) { |
| 168 return x > -(FLT_EPSILON_SQUARED); |
| 169 } |
| 170 |
| 171 inline bool approximately_zero_or_more(double x) { |
| 172 return x > -FLT_EPSILON; |
| 173 } |
| 174 |
| 175 inline bool approximately_between(double a, double b, double c) { |
| 176 return a <= c ? approximately_negative(a - b) && approximately_negative(b -
c) |
| 177 : approximately_negative(b - a) && approximately_negative(c - b); |
| 178 } |
| 179 |
| 180 // returns true if (a <= b <= c) || (a >= b >= c) |
| 181 inline bool between(double a, double b, double c) { |
| 182 SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <=
0)); |
| 183 return (a - b) * (c - b) <= 0; |
| 184 } |
| 185 |
| 186 inline bool more_roughly_equal(double x, double y) { |
| 187 return fabs(x - y) < MORE_ROUGH_EPSILON; |
| 188 } |
| 189 |
| 190 inline bool roughly_equal(double x, double y) { |
| 191 return fabs(x - y) < ROUGH_EPSILON; |
| 192 } |
| 193 |
| 194 struct SkDPoint; |
| 195 struct SkDVector; |
| 196 struct SkDLine; |
| 197 struct SkDQuad; |
| 198 struct SkDTriangle; |
| 199 struct SkDCubic; |
| 200 struct SkDRect; |
| 201 |
| 202 inline double SkDInterp(double A, double B, double t) { |
| 203 return A + (B - A) * t; |
| 204 } |
| 205 |
| 206 double SkDCubeRoot(double x); |
| 207 |
| 208 /* Returns -1 if negative, 0 if zero, 1 if positive |
| 209 */ |
| 210 inline int SkDSign(double x) { |
| 211 return (x > 0) - (x < 0); |
| 212 } |
| 213 |
| 214 /* Returns 0 if negative, 1 if zero, 2 if positive |
| 215 */ |
| 216 inline int SKDSide(double x) { |
| 217 return (x > 0) + (x >= 0); |
| 218 } |
| 219 |
| 220 /* Returns 1 if negative, 2 if zero, 4 if positive |
| 221 */ |
| 222 inline int SkDSideBit(double x) { |
| 223 return 1 << SKDSide(x); |
| 224 } |
| 225 |
| 226 #endif |
OLD | NEW |