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