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 #include "SkIntersections.h" | 7 #include "SkIntersections.h" |
8 #include "SkPathOpsLine.h" | 8 #include "SkPathOpsLine.h" |
9 #include "SkPathOpsQuad.h" | 9 #include "SkPathOpsQuad.h" |
10 | 10 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 if (flipped) { | 193 if (flipped) { |
194 intersections->flip(); | 194 intersections->flip(); |
195 } | 195 } |
196 return intersections->used(); | 196 return intersections->used(); |
197 } | 197 } |
198 | 198 |
199 protected: | 199 protected: |
200 // add endpoints first to get zero and one t values exactly | 200 // add endpoints first to get zero and one t values exactly |
201 void addEndPoints() { | 201 void addEndPoints() { |
202 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 202 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 203 bool foundEnd = false; |
203 for (int lIndex = 0; lIndex < 2; lIndex++) { | 204 for (int lIndex = 0; lIndex < 2; lIndex++) { |
204 if (quad[qIndex] == line[lIndex]) { | 205 if (quad[qIndex] == line[lIndex]) { |
205 intersections->insert(qIndex >> 1, lIndex, line[lIndex]); | 206 intersections->insert(qIndex >> 1, lIndex, line[lIndex]); |
| 207 foundEnd = true; |
206 } | 208 } |
207 } | 209 } |
| 210 if (foundEnd) { |
| 211 continue; |
| 212 } |
| 213 // See if the quad end touches the line. |
| 214 double dist = line.isLeft(quad[qIndex]); // this distance isn't cart
esian |
| 215 SkDVector lineLen = line[1] - line[0]; // the x/y magnitudes of the
line |
| 216 // compute the ULPS of the larger of the x/y deltas |
| 217 double larger = SkTMax(SkTAbs(lineLen.fX), SkTAbs(lineLen.fY)); |
| 218 if (!RoughlyEqualUlps(larger, larger + dist)) { // is the dist withi
n ULPS tolerance? |
| 219 continue; |
| 220 } |
| 221 double lineT = findLineT(qIndex >> 1); |
| 222 if (!between(0, lineT, 1)) { |
| 223 continue; |
| 224 } |
| 225 SkDPoint linePt = line.xyAtT(lineT); |
| 226 if (linePt.approximatelyEqual(quad[qIndex])) { |
| 227 intersections->insert(qIndex >> 1, lineT, quad[qIndex]); |
| 228 } |
208 } | 229 } |
209 } | 230 } |
210 | 231 |
211 void addHorizontalEndPoints(double left, double right, double y) { | 232 void addHorizontalEndPoints(double left, double right, double y) { |
212 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 233 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
213 if (quad[qIndex].fY != y) { | 234 if (!AlmostEqualUlps(quad[qIndex].fY, y)) { |
214 continue; | 235 continue; |
215 } | 236 } |
216 if (quad[qIndex].fX == left) { | 237 double x = quad[qIndex].fX; |
217 intersections->insert(qIndex >> 1, 0, quad[qIndex]); | 238 if (between(left, x, right)) { |
218 } | 239 double t = (x - left) / (right - left); |
219 if (quad[qIndex].fX == right) { | 240 intersections->insert(qIndex >> 1, t, quad[qIndex]); |
220 intersections->insert(qIndex >> 1, 1, quad[qIndex]); | |
221 } | 241 } |
222 } | 242 } |
223 } | 243 } |
224 | 244 |
225 void addVerticalEndPoints(double top, double bottom, double x) { | 245 void addVerticalEndPoints(double top, double bottom, double x) { |
226 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 246 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
227 if (quad[qIndex].fX != x) { | 247 if (!AlmostEqualUlps(quad[qIndex].fX, x)) { |
228 continue; | 248 continue; |
229 } | 249 } |
230 if (quad[qIndex].fY == top) { | 250 double y = quad[qIndex].fY; |
231 intersections->insert(qIndex >> 1, 0, quad[qIndex]); | 251 if (between(top, y, bottom)) { |
232 } | 252 double t = (y - top) / (bottom - top); |
233 if (quad[qIndex].fY == bottom) { | 253 intersections->insert(qIndex >> 1, t, quad[qIndex]); |
234 intersections->insert(qIndex >> 1, 1, quad[qIndex]); | |
235 } | 254 } |
236 } | 255 } |
237 } | 256 } |
238 | 257 |
239 double findLineT(double t) { | 258 double findLineT(double t) { |
240 SkDPoint xy = quad.xyAtT(t); | 259 SkDPoint xy = quad.xyAtT(t); |
241 double dx = line[1].fX - line[0].fX; | 260 double dx = line[1].fX - line[0].fX; |
242 double dy = line[1].fY - line[0].fY; | 261 double dy = line[1].fY - line[0].fY; |
| 262 #if 0 |
243 if (fabs(dx) > fabs(dy)) { | 263 if (fabs(dx) > fabs(dy)) { |
244 return (xy.fX - line[0].fX) / dx; | 264 return (xy.fX - line[0].fX) / dx; |
245 } | 265 } |
246 return (xy.fY - line[0].fY) / dy; | 266 return (xy.fY - line[0].fY) / dy; |
| 267 #else |
| 268 double dxT = (xy.fX - line[0].fX) / dx; |
| 269 double dyT = (xy.fY - line[0].fY) / dy; |
| 270 if (!between(FLT_EPSILON, dxT, 1 - FLT_EPSILON) && between(0, dyT, 1)) { |
| 271 return dyT; |
| 272 } |
| 273 if (!between(FLT_EPSILON, dyT, 1 - FLT_EPSILON) && between(0, dxT, 1)) { |
| 274 return dxT; |
| 275 } |
| 276 return fabs(dx) > fabs(dy) ? dxT : dyT; |
| 277 #endif |
247 } | 278 } |
248 | 279 |
249 static bool PinTs(double* quadT, double* lineT) { | 280 static bool PinTs(double* quadT, double* lineT) { |
250 if (!approximately_one_or_less(*lineT)) { | 281 if (!approximately_one_or_less(*lineT)) { |
251 return false; | 282 return false; |
252 } | 283 } |
253 if (!approximately_zero_or_more(*lineT)) { | 284 if (!approximately_zero_or_more(*lineT)) { |
254 return false; | 285 return false; |
255 } | 286 } |
256 if (precisely_less_than_zero(*quadT)) { | 287 if (precisely_less_than_zero(*quadT)) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 } | 359 } |
329 | 360 |
330 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { | 361 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { |
331 LineQuadraticIntersections q(quad, line, this); | 362 LineQuadraticIntersections q(quad, line, this); |
332 fUsed = q.intersectRay(fT[0]); | 363 fUsed = q.intersectRay(fT[0]); |
333 for (int index = 0; index < fUsed; ++index) { | 364 for (int index = 0; index < fUsed; ++index) { |
334 fPt[index] = quad.xyAtT(fT[0][index]); | 365 fPt[index] = quad.xyAtT(fT[0][index]); |
335 } | 366 } |
336 return fUsed; | 367 return fUsed; |
337 } | 368 } |
OLD | NEW |