OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #ifndef SkPathOpsPoint_DEFINED | 7 #ifndef SkPathOpsPoint_DEFINED |
8 #define SkPathOpsPoint_DEFINED | 8 #define SkPathOpsPoint_DEFINED |
9 | 9 |
10 #include "SkPathOpsTypes.h" | 10 #include "SkPathOpsTypes.h" |
11 #include "SkPoint.h" | 11 #include "SkPoint.h" |
12 | 12 |
13 inline bool AlmostEqualUlps(const SkPoint& pt1, const SkPoint& pt2) { | 13 inline bool AlmostEqualUlps(const SkPoint& pt1, const SkPoint& pt2) { |
14 return AlmostEqualUlps(pt1.fX, pt2.fX) && AlmostEqualUlps(pt1.fY, pt2.fY); | 14 return AlmostEqualUlps(pt1.fX, pt2.fX) && AlmostEqualUlps(pt1.fY, pt2.fY); |
15 } | 15 } |
16 | 16 |
17 struct SkDVector { | 17 struct SkDVector { |
18 double fX; | 18 double fX; |
19 double fY; | 19 double fY; |
20 | 20 |
21 void set(const SkVector& pt) { | 21 void set(const SkVector& pt) { |
22 fX = pt.fX; | 22 fX = pt.fX; |
23 fY = pt.fY; | 23 fY = pt.fY; |
24 } | 24 } |
25 | 25 |
26 friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b); | 26 friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b); |
27 | 27 |
| 28 // only used by testing |
28 void operator+=(const SkDVector& v) { | 29 void operator+=(const SkDVector& v) { |
29 fX += v.fX; | 30 fX += v.fX; |
30 fY += v.fY; | 31 fY += v.fY; |
31 } | 32 } |
32 | 33 |
| 34 // only called by nearestT, which is currently only used by testing |
33 void operator-=(const SkDVector& v) { | 35 void operator-=(const SkDVector& v) { |
34 fX -= v.fX; | 36 fX -= v.fX; |
35 fY -= v.fY; | 37 fY -= v.fY; |
36 } | 38 } |
37 | 39 |
| 40 // only used by testing |
38 void operator/=(const double s) { | 41 void operator/=(const double s) { |
39 fX /= s; | 42 fX /= s; |
40 fY /= s; | 43 fY /= s; |
41 } | 44 } |
42 | 45 |
| 46 // only used by testing |
43 void operator*=(const double s) { | 47 void operator*=(const double s) { |
44 fX *= s; | 48 fX *= s; |
45 fY *= s; | 49 fY *= s; |
46 } | 50 } |
47 | 51 |
48 SkVector asSkVector() const { | 52 SkVector asSkVector() const { |
49 SkVector v = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)}; | 53 SkVector v = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)}; |
50 return v; | 54 return v; |
51 } | 55 } |
52 | 56 |
| 57 // only used by testing |
53 double cross(const SkDVector& a) const { | 58 double cross(const SkDVector& a) const { |
54 return fX * a.fY - fY * a.fX; | 59 return fX * a.fY - fY * a.fX; |
55 } | 60 } |
56 | 61 |
57 // similar to cross, this bastardization considers nearly coincident to be z
ero | 62 // similar to cross, this bastardization considers nearly coincident to be z
ero |
58 double crossCheck(const SkDVector& a) const { | 63 double crossCheck(const SkDVector& a) const { |
59 double xy = fX * a.fY; | 64 double xy = fX * a.fY; |
60 double yx = fY * a.fX; | 65 double yx = fY * a.fX; |
61 return AlmostEqualUlps(xy, yx) ? 0 : xy - yx; | 66 return AlmostEqualUlps(xy, yx) ? 0 : xy - yx; |
62 } | 67 } |
(...skipping 28 matching lines...) Expand all Loading... |
91 | 96 |
92 friend bool operator!=(const SkDPoint& a, const SkDPoint& b) { | 97 friend bool operator!=(const SkDPoint& a, const SkDPoint& b) { |
93 return a.fX != b.fX || a.fY != b.fY; | 98 return a.fX != b.fX || a.fY != b.fY; |
94 } | 99 } |
95 | 100 |
96 void operator=(const SkPoint& pt) { | 101 void operator=(const SkPoint& pt) { |
97 fX = pt.fX; | 102 fX = pt.fX; |
98 fY = pt.fY; | 103 fY = pt.fY; |
99 } | 104 } |
100 | 105 |
| 106 // only used by testing |
101 void operator+=(const SkDVector& v) { | 107 void operator+=(const SkDVector& v) { |
102 fX += v.fX; | 108 fX += v.fX; |
103 fY += v.fY; | 109 fY += v.fY; |
104 } | 110 } |
105 | 111 |
| 112 // only used by testing |
106 void operator-=(const SkDVector& v) { | 113 void operator-=(const SkDVector& v) { |
107 fX -= v.fX; | 114 fX -= v.fX; |
108 fY -= v.fY; | 115 fY -= v.fY; |
109 } | 116 } |
110 | 117 |
111 // note: this can not be implemented with | 118 // note: this can not be implemented with |
112 // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX); | 119 // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX); |
113 // because that will not take the magnitude of the values into account | 120 // because that will not take the magnitude of the values into account |
114 bool approximatelyEqual(const SkDPoint& a) const { | 121 bool approximatelyEqual(const SkDPoint& a) const { |
115 if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) { | 122 if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) { |
116 return true; | 123 return true; |
117 } | 124 } |
118 if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) { | 125 if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) { |
119 return false; | 126 return false; |
120 } | 127 } |
121 double dist = distance(a); // OPTIMIZATION: can we compare against dist
Sq instead ? | 128 double dist = distance(a); // OPTIMIZATION: can we compare against dist
Sq instead ? |
122 double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); | 129 double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); |
123 double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); | 130 double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); |
124 largest = SkTMax(largest, -tiniest); | 131 largest = SkTMax(largest, -tiniest); |
125 return AlmostBequalUlps(largest, largest + dist); // is the dist within
ULPS tolerance? | 132 return AlmostPequalUlps(largest, largest + dist); // is the dist within
ULPS tolerance? |
126 } | 133 } |
127 | 134 |
128 bool approximatelyEqual(const SkPoint& a) const { | 135 bool approximatelyEqual(const SkPoint& a) const { |
129 SkDPoint dA; | 136 SkDPoint dA; |
130 dA.set(a); | 137 dA.set(a); |
131 return approximatelyEqual(dA); | 138 return approximatelyEqual(dA); |
132 } | 139 } |
133 | 140 |
134 static bool ApproximatelyEqual(const SkPoint& a, const SkPoint& b) { | 141 static bool ApproximatelyEqual(const SkPoint& a, const SkPoint& b) { |
135 if (approximately_equal(a.fX, b.fX) && approximately_equal(a.fY, b.fY))
{ | 142 if (approximately_equal(a.fX, b.fX) && approximately_equal(a.fY, b.fY))
{ |
136 return true; | 143 return true; |
137 } | 144 } |
138 if (!RoughlyEqualUlps(a.fX, b.fX) || !RoughlyEqualUlps(a.fY, b.fY)) { | 145 if (!RoughlyEqualUlps(a.fX, b.fX) || !RoughlyEqualUlps(a.fY, b.fY)) { |
139 return false; | 146 return false; |
140 } | 147 } |
141 SkDPoint dA, dB; | 148 SkDPoint dA, dB; |
142 dA.set(a); | 149 dA.set(a); |
143 dB.set(b); | 150 dB.set(b); |
144 double dist = dA.distance(dB); // OPTIMIZATION: can we compare against
distSq instead ? | 151 double dist = dA.distance(dB); // OPTIMIZATION: can we compare against
distSq instead ? |
145 float tiniest = SkTMin(SkTMin(SkTMin(a.fX, b.fX), a.fY), b.fY); | 152 float tiniest = SkTMin(SkTMin(SkTMin(a.fX, b.fX), a.fY), b.fY); |
146 float largest = SkTMax(SkTMax(SkTMax(a.fX, b.fX), a.fY), b.fY); | 153 float largest = SkTMax(SkTMax(SkTMax(a.fX, b.fX), a.fY), b.fY); |
147 largest = SkTMax(largest, -tiniest); | 154 largest = SkTMax(largest, -tiniest); |
148 return AlmostBequalUlps((double) largest, largest + dist); // is dist wi
thin ULPS tolerance? | 155 return AlmostPequalUlps((double) largest, largest + dist); // is dist wi
thin ULPS tolerance? |
149 } | 156 } |
150 | 157 |
151 static bool RoughlyEqual(const SkPoint& a, const SkPoint& b) { | 158 // only used by testing |
152 if (approximately_equal(a.fX, b.fX) && approximately_equal(a.fY, b.fY))
{ | |
153 return true; | |
154 } | |
155 return RoughlyEqualUlps(a.fX, b.fX) && RoughlyEqualUlps(a.fY, b.fY); | |
156 } | |
157 | |
158 bool approximatelyPEqual(const SkDPoint& a) const { | |
159 if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) { | |
160 return true; | |
161 } | |
162 if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) { | |
163 return false; | |
164 } | |
165 double dist = distance(a); // OPTIMIZATION: can we compare against dist
Sq instead ? | |
166 double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); | |
167 double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); | |
168 largest = SkTMax(largest, -tiniest); | |
169 return AlmostPequalUlps(largest, largest + dist); // is the dist within
ULPS tolerance? | |
170 } | |
171 | |
172 bool approximatelyDEqual(const SkDPoint& a) const { | |
173 if (approximately_equal(fX, a.fX) && approximately_equal(fY, a.fY)) { | |
174 return true; | |
175 } | |
176 if (!RoughlyEqualUlps(fX, a.fX) || !RoughlyEqualUlps(fY, a.fY)) { | |
177 return false; | |
178 } | |
179 double dist = distance(a); // OPTIMIZATION: can we compare against dist
Sq instead ? | |
180 double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); | |
181 double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); | |
182 largest = SkTMax(largest, -tiniest); | |
183 return AlmostDequalUlps(largest, largest + dist); // is the dist within
ULPS tolerance? | |
184 } | |
185 | |
186 bool approximatelyZero() const { | 159 bool approximatelyZero() const { |
187 return approximately_zero(fX) && approximately_zero(fY); | 160 return approximately_zero(fX) && approximately_zero(fY); |
188 } | 161 } |
189 | 162 |
190 SkPoint asSkPoint() const { | 163 SkPoint asSkPoint() const { |
191 SkPoint pt = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)}; | 164 SkPoint pt = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)}; |
192 return pt; | 165 return pt; |
193 } | 166 } |
194 | 167 |
195 double distance(const SkDPoint& a) const { | 168 double distance(const SkDPoint& a) const { |
196 SkDVector temp = *this - a; | 169 SkDVector temp = *this - a; |
197 return temp.length(); | 170 return temp.length(); |
198 } | 171 } |
199 | 172 |
200 double distanceSquared(const SkDPoint& a) const { | 173 double distanceSquared(const SkDPoint& a) const { |
201 SkDVector temp = *this - a; | 174 SkDVector temp = *this - a; |
202 return temp.lengthSquared(); | 175 return temp.lengthSquared(); |
203 } | 176 } |
204 | 177 |
205 static SkDPoint Mid(const SkDPoint& a, const SkDPoint& b) { | 178 static SkDPoint Mid(const SkDPoint& a, const SkDPoint& b) { |
206 SkDPoint result; | 179 SkDPoint result; |
207 result.fX = (a.fX + b.fX) / 2; | 180 result.fX = (a.fX + b.fX) / 2; |
208 result.fY = (a.fY + b.fY) / 2; | 181 result.fY = (a.fY + b.fY) / 2; |
209 return result; | 182 return result; |
210 } | 183 } |
211 | 184 |
212 bool moreRoughlyEqual(const SkDPoint& a) const { | 185 bool roughlyEqual(const SkDPoint& a) const { |
213 if (roughly_equal(fX, a.fX) && roughly_equal(fY, a.fY)) { | 186 if (roughly_equal(fX, a.fX) && roughly_equal(fY, a.fY)) { |
214 return true; | 187 return true; |
215 } | 188 } |
216 double dist = distance(a); // OPTIMIZATION: can we compare against dist
Sq instead ? | 189 double dist = distance(a); // OPTIMIZATION: can we compare against dist
Sq instead ? |
217 double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); | 190 double tiniest = SkTMin(SkTMin(SkTMin(fX, a.fX), fY), a.fY); |
218 double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); | 191 double largest = SkTMax(SkTMax(SkTMax(fX, a.fX), fY), a.fY); |
219 largest = SkTMax(largest, -tiniest); | 192 largest = SkTMax(largest, -tiniest); |
220 return RoughlyEqualUlps(largest, largest + dist); // is the dist within
ULPS tolerance? | 193 return RoughlyEqualUlps(largest, largest + dist); // is the dist within
ULPS tolerance? |
221 } | 194 } |
222 | 195 |
223 bool roughlyEqual(const SkDPoint& a) const { | |
224 return roughly_equal(a.fY, fY) && roughly_equal(a.fX, fX); | |
225 } | |
226 | |
227 // utilities callable by the user from the debugger when the implementation
code is linked in | 196 // utilities callable by the user from the debugger when the implementation
code is linked in |
228 void dump() const; | 197 void dump() const; |
229 static void Dump(const SkPoint& pt); | 198 static void Dump(const SkPoint& pt); |
230 static void DumpHex(const SkPoint& pt); | 199 static void DumpHex(const SkPoint& pt); |
231 }; | 200 }; |
232 | 201 |
233 #endif | 202 #endif |
OLD | NEW |