Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: experimental/Intersection/DataTypes.h

Issue 867213004: remove prototype pathops code (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « experimental/Intersection/CurveUtilities.h ('k') | experimental/Intersection/DataTypes.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 <float.h> // for FLT_EPSILON
11 #include <math.h> // for fabs, sqrt
12
13 #include "SkPoint.h"
14
15 #define FORCE_RELEASE 0 // set force release to 1 for multiple thread -- no deb ugging
16 #define ONE_OFF_DEBUG 1
17 #define ONE_OFF_DEBUG_MATHEMATICA 0
18
19 // FIXME: move these into SkTypes.h
20 template <typename T> inline T SkTMax(T a, T b) {
21 if (a < b)
22 a = b;
23 return a;
24 }
25
26 template <typename T> inline T SkTMin(T a, T b) {
27 if (a > b)
28 a = b;
29 return a;
30 }
31
32 extern bool AlmostEqualUlps(float A, float B);
33 inline bool AlmostEqualUlps(double A, double B) { return AlmostEqualUlps((float) A, (float) B); }
34
35 // FIXME: delete
36 int UlpsDiff(float A, float B);
37
38 // FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23)
39 // DBL_EPSILON == 2.22045e-16
40 const double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON;
41 const double FLT_EPSILON_HALF = FLT_EPSILON / 2;
42 const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON;
43 const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON);
44 const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON;
45 const double DBL_EPSILON_ERR = DBL_EPSILON * 4; // tune -- allow a few bits of e rror
46 const double ROUGH_EPSILON = FLT_EPSILON * 64;
47 const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256;
48
49 inline bool approximately_zero(double x) {
50 return fabs(x) < FLT_EPSILON;
51 }
52
53 inline bool precisely_zero(double x) {
54 return fabs(x) < DBL_EPSILON_ERR;
55 }
56
57 inline bool approximately_zero(float x) {
58 return fabs(x) < FLT_EPSILON;
59 }
60
61 inline bool approximately_zero_cubed(double x) {
62 return fabs(x) < FLT_EPSILON_CUBED;
63 }
64
65 inline bool approximately_zero_half(double x) {
66 return fabs(x) < FLT_EPSILON_HALF;
67 }
68
69 inline bool approximately_zero_squared(double x) {
70 return fabs(x) < FLT_EPSILON_SQUARED;
71 }
72
73 inline bool approximately_zero_sqrt(double x) {
74 return fabs(x) < FLT_EPSILON_SQRT;
75 }
76
77 inline bool approximately_zero_inverse(double x) {
78 return fabs(x) > FLT_EPSILON_INVERSE;
79 }
80
81 // FIXME: if called multiple times with the same denom, we want to pass 1/y inst ead
82 inline bool approximately_zero_when_compared_to(double x, double y) {
83 return x == 0 || fabs(x / y) < FLT_EPSILON;
84 }
85
86 // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use
87 // AlmostEqualUlps instead.
88 inline bool approximately_equal(double x, double y) {
89 #if 1
90 return approximately_zero(x - y);
91 #else
92 // see http://visualstudiomagazine.com/blogs/tool-tracker/2011/11/compare-floati ng-point-numbers.aspx
93 // this allows very small (e.g. degenerate) values to compare unequally, but in this case,
94 // AlmostEqualUlps should be used instead.
95 if (x == y) {
96 return true;
97 }
98 double absY = fabs(y);
99 if (x == 0) {
100 return absY < FLT_EPSILON;
101 }
102 double absX = fabs(x);
103 if (y == 0) {
104 return absX < FLT_EPSILON;
105 }
106 return fabs(x - y) < (absX > absY ? absX : absY) * FLT_EPSILON;
107 #endif
108 }
109
110 inline bool precisely_equal(double x, double y) {
111 return precisely_zero(x - y);
112 }
113
114 inline bool approximately_equal_half(double x, double y) {
115 return approximately_zero_half(x - y);
116 }
117
118 inline bool approximately_equal_squared(double x, double y) {
119 return approximately_equal(x, y);
120 }
121
122 inline bool approximately_greater(double x, double y) {
123 return x - FLT_EPSILON >= y;
124 }
125
126 inline bool approximately_greater_or_equal(double x, double y) {
127 return x + FLT_EPSILON > y;
128 }
129
130 inline bool approximately_lesser(double x, double y) {
131 return x + FLT_EPSILON <= y;
132 }
133
134 inline bool approximately_lesser_or_equal(double x, double y) {
135 return x - FLT_EPSILON < y;
136 }
137
138 inline double approximately_pin(double x) {
139 return approximately_zero(x) ? 0 : x;
140 }
141
142 inline float approximately_pin(float x) {
143 return approximately_zero(x) ? 0 : x;
144 }
145
146 inline bool approximately_greater_than_one(double x) {
147 return x > 1 - FLT_EPSILON;
148 }
149
150 inline bool precisely_greater_than_one(double x) {
151 return x > 1 - DBL_EPSILON_ERR;
152 }
153
154 inline bool approximately_less_than_zero(double x) {
155 return x < FLT_EPSILON;
156 }
157
158 inline bool precisely_less_than_zero(double x) {
159 return x < DBL_EPSILON_ERR;
160 }
161
162 inline bool approximately_negative(double x) {
163 return x < FLT_EPSILON;
164 }
165
166 inline bool precisely_negative(double x) {
167 return x < DBL_EPSILON_ERR;
168 }
169
170 inline bool approximately_one_or_less(double x) {
171 return x < 1 + FLT_EPSILON;
172 }
173
174 inline bool approximately_positive(double x) {
175 return x > -FLT_EPSILON;
176 }
177
178 inline bool approximately_positive_squared(double x) {
179 return x > -(FLT_EPSILON_SQUARED);
180 }
181
182 inline bool approximately_zero_or_more(double x) {
183 return x > -FLT_EPSILON;
184 }
185
186 inline bool approximately_between(double a, double b, double c) {
187 return a <= c ? approximately_negative(a - b) && approximately_negative(b - c)
188 : approximately_negative(b - a) && approximately_negative(c - b);
189 }
190
191 // returns true if (a <= b <= c) || (a >= b >= c)
192 inline bool between(double a, double b, double c) {
193 SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0));
194 return (a - b) * (c - b) <= 0;
195 }
196
197 inline bool more_roughly_equal(double x, double y) {
198 return fabs(x - y) < MORE_ROUGH_EPSILON;
199 }
200
201 inline bool roughly_equal(double x, double y) {
202 return fabs(x - y) < ROUGH_EPSILON;
203 }
204
205 struct _Point;
206
207 struct _Vector {
208 double x;
209 double y;
210
211 friend _Point operator+(const _Point& a, const _Vector& b);
212
213 void operator+=(const _Vector& v) {
214 x += v.x;
215 y += v.y;
216 }
217
218 void operator-=(const _Vector& v) {
219 x -= v.x;
220 y -= v.y;
221 }
222
223 void operator/=(const double s) {
224 x /= s;
225 y /= s;
226 }
227
228 void operator*=(const double s) {
229 x *= s;
230 y *= s;
231 }
232
233 double cross(const _Vector& a) const {
234 return x * a.y - y * a.x;
235 }
236
237 double dot(const _Vector& a) const {
238 return x * a.x + y * a.y;
239 }
240
241 double length() const {
242 return sqrt(lengthSquared());
243 }
244
245 double lengthSquared() const {
246 return x * x + y * y;
247 }
248
249 SkVector asSkVector() const {
250 SkVector v = {SkDoubleToScalar(x), SkDoubleToScalar(y)};
251 return v;
252 }
253 };
254
255 struct _Point {
256 double x;
257 double y;
258
259 friend _Vector operator-(const _Point& a, const _Point& b);
260
261 void operator+=(const _Vector& v) {
262 x += v.x;
263 y += v.y;
264 }
265
266 void operator-=(const _Vector& v) {
267 x -= v.x;
268 y -= v.y;
269 }
270
271 friend bool operator==(const _Point& a, const _Point& b) {
272 return a.x == b.x && a.y == b.y;
273 }
274
275 friend bool operator!=(const _Point& a, const _Point& b) {
276 return a.x != b.x || a.y != b.y;
277 }
278
279 // note: this can not be implemented with
280 // return approximately_equal(a.y, y) && approximately_equal(a.x, x);
281 // because that will not take the magnitude of the values
282 bool approximatelyEqual(const _Point& a) const {
283 double denom = SkTMax(fabs(x), SkTMax(fabs(y), SkTMax(fabs(a.x), fabs(a. y))));
284 if (denom == 0) {
285 return true;
286 }
287 double inv = 1 / denom;
288 return approximately_equal(x * inv, a.x * inv) && approximately_equal(y * inv, a.y * inv);
289 }
290
291 bool approximatelyEqual(const SkPoint& a) const {
292 double denom = SkTMax(fabs(x), SkTMax(fabs(y), SkTMax(fabs(a.fX), fabs(a .fY))));
293 if (denom == 0) {
294 return true;
295 }
296 double inv = 1 / denom;
297 return approximately_equal(x * inv, a.fX * inv) && approximately_equal(y * inv, a.fY * inv);
298 }
299
300 bool approximatelyEqualHalf(const _Point& a) const {
301 double denom = SkTMax(fabs(x), SkTMax(fabs(y), SkTMax(fabs(a.x), fabs(a. y))));
302 if (denom == 0) {
303 return true;
304 }
305 double inv = 1 / denom;
306 return approximately_equal_half(x * inv, a.x * inv)
307 && approximately_equal_half(y * inv, a.y * inv);
308 }
309
310 bool approximatelyZero() const {
311 return approximately_zero(x) && approximately_zero(y);
312 }
313
314 SkPoint asSkPoint() const {
315 SkPoint pt = {SkDoubleToScalar(x), SkDoubleToScalar(y)};
316 return pt;
317 }
318
319 double distance(const _Point& a) const {
320 _Vector temp = *this - a;
321 return temp.length();
322 }
323
324 double distanceSquared(const _Point& a) const {
325 _Vector temp = *this - a;
326 return temp.lengthSquared();
327 }
328
329 double moreRoughlyEqual(const _Point& a) const {
330 return more_roughly_equal(a.y, y) && more_roughly_equal(a.x, x);
331 }
332
333 double roughlyEqual(const _Point& a) const {
334 return roughly_equal(a.y, y) && roughly_equal(a.x, x);
335 }
336 };
337
338 typedef _Point _Line[2];
339 typedef _Point Quadratic[3];
340 typedef _Point Triangle[3];
341 typedef _Point Cubic[4];
342
343 struct _Rect {
344 double left;
345 double top;
346 double right;
347 double bottom;
348
349 void add(const _Point& pt) {
350 if (left > pt.x) {
351 left = pt.x;
352 }
353 if (top > pt.y) {
354 top = pt.y;
355 }
356 if (right < pt.x) {
357 right = pt.x;
358 }
359 if (bottom < pt.y) {
360 bottom = pt.y;
361 }
362 }
363
364 // FIXME: used by debugging only ?
365 bool contains(const _Point& pt) const {
366 return approximately_between(left, pt.x, right)
367 && approximately_between(top, pt.y, bottom);
368 }
369
370 bool intersects(_Rect& r) const {
371 SkASSERT(left <= right);
372 SkASSERT(top <= bottom);
373 SkASSERT(r.left <= r.right);
374 SkASSERT(r.top <= r.bottom);
375 return r.left <= right && left <= r.right && r.top <= bottom && top <= r .bottom;
376 }
377
378 void set(const _Point& pt) {
379 left = right = pt.x;
380 top = bottom = pt.y;
381 }
382
383 void setBounds(const _Line& line) {
384 set(line[0]);
385 add(line[1]);
386 }
387
388 void setBounds(const Cubic& );
389 void setBounds(const Quadratic& );
390 void setRawBounds(const Cubic& );
391 void setRawBounds(const Quadratic& );
392 };
393
394 struct CubicPair {
395 const Cubic& first() const { return (const Cubic&) pts[0]; }
396 const Cubic& second() const { return (const Cubic&) pts[3]; }
397 _Point pts[7];
398 };
399
400 struct QuadraticPair {
401 const Quadratic& first() const { return (const Quadratic&) pts[0]; }
402 const Quadratic& second() const { return (const Quadratic&) pts[2]; }
403 _Point pts[5];
404 };
405
406 // FIXME: move these into SkFloatingPoint.h
407 #include "SkFloatingPoint.h"
408
409 #define sk_double_isnan(a) sk_float_isnan(a)
410
411 // FIXME: move these to debugging file
412 #ifdef SK_DEBUG
413 void mathematica_ize(char* str, size_t bufferSize);
414 bool valid_wind(int winding);
415 void winding_printf(int winding);
416 #endif
417
418 #endif // __DataTypes_h__
OLDNEW
« no previous file with comments | « experimental/Intersection/CurveUtilities.h ('k') | experimental/Intersection/DataTypes.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698