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