DataTypes.h revision 05c4bad470722bc4e5e6ae3d79aa8bcf9e732f06
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 void operator-=(const _Point& v) { 144 x -= v.x; 145 y -= v.y; 146 } 147 148 void operator/=(const double s) { 149 x /= s; 150 y /= s; 151 } 152 153 void operator*=(const double s) { 154 x *= s; 155 y *= s; 156 } 157 158 friend bool operator==(const _Point& a, const _Point& b) { 159 return a.x == b.x && a.y == b.y; 160 } 161 162 friend bool operator!=(const _Point& a, const _Point& b) { 163 return a.x!= b.x || a.y != b.y; 164 } 165 166 // note: this can not be implemented with 167 // return approximately_equal(a.y, y) && approximately_equal(a.x, x); 168 // because that will not take the magnitude of the values 169 bool approximatelyEqual(const _Point& a) const { 170 return AlmostEqualUlps((float) x, (float) a.x) 171 && AlmostEqualUlps((float) y, (float) a.y); 172 } 173 174 double dot(const _Point& a) { 175 return x * a.x + y * a.y; 176 } 177}; 178 179typedef _Point _Line[2]; 180typedef _Point Quadratic[3]; 181typedef _Point Cubic[4]; 182 183struct _Rect { 184 double left; 185 double top; 186 double right; 187 double bottom; 188 189 void add(const _Point& pt) { 190 if (left > pt.x) { 191 left = pt.x; 192 } 193 if (top > pt.y) { 194 top = pt.y; 195 } 196 if (right < pt.x) { 197 right = pt.x; 198 } 199 if (bottom < pt.y) { 200 bottom = pt.y; 201 } 202 } 203 204 // FIXME: used by debugging only ? 205 bool contains(const _Point& pt) const { 206 return approximately_between(left, pt.x, right) 207 && approximately_between(top, pt.y, bottom); 208 } 209 210 bool intersects(_Rect& r) const { 211 assert(left < right); 212 assert(top < bottom); 213 assert(r.left < r.right); 214 assert(r.top < r.bottom); 215 return r.left < right && left < r.right && r.top < bottom && top < r.bottom; 216 } 217 218 void set(const _Point& pt) { 219 left = right = pt.x; 220 top = bottom = pt.y; 221 } 222 223 void setBounds(const _Line& line) { 224 set(line[0]); 225 add(line[1]); 226 } 227 228 void setBounds(const Cubic& ); 229 void setBounds(const Quadratic& ); 230 void setRawBounds(const Cubic& ); 231 void setRawBounds(const Quadratic& ); 232}; 233 234struct CubicPair { 235 const Cubic& first() const { return (const Cubic&) pts[0]; } 236 const Cubic& second() const { return (const Cubic&) pts[3]; } 237 _Point pts[7]; 238}; 239 240struct QuadraticPair { 241 const Quadratic& first() const { return (const Quadratic&) pts[0]; } 242 const Quadratic& second() const { return (const Quadratic&) pts[2]; } 243 _Point pts[5]; 244}; 245 246#endif // __DataTypes_h__ 247