| 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 |