| 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 double A = r[2]; | 130 double A = r[2]; |
| 131 double B = r[1]; | 131 double B = r[1]; |
| 132 double C = r[0]; | 132 double C = r[0]; |
| 133 A += C - 2 * B; // A = a - 2*b + c | 133 A += C - 2 * B; // A = a - 2*b + c |
| 134 B -= C; // B = -(b - c) | 134 B -= C; // B = -(b - c) |
| 135 return SkDQuad::RootsValidT(A, 2 * B, C, roots); | 135 return SkDQuad::RootsValidT(A, 2 * B, C, roots); |
| 136 } | 136 } |
| 137 | 137 |
| 138 int intersect() { | 138 int intersect() { |
| 139 addExactEndPoints(); | 139 addExactEndPoints(); |
| 140 if (fAllowNear) { |
| 141 addNearEndPoints(); |
| 142 } |
| 140 double rootVals[2]; | 143 double rootVals[2]; |
| 141 int roots = intersectRay(rootVals); | 144 int roots = intersectRay(rootVals); |
| 142 for (int index = 0; index < roots; ++index) { | 145 for (int index = 0; index < roots; ++index) { |
| 143 double quadT = rootVals[index]; | 146 double quadT = rootVals[index]; |
| 144 double lineT = findLineT(quadT); | 147 double lineT = findLineT(quadT); |
| 145 SkDPoint pt; | 148 SkDPoint pt; |
| 146 if (pinTs(&quadT, &lineT, &pt, kPointUninitialized)) { | 149 if (pinTs(&quadT, &lineT, &pt, kPointUninitialized)) { |
| 147 fIntersections->insert(quadT, lineT, pt); | 150 fIntersections->insert(quadT, lineT, pt); |
| 148 } | 151 } |
| 149 } | 152 } |
| 150 if (fAllowNear) { | |
| 151 addNearEndPoints(); | |
| 152 } | |
| 153 return fIntersections->used(); | 153 return fIntersections->used(); |
| 154 } | 154 } |
| 155 | 155 |
| 156 int horizontalIntersect(double axisIntercept, double roots[2]) { | 156 int horizontalIntersect(double axisIntercept, double roots[2]) { |
| 157 double D = fQuad[2].fY; // f | 157 double D = fQuad[2].fY; // f |
| 158 double E = fQuad[1].fY; // e | 158 double E = fQuad[1].fY; // e |
| 159 double F = fQuad[0].fY; // d | 159 double F = fQuad[0].fY; // d |
| 160 D += F - 2 * E; // D = d - 2*e + f | 160 D += F - 2 * E; // D = d - 2*e + f |
| 161 E -= F; // E = -(d - e) | 161 E -= F; // E = -(d - e) |
| 162 F -= axisIntercept; | 162 F -= axisIntercept; |
| 163 return SkDQuad::RootsValidT(D, 2 * E, F, roots); | 163 return SkDQuad::RootsValidT(D, 2 * E, F, roots); |
| 164 } | 164 } |
| 165 | 165 |
| 166 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { | 166 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { |
| 167 addExactHorizontalEndPoints(left, right, axisIntercept); | 167 addExactHorizontalEndPoints(left, right, axisIntercept); |
| 168 if (fAllowNear) { |
| 169 addNearHorizontalEndPoints(left, right, axisIntercept); |
| 170 } |
| 168 double rootVals[2]; | 171 double rootVals[2]; |
| 169 int roots = horizontalIntersect(axisIntercept, rootVals); | 172 int roots = horizontalIntersect(axisIntercept, rootVals); |
| 170 for (int index = 0; index < roots; ++index) { | 173 for (int index = 0; index < roots; ++index) { |
| 171 double quadT = rootVals[index]; | 174 double quadT = rootVals[index]; |
| 172 SkDPoint pt = fQuad.ptAtT(quadT); | 175 SkDPoint pt = fQuad.ptAtT(quadT); |
| 173 double lineT = (pt.fX - left) / (right - left); | 176 double lineT = (pt.fX - left) / (right - left); |
| 174 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { | 177 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { |
| 175 fIntersections->insert(quadT, lineT, pt); | 178 fIntersections->insert(quadT, lineT, pt); |
| 176 } | 179 } |
| 177 } | 180 } |
| 178 if (fAllowNear) { | |
| 179 addNearHorizontalEndPoints(left, right, axisIntercept); | |
| 180 } | |
| 181 if (flipped) { | 181 if (flipped) { |
| 182 fIntersections->flip(); | 182 fIntersections->flip(); |
| 183 } | 183 } |
| 184 return fIntersections->used(); | 184 return fIntersections->used(); |
| 185 } | 185 } |
| 186 | 186 |
| 187 int verticalIntersect(double axisIntercept, double roots[2]) { | 187 int verticalIntersect(double axisIntercept, double roots[2]) { |
| 188 double D = fQuad[2].fX; // f | 188 double D = fQuad[2].fX; // f |
| 189 double E = fQuad[1].fX; // e | 189 double E = fQuad[1].fX; // e |
| 190 double F = fQuad[0].fX; // d | 190 double F = fQuad[0].fX; // d |
| 191 D += F - 2 * E; // D = d - 2*e + f | 191 D += F - 2 * E; // D = d - 2*e + f |
| 192 E -= F; // E = -(d - e) | 192 E -= F; // E = -(d - e) |
| 193 F -= axisIntercept; | 193 F -= axisIntercept; |
| 194 return SkDQuad::RootsValidT(D, 2 * E, F, roots); | 194 return SkDQuad::RootsValidT(D, 2 * E, F, roots); |
| 195 } | 195 } |
| 196 | 196 |
| 197 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { | 197 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { |
| 198 addExactVerticalEndPoints(top, bottom, axisIntercept); | 198 addExactVerticalEndPoints(top, bottom, axisIntercept); |
| 199 if (fAllowNear) { |
| 200 addNearVerticalEndPoints(top, bottom, axisIntercept); |
| 201 } |
| 199 double rootVals[2]; | 202 double rootVals[2]; |
| 200 int roots = verticalIntersect(axisIntercept, rootVals); | 203 int roots = verticalIntersect(axisIntercept, rootVals); |
| 201 for (int index = 0; index < roots; ++index) { | 204 for (int index = 0; index < roots; ++index) { |
| 202 double quadT = rootVals[index]; | 205 double quadT = rootVals[index]; |
| 203 SkDPoint pt = fQuad.ptAtT(quadT); | 206 SkDPoint pt = fQuad.ptAtT(quadT); |
| 204 double lineT = (pt.fY - top) / (bottom - top); | 207 double lineT = (pt.fY - top) / (bottom - top); |
| 205 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { | 208 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { |
| 206 fIntersections->insert(quadT, lineT, pt); | 209 fIntersections->insert(quadT, lineT, pt); |
| 207 } | 210 } |
| 208 } | 211 } |
| 209 if (fAllowNear) { | |
| 210 addNearVerticalEndPoints(top, bottom, axisIntercept); | |
| 211 } | |
| 212 if (flipped) { | 212 if (flipped) { |
| 213 fIntersections->flip(); | 213 fIntersections->flip(); |
| 214 } | 214 } |
| 215 return fIntersections->used(); | 215 return fIntersections->used(); |
| 216 } | 216 } |
| 217 | 217 |
| 218 protected: | 218 protected: |
| 219 // add endpoints first to get zero and one t values exactly | 219 // add endpoints first to get zero and one t values exactly |
| 220 void addExactEndPoints() { | 220 void addExactEndPoints() { |
| 221 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 221 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 if (!approximately_zero_or_more(*lineT)) { | 317 if (!approximately_zero_or_more(*lineT)) { |
| 318 return false; | 318 return false; |
| 319 } | 319 } |
| 320 double qT = *quadT = SkPinT(*quadT); | 320 double qT = *quadT = SkPinT(*quadT); |
| 321 double lT = *lineT = SkPinT(*lineT); | 321 double lT = *lineT = SkPinT(*lineT); |
| 322 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT
!= 1)) { | 322 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT
!= 1)) { |
| 323 *pt = fLine.ptAtT(lT); | 323 *pt = fLine.ptAtT(lT); |
| 324 } else if (ptSet == kPointUninitialized) { | 324 } else if (ptSet == kPointUninitialized) { |
| 325 *pt = fQuad.ptAtT(qT); | 325 *pt = fQuad.ptAtT(qT); |
| 326 } | 326 } |
| 327 SkPoint gridPt = pt->asSkPoint(); |
| 328 if (gridPt == fLine[0].asSkPoint()) { |
| 329 *lineT = 0; |
| 330 } else if (gridPt == fLine[1].asSkPoint()) { |
| 331 *lineT = 1; |
| 332 } |
| 333 if (gridPt == fQuad[0].asSkPoint()) { |
| 334 *quadT = 0; |
| 335 } else if (gridPt == fQuad[2].asSkPoint()) { |
| 336 *quadT = 1; |
| 337 } |
| 327 return true; | 338 return true; |
| 328 } | 339 } |
| 329 | 340 |
| 330 private: | 341 private: |
| 331 const SkDQuad& fQuad; | 342 const SkDQuad& fQuad; |
| 332 const SkDLine& fLine; | 343 const SkDLine& fLine; |
| 333 SkIntersections* fIntersections; | 344 SkIntersections* fIntersections; |
| 334 bool fAllowNear; | 345 bool fAllowNear; |
| 335 }; | 346 }; |
| 336 | 347 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 } | 404 } |
| 394 | 405 |
| 395 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { | 406 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { |
| 396 LineQuadraticIntersections q(quad, line, this); | 407 LineQuadraticIntersections q(quad, line, this); |
| 397 fUsed = q.intersectRay(fT[0]); | 408 fUsed = q.intersectRay(fT[0]); |
| 398 for (int index = 0; index < fUsed; ++index) { | 409 for (int index = 0; index < fUsed; ++index) { |
| 399 fPt[index] = quad.ptAtT(fT[0][index]); | 410 fPt[index] = quad.ptAtT(fT[0][index]); |
| 400 } | 411 } |
| 401 return fUsed; | 412 return fUsed; |
| 402 } | 413 } |
| OLD | NEW |