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