DataTypes.h revision 73ca6243b31e225e9fd5b75a96cbc82d62557de6
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 __DataTypes_h__ 8#define __DataTypes_h__ 9 10#include <assert.h> 11#include <float.h> 12#include <limits.h> 13#include <math.h> 14#include <stdarg.h> 15#include <stdio.h> 16#include <stdint.h> 17#include <stdlib.h> 18#include <strings.h> 19#include <sys/types.h> 20 21extern bool AlmostEqualUlps(float A, float B); 22inline bool AlmostEqualUlps(double A, double B) { return AlmostEqualUlps((float) A, (float) B); } 23 24// FIXME: delete 25int UlpsDiff(float A, float B); 26 27const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON; 28const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON); 29 30inline bool approximately_zero(double x) { 31 32 return fabs(x) < FLT_EPSILON; 33} 34 35inline bool precisely_zero(double x) { 36 37 return fabs(x) < DBL_EPSILON; 38} 39 40inline bool approximately_zero(float x) { 41 42 return fabs(x) < FLT_EPSILON; 43} 44 45inline bool approximately_zero_squared(double x) { 46 return fabs(x) < FLT_EPSILON_SQUARED; 47} 48 49inline bool approximately_zero_sqrt(double x) { 50 return fabs(x) < FLT_EPSILON_SQRT; 51} 52 53inline bool approximately_equal(double x, double y) { 54 return approximately_zero(x - y); 55} 56 57inline bool approximately_equal_squared(double x, double y) { 58 return approximately_equal(x, y); 59} 60 61inline bool approximately_greater(double x, double y) { 62 return approximately_equal(x, y) ? false : x > y; 63} 64 65inline bool approximately_lesser(double x, double y) { 66 return approximately_equal(x, y) ? false : x < y; 67} 68 69inline double approximately_pin(double x) { 70 return approximately_zero(x) ? 0 : x; 71} 72 73inline float approximately_pin(float x) { 74 return approximately_zero(x) ? 0 : x; 75} 76 77inline bool approximately_greater_than_one(double x) { 78 return x > 1 - FLT_EPSILON; 79} 80 81inline bool precisely_greater_than_one(double x) { 82 return x > 1 - DBL_EPSILON; 83} 84 85inline bool approximately_less_than_zero(double x) { 86 return x < FLT_EPSILON; 87} 88 89inline bool precisely_less_than_zero(double x) { 90 return x < DBL_EPSILON; 91} 92 93inline bool approximately_negative(double x) { 94 return x < FLT_EPSILON; 95} 96 97inline bool precisely_negative(double x) { 98 return x < DBL_EPSILON; 99} 100 101inline bool approximately_one_or_less(double x) { 102 return x < 1 + FLT_EPSILON; 103} 104 105inline bool approximately_positive(double x) { 106 return x > -FLT_EPSILON; 107} 108 109inline bool approximately_positive_squared(double x) { 110 return x > -(FLT_EPSILON_SQUARED); 111} 112 113inline bool approximately_zero_or_more(double x) { 114 return x > -FLT_EPSILON; 115} 116 117inline bool approximately_between(double a, double b, double c) { 118 assert(a <= c); 119 return a <= c ? approximately_negative(a - b) && approximately_negative(b - c) 120 : approximately_negative(b - a) && approximately_negative(c - b); 121} 122 123// returns true if (a <= b <= c) || (a >= b >= c) 124inline bool between(double a, double b, double c) { 125 assert(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)); 126 return (a - b) * (c - b) <= 0; 127} 128 129struct _Point { 130 double x; 131 double y; 132 133 friend _Point operator-(const _Point& a, const _Point& b) { 134 _Point v = {a.x - b.x, a.y - b.y}; 135 return v; 136 } 137 138 void operator-=(const _Point& v) { 139 x -= v.x; 140 y -= v.y; 141 } 142 143 friend bool operator==(const _Point& a, const _Point& b) { 144 return a.x == b.x && a.y == b.y; 145 } 146 147 friend bool operator!=(const _Point& a, const _Point& b) { 148 return a.x!= b.x || a.y != b.y; 149 } 150 151 // note: this can not be implemented with 152 // return approximately_equal(a.y, y) && approximately_equal(a.x, x); 153 // because that will not take the magnitude of the values 154 bool approximatelyEqual(const _Point& a) const { 155 return AlmostEqualUlps((float) x, (float) a.x) 156 && AlmostEqualUlps((float) y, (float) a.y); 157 } 158 159 double dot(const _Point& a) { 160 return x * a.x + y * a.y; 161 } 162}; 163 164typedef _Point _Line[2]; 165typedef _Point Quadratic[3]; 166typedef _Point Cubic[4]; 167 168struct _Rect { 169 double left; 170 double top; 171 double right; 172 double bottom; 173 174 void add(const _Point& pt) { 175 if (left > pt.x) { 176 left = pt.x; 177 } 178 if (top > pt.y) { 179 top = pt.y; 180 } 181 if (right < pt.x) { 182 right = pt.x; 183 } 184 if (bottom < pt.y) { 185 bottom = pt.y; 186 } 187 } 188 189 // FIXME: used by debugging only ? 190 bool contains(const _Point& pt) { 191 return approximately_between(left, pt.x, right) 192 && approximately_between(top, pt.y, bottom); 193 } 194 195 void set(const _Point& pt) { 196 left = right = pt.x; 197 top = bottom = pt.y; 198 } 199 200 void setBounds(const _Line& line) { 201 set(line[0]); 202 add(line[1]); 203 } 204 205 void setBounds(const Cubic& ); 206 void setBounds(const Quadratic& ); 207 void setRawBounds(const Cubic& ); 208 void setRawBounds(const Quadratic& ); 209}; 210 211struct CubicPair { 212 const Cubic& first() const { return (const Cubic&) pts[0]; } 213 const Cubic& second() const { return (const Cubic&) pts[3]; } 214 _Point pts[7]; 215}; 216 217struct QuadraticPair { 218 const Quadratic& first() const { return (const Quadratic&) pts[0]; } 219 const Quadratic& second() const { return (const Quadratic&) pts[2]; } 220 _Point pts[5]; 221}; 222 223#endif // __DataTypes_h__ 224