| 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 | 82 |
| 83 Thus, if the slope of the line tends towards vertical, we use: | 83 Thus, if the slope of the line tends towards vertical, we use: |
| 84 A = ( (a - 2*b + c) - g'*(d - 2*e + f) ) | 84 A = ( (a - 2*b + c) - g'*(d - 2*e + f) ) |
| 85 B = 2*(-(a - b ) + g'*(d - e ) ) | 85 B = 2*(-(a - b ) + g'*(d - e ) ) |
| 86 C = ( (a ) - g'*(d ) - h' ) | 86 C = ( (a ) - g'*(d ) - h' ) |
| 87 */ | 87 */ |
| 88 | 88 |
| 89 | 89 |
| 90 class LineQuadraticIntersections { | 90 class LineQuadraticIntersections { |
| 91 public: | 91 public: |
| 92 enum PinTPoint { |
| 93 kPointUninitialized, |
| 94 kPointInitialized |
| 95 }; |
| 96 |
| 92 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio
ns* i) | 97 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio
ns* i) |
| 93 : quad(q) | 98 : fQuad(q) |
| 94 , line(l) | 99 , fLine(l) |
| 95 , intersections(i) | 100 , fIntersections(i) |
| 96 , fAllowNear(true) { | 101 , fAllowNear(true) { |
| 97 } | 102 } |
| 98 | 103 |
| 99 void allowNear(bool allow) { | 104 void allowNear(bool allow) { |
| 100 fAllowNear = allow; | 105 fAllowNear = allow; |
| 101 } | 106 } |
| 102 | 107 |
| 103 int intersectRay(double roots[2]) { | 108 int intersectRay(double roots[2]) { |
| 104 /* | 109 /* |
| 105 solve by rotating line+quad so line is horizontal, then finding the root
s | 110 solve by rotating line+quad so line is horizontal, then finding the root
s |
| 106 set up matrix to rotate quad to x-axis | 111 set up matrix to rotate quad to x-axis |
| 107 |cos(a) -sin(a)| | 112 |cos(a) -sin(a)| |
| 108 |sin(a) cos(a)| | 113 |sin(a) cos(a)| |
| 109 note that cos(a) = A(djacent) / Hypoteneuse | 114 note that cos(a) = A(djacent) / Hypoteneuse |
| 110 sin(a) = O(pposite) / Hypoteneuse | 115 sin(a) = O(pposite) / Hypoteneuse |
| 111 since we are computing Ts, we can ignore hypoteneuse, the scale factor: | 116 since we are computing Ts, we can ignore hypoteneuse, the scale factor: |
| 112 | A -O | | 117 | A -O | |
| 113 | O A | | 118 | O A | |
| 114 A = line[1].fX - line[0].fX (adjacent side of the right triangle) | 119 A = line[1].fX - line[0].fX (adjacent side of the right triangle) |
| 115 O = line[1].fY - line[0].fY (opposite side of the right triangle) | 120 O = line[1].fY - line[0].fY (opposite side of the right triangle) |
| 116 for each of the three points (e.g. n = 0 to 2) | 121 for each of the three points (e.g. n = 0 to 2) |
| 117 quad[n].fY' = (quad[n].fY - line[0].fY) * A - (quad[n].fX - line[0].fX)
* O | 122 quad[n].fY' = (quad[n].fY - line[0].fY) * A - (quad[n].fX - line[0].fX)
* O |
| 118 */ | 123 */ |
| 119 double adj = line[1].fX - line[0].fX; | 124 double adj = fLine[1].fX - fLine[0].fX; |
| 120 double opp = line[1].fY - line[0].fY; | 125 double opp = fLine[1].fY - fLine[0].fY; |
| 121 double r[3]; | 126 double r[3]; |
| 122 for (int n = 0; n < 3; ++n) { | 127 for (int n = 0; n < 3; ++n) { |
| 123 r[n] = (quad[n].fY - line[0].fY) * adj - (quad[n].fX - line[0].fX) *
opp; | 128 r[n] = (fQuad[n].fY - fLine[0].fY) * adj - (fQuad[n].fX - fLine[0].f
X) * opp; |
| 124 } | 129 } |
| 125 double A = r[2]; | 130 double A = r[2]; |
| 126 double B = r[1]; | 131 double B = r[1]; |
| 127 double C = r[0]; | 132 double C = r[0]; |
| 128 A += C - 2 * B; // A = a - 2*b + c | 133 A += C - 2 * B; // A = a - 2*b + c |
| 129 B -= C; // B = -(b - c) | 134 B -= C; // B = -(b - c) |
| 130 return SkDQuad::RootsValidT(A, 2 * B, C, roots); | 135 return SkDQuad::RootsValidT(A, 2 * B, C, roots); |
| 131 } | 136 } |
| 132 | 137 |
| 133 int intersect() { | 138 int intersect() { |
| 134 addExactEndPoints(); | 139 addExactEndPoints(); |
| 135 double rootVals[2]; | 140 double rootVals[2]; |
| 136 int roots = intersectRay(rootVals); | 141 int roots = intersectRay(rootVals); |
| 137 for (int index = 0; index < roots; ++index) { | 142 for (int index = 0; index < roots; ++index) { |
| 138 double quadT = rootVals[index]; | 143 double quadT = rootVals[index]; |
| 139 double lineT = findLineT(quadT); | 144 double lineT = findLineT(quadT); |
| 140 if (PinTs(&quadT, &lineT)) { | 145 SkDPoint pt; |
| 141 SkDPoint pt = line.xyAtT(lineT); | 146 if (pinTs(&quadT, &lineT, &pt, kPointUninitialized)) { |
| 142 intersections->insert(quadT, lineT, pt); | 147 fIntersections->insert(quadT, lineT, pt); |
| 143 } | 148 } |
| 144 } | 149 } |
| 145 if (fAllowNear) { | 150 if (fAllowNear) { |
| 146 addNearEndPoints(); | 151 addNearEndPoints(); |
| 147 } | 152 } |
| 148 return intersections->used(); | 153 return fIntersections->used(); |
| 149 } | 154 } |
| 150 | 155 |
| 151 int horizontalIntersect(double axisIntercept, double roots[2]) { | 156 int horizontalIntersect(double axisIntercept, double roots[2]) { |
| 152 double D = quad[2].fY; // f | 157 double D = fQuad[2].fY; // f |
| 153 double E = quad[1].fY; // e | 158 double E = fQuad[1].fY; // e |
| 154 double F = quad[0].fY; // d | 159 double F = fQuad[0].fY; // d |
| 155 D += F - 2 * E; // D = d - 2*e + f | 160 D += F - 2 * E; // D = d - 2*e + f |
| 156 E -= F; // E = -(d - e) | 161 E -= F; // E = -(d - e) |
| 157 F -= axisIntercept; | 162 F -= axisIntercept; |
| 158 return SkDQuad::RootsValidT(D, 2 * E, F, roots); | 163 return SkDQuad::RootsValidT(D, 2 * E, F, roots); |
| 159 } | 164 } |
| 160 | 165 |
| 161 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { | 166 int horizontalIntersect(double axisIntercept, double left, double right, boo
l flipped) { |
| 162 addExactHorizontalEndPoints(left, right, axisIntercept); | 167 addExactHorizontalEndPoints(left, right, axisIntercept); |
| 163 double rootVals[2]; | 168 double rootVals[2]; |
| 164 int roots = horizontalIntersect(axisIntercept, rootVals); | 169 int roots = horizontalIntersect(axisIntercept, rootVals); |
| 165 for (int index = 0; index < roots; ++index) { | 170 for (int index = 0; index < roots; ++index) { |
| 166 double quadT = rootVals[index]; | 171 double quadT = rootVals[index]; |
| 167 SkDPoint pt = quad.xyAtT(quadT); | 172 SkDPoint pt = fQuad.ptAtT(quadT); |
| 168 double lineT = (pt.fX - left) / (right - left); | 173 double lineT = (pt.fX - left) / (right - left); |
| 169 if (PinTs(&quadT, &lineT)) { | 174 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { |
| 170 intersections->insert(quadT, lineT, pt); | 175 fIntersections->insert(quadT, lineT, pt); |
| 171 } | 176 } |
| 172 } | 177 } |
| 173 if (fAllowNear) { | 178 if (fAllowNear) { |
| 174 addNearHorizontalEndPoints(left, right, axisIntercept); | 179 addNearHorizontalEndPoints(left, right, axisIntercept); |
| 175 } | 180 } |
| 176 if (flipped) { | 181 if (flipped) { |
| 177 intersections->flip(); | 182 fIntersections->flip(); |
| 178 } | 183 } |
| 179 return intersections->used(); | 184 return fIntersections->used(); |
| 180 } | 185 } |
| 181 | 186 |
| 182 int verticalIntersect(double axisIntercept, double roots[2]) { | 187 int verticalIntersect(double axisIntercept, double roots[2]) { |
| 183 double D = quad[2].fX; // f | 188 double D = fQuad[2].fX; // f |
| 184 double E = quad[1].fX; // e | 189 double E = fQuad[1].fX; // e |
| 185 double F = quad[0].fX; // d | 190 double F = fQuad[0].fX; // d |
| 186 D += F - 2 * E; // D = d - 2*e + f | 191 D += F - 2 * E; // D = d - 2*e + f |
| 187 E -= F; // E = -(d - e) | 192 E -= F; // E = -(d - e) |
| 188 F -= axisIntercept; | 193 F -= axisIntercept; |
| 189 return SkDQuad::RootsValidT(D, 2 * E, F, roots); | 194 return SkDQuad::RootsValidT(D, 2 * E, F, roots); |
| 190 } | 195 } |
| 191 | 196 |
| 192 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { | 197 int verticalIntersect(double axisIntercept, double top, double bottom, bool
flipped) { |
| 193 addExactVerticalEndPoints(top, bottom, axisIntercept); | 198 addExactVerticalEndPoints(top, bottom, axisIntercept); |
| 194 double rootVals[2]; | 199 double rootVals[2]; |
| 195 int roots = verticalIntersect(axisIntercept, rootVals); | 200 int roots = verticalIntersect(axisIntercept, rootVals); |
| 196 for (int index = 0; index < roots; ++index) { | 201 for (int index = 0; index < roots; ++index) { |
| 197 double quadT = rootVals[index]; | 202 double quadT = rootVals[index]; |
| 198 SkDPoint pt = quad.xyAtT(quadT); | 203 SkDPoint pt = fQuad.ptAtT(quadT); |
| 199 double lineT = (pt.fY - top) / (bottom - top); | 204 double lineT = (pt.fY - top) / (bottom - top); |
| 200 if (PinTs(&quadT, &lineT)) { | 205 if (pinTs(&quadT, &lineT, &pt, kPointInitialized)) { |
| 201 intersections->insert(quadT, lineT, pt); | 206 fIntersections->insert(quadT, lineT, pt); |
| 202 } | 207 } |
| 203 } | 208 } |
| 204 if (fAllowNear) { | 209 if (fAllowNear) { |
| 205 addNearVerticalEndPoints(top, bottom, axisIntercept); | 210 addNearVerticalEndPoints(top, bottom, axisIntercept); |
| 206 } | 211 } |
| 207 if (flipped) { | 212 if (flipped) { |
| 208 intersections->flip(); | 213 fIntersections->flip(); |
| 209 } | 214 } |
| 210 return intersections->used(); | 215 return fIntersections->used(); |
| 211 } | 216 } |
| 212 | 217 |
| 213 protected: | 218 protected: |
| 214 // add endpoints first to get zero and one t values exactly | 219 // add endpoints first to get zero and one t values exactly |
| 215 void addExactEndPoints() { | 220 void addExactEndPoints() { |
| 216 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 221 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 217 double lineT = line.exactPoint(quad[qIndex]); | 222 double lineT = fLine.exactPoint(fQuad[qIndex]); |
| 218 if (lineT < 0) { | 223 if (lineT < 0) { |
| 219 continue; | 224 continue; |
| 220 } | 225 } |
| 221 double quadT = (double) (qIndex >> 1); | 226 double quadT = (double) (qIndex >> 1); |
| 222 intersections->insert(quadT, lineT, quad[qIndex]); | 227 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 223 } | 228 } |
| 224 } | 229 } |
| 225 | 230 |
| 226 void addNearEndPoints() { | 231 void addNearEndPoints() { |
| 227 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 232 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 228 double quadT = (double) (qIndex >> 1); | 233 double quadT = (double) (qIndex >> 1); |
| 229 if (intersections->hasT(quadT)) { | 234 if (fIntersections->hasT(quadT)) { |
| 230 continue; | 235 continue; |
| 231 } | 236 } |
| 232 double lineT = line.nearPoint(quad[qIndex]); | 237 double lineT = fLine.nearPoint(fQuad[qIndex]); |
| 233 if (lineT < 0) { | 238 if (lineT < 0) { |
| 234 continue; | 239 continue; |
| 235 } | 240 } |
| 236 intersections->insert(quadT, lineT, quad[qIndex]); | 241 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 237 } | 242 } |
| 238 // FIXME: see if line end is nearly on quad | 243 // FIXME: see if line end is nearly on quad |
| 239 } | 244 } |
| 240 | 245 |
| 241 void addExactHorizontalEndPoints(double left, double right, double y) { | 246 void addExactHorizontalEndPoints(double left, double right, double y) { |
| 242 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 247 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 243 double lineT = SkDLine::ExactPointH(quad[qIndex], left, right, y); | 248 double lineT = SkDLine::ExactPointH(fQuad[qIndex], left, right, y); |
| 244 if (lineT < 0) { | 249 if (lineT < 0) { |
| 245 continue; | 250 continue; |
| 246 } | 251 } |
| 247 double quadT = (double) (qIndex >> 1); | 252 double quadT = (double) (qIndex >> 1); |
| 248 intersections->insert(quadT, lineT, quad[qIndex]); | 253 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 249 } | 254 } |
| 250 } | 255 } |
| 251 | 256 |
| 252 void addNearHorizontalEndPoints(double left, double right, double y) { | 257 void addNearHorizontalEndPoints(double left, double right, double y) { |
| 253 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 258 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 254 double quadT = (double) (qIndex >> 1); | 259 double quadT = (double) (qIndex >> 1); |
| 255 if (intersections->hasT(quadT)) { | 260 if (fIntersections->hasT(quadT)) { |
| 256 continue; | 261 continue; |
| 257 } | 262 } |
| 258 double lineT = SkDLine::NearPointH(quad[qIndex], left, right, y); | 263 double lineT = SkDLine::NearPointH(fQuad[qIndex], left, right, y); |
| 259 if (lineT < 0) { | 264 if (lineT < 0) { |
| 260 continue; | 265 continue; |
| 261 } | 266 } |
| 262 intersections->insert(quadT, lineT, quad[qIndex]); | 267 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 263 } | 268 } |
| 264 // FIXME: see if line end is nearly on quad | 269 // FIXME: see if line end is nearly on quad |
| 265 } | 270 } |
| 266 | 271 |
| 267 void addExactVerticalEndPoints(double top, double bottom, double x) { | 272 void addExactVerticalEndPoints(double top, double bottom, double x) { |
| 268 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 273 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 269 double lineT = SkDLine::ExactPointV(quad[qIndex], top, bottom, x); | 274 double lineT = SkDLine::ExactPointV(fQuad[qIndex], top, bottom, x); |
| 270 if (lineT < 0) { | 275 if (lineT < 0) { |
| 271 continue; | 276 continue; |
| 272 } | 277 } |
| 273 double quadT = (double) (qIndex >> 1); | 278 double quadT = (double) (qIndex >> 1); |
| 274 intersections->insert(quadT, lineT, quad[qIndex]); | 279 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 275 } | 280 } |
| 276 } | 281 } |
| 277 | 282 |
| 278 void addNearVerticalEndPoints(double top, double bottom, double x) { | 283 void addNearVerticalEndPoints(double top, double bottom, double x) { |
| 279 for (int qIndex = 0; qIndex < 3; qIndex += 2) { | 284 for (int qIndex = 0; qIndex < 3; qIndex += 2) { |
| 280 double quadT = (double) (qIndex >> 1); | 285 double quadT = (double) (qIndex >> 1); |
| 281 if (intersections->hasT(quadT)) { | 286 if (fIntersections->hasT(quadT)) { |
| 282 continue; | 287 continue; |
| 283 } | 288 } |
| 284 double lineT = SkDLine::NearPointV(quad[qIndex], top, bottom, x); | 289 double lineT = SkDLine::NearPointV(fQuad[qIndex], top, bottom, x); |
| 285 if (lineT < 0) { | 290 if (lineT < 0) { |
| 286 continue; | 291 continue; |
| 287 } | 292 } |
| 288 intersections->insert(quadT, lineT, quad[qIndex]); | 293 fIntersections->insert(quadT, lineT, fQuad[qIndex]); |
| 289 } | 294 } |
| 290 // FIXME: see if line end is nearly on quad | 295 // FIXME: see if line end is nearly on quad |
| 291 } | 296 } |
| 292 | 297 |
| 293 double findLineT(double t) { | 298 double findLineT(double t) { |
| 294 SkDPoint xy = quad.xyAtT(t); | 299 SkDPoint xy = fQuad.ptAtT(t); |
| 295 double dx = line[1].fX - line[0].fX; | 300 double dx = fLine[1].fX - fLine[0].fX; |
| 296 double dy = line[1].fY - line[0].fY; | 301 double dy = fLine[1].fY - fLine[0].fY; |
| 297 double dxT = (xy.fX - line[0].fX) / dx; | 302 double dxT = (xy.fX - fLine[0].fX) / dx; |
| 298 double dyT = (xy.fY - line[0].fY) / dy; | 303 double dyT = (xy.fY - fLine[0].fY) / dy; |
| 299 if (!between(FLT_EPSILON, dxT, 1 - FLT_EPSILON) && between(0, dyT, 1)) { | 304 if (!between(FLT_EPSILON, dxT, 1 - FLT_EPSILON) && between(0, dyT, 1)) { |
| 300 return dyT; | 305 return dyT; |
| 301 } | 306 } |
| 302 if (!between(FLT_EPSILON, dyT, 1 - FLT_EPSILON) && between(0, dxT, 1)) { | 307 if (!between(FLT_EPSILON, dyT, 1 - FLT_EPSILON) && between(0, dxT, 1)) { |
| 303 return dxT; | 308 return dxT; |
| 304 } | 309 } |
| 305 return fabs(dx) > fabs(dy) ? dxT : dyT; | 310 return fabs(dx) > fabs(dy) ? dxT : dyT; |
| 306 } | 311 } |
| 307 | 312 |
| 308 static bool PinTs(double* quadT, double* lineT) { | 313 bool pinTs(double* quadT, double* lineT, SkDPoint* pt, PinTPoint ptSet) { |
| 309 if (!approximately_one_or_less(*lineT)) { | 314 if (!approximately_one_or_less(*lineT)) { |
| 310 return false; | 315 return false; |
| 311 } | 316 } |
| 312 if (!approximately_zero_or_more(*lineT)) { | 317 if (!approximately_zero_or_more(*lineT)) { |
| 313 return false; | 318 return false; |
| 314 } | 319 } |
| 315 *quadT = SkPinT(*quadT); | 320 double qT = *quadT = SkPinT(*quadT); |
| 316 *lineT = SkPinT(*lineT); | 321 double lT = *lineT = SkPinT(*lineT); |
| 322 if (lT == 0 || lT == 1 || (ptSet == kPointUninitialized && qT != 0 && qT
!= 1)) { |
| 323 *pt = fLine.ptAtT(lT); |
| 324 } else if (ptSet == kPointUninitialized) { |
| 325 *pt = fQuad.ptAtT(qT); |
| 326 } |
| 317 return true; | 327 return true; |
| 318 } | 328 } |
| 319 | 329 |
| 320 private: | 330 private: |
| 321 const SkDQuad& quad; | 331 const SkDQuad& fQuad; |
| 322 const SkDLine& line; | 332 const SkDLine& fLine; |
| 323 SkIntersections* intersections; | 333 SkIntersections* fIntersections; |
| 324 bool fAllowNear; | 334 bool fAllowNear; |
| 325 }; | 335 }; |
| 326 | 336 |
| 327 // utility for pairs of coincident quads | 337 // utility for pairs of coincident quads |
| 328 static double horizontalIntersect(const SkDQuad& quad, const SkDPoint& pt) { | 338 static double horizontalIntersect(const SkDQuad& quad, const SkDPoint& pt) { |
| 329 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), | 339 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), |
| 330 static_cast<SkIntersections*>(0)); | 340 static_cast<SkIntersections*>(0)); |
| 331 double rootVals[2]; | 341 double rootVals[2]; |
| 332 int roots = q.horizontalIntersect(pt.fY, rootVals); | 342 int roots = q.horizontalIntersect(pt.fY, rootVals); |
| 333 for (int index = 0; index < roots; ++index) { | 343 for (int index = 0; index < roots; ++index) { |
| 334 double t = rootVals[index]; | 344 double t = rootVals[index]; |
| 335 SkDPoint qPt = quad.xyAtT(t); | 345 SkDPoint qPt = quad.ptAtT(t); |
| 336 if (AlmostEqualUlps(qPt.fX, pt.fX)) { | 346 if (AlmostEqualUlps(qPt.fX, pt.fX)) { |
| 337 return t; | 347 return t; |
| 338 } | 348 } |
| 339 } | 349 } |
| 340 return -1; | 350 return -1; |
| 341 } | 351 } |
| 342 | 352 |
| 343 static double verticalIntersect(const SkDQuad& quad, const SkDPoint& pt) { | 353 static double verticalIntersect(const SkDQuad& quad, const SkDPoint& pt) { |
| 344 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), | 354 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), |
| 345 static_cast<SkIntersections*>(0)); | 355 static_cast<SkIntersections*>(0)); |
| 346 double rootVals[2]; | 356 double rootVals[2]; |
| 347 int roots = q.verticalIntersect(pt.fX, rootVals); | 357 int roots = q.verticalIntersect(pt.fX, rootVals); |
| 348 for (int index = 0; index < roots; ++index) { | 358 for (int index = 0; index < roots; ++index) { |
| 349 double t = rootVals[index]; | 359 double t = rootVals[index]; |
| 350 SkDPoint qPt = quad.xyAtT(t); | 360 SkDPoint qPt = quad.ptAtT(t); |
| 351 if (AlmostEqualUlps(qPt.fY, pt.fY)) { | 361 if (AlmostEqualUlps(qPt.fY, pt.fY)) { |
| 352 return t; | 362 return t; |
| 353 } | 363 } |
| 354 } | 364 } |
| 355 return -1; | 365 return -1; |
| 356 } | 366 } |
| 357 | 367 |
| 358 double SkIntersections::Axial(const SkDQuad& q1, const SkDPoint& p, bool vertica
l) { | 368 double SkIntersections::Axial(const SkDQuad& q1, const SkDPoint& p, bool vertica
l) { |
| 359 if (vertical) { | 369 if (vertical) { |
| 360 return verticalIntersect(q1, p); | 370 return verticalIntersect(q1, p); |
| 361 } | 371 } |
| 362 return horizontalIntersect(q1, p); | 372 return horizontalIntersect(q1, p); |
| 363 } | 373 } |
| 364 | 374 |
| 365 int SkIntersections::horizontal(const SkDQuad& quad, double left, double right,
double y, | 375 int SkIntersections::horizontal(const SkDQuad& quad, double left, double right,
double y, |
| 366 bool flipped) { | 376 bool flipped) { |
| 367 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), this); | 377 SkDLine line = {{{ left, y }, { right, y }}}; |
| 378 LineQuadraticIntersections q(quad, line, this); |
| 368 return q.horizontalIntersect(y, left, right, flipped); | 379 return q.horizontalIntersect(y, left, right, flipped); |
| 369 } | 380 } |
| 370 | 381 |
| 371 int SkIntersections::vertical(const SkDQuad& quad, double top, double bottom, do
uble x, | 382 int SkIntersections::vertical(const SkDQuad& quad, double top, double bottom, do
uble x, |
| 372 bool flipped) { | 383 bool flipped) { |
| 373 LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), this); | 384 SkDLine line = {{{ x, top }, { x, bottom }}}; |
| 385 LineQuadraticIntersections q(quad, line, this); |
| 374 return q.verticalIntersect(x, top, bottom, flipped); | 386 return q.verticalIntersect(x, top, bottom, flipped); |
| 375 } | 387 } |
| 376 | 388 |
| 377 int SkIntersections::intersect(const SkDQuad& quad, const SkDLine& line) { | 389 int SkIntersections::intersect(const SkDQuad& quad, const SkDLine& line) { |
| 378 LineQuadraticIntersections q(quad, line, this); | 390 LineQuadraticIntersections q(quad, line, this); |
| 379 q.allowNear(fAllowNear); | 391 q.allowNear(fAllowNear); |
| 380 return q.intersect(); | 392 return q.intersect(); |
| 381 } | 393 } |
| 382 | 394 |
| 383 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { | 395 int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) { |
| 384 LineQuadraticIntersections q(quad, line, this); | 396 LineQuadraticIntersections q(quad, line, this); |
| 385 fUsed = q.intersectRay(fT[0]); | 397 fUsed = q.intersectRay(fT[0]); |
| 386 for (int index = 0; index < fUsed; ++index) { | 398 for (int index = 0; index < fUsed; ++index) { |
| 387 fPt[index] = quad.xyAtT(fT[0][index]); | 399 fPt[index] = quad.ptAtT(fT[0][index]); |
| 388 } | 400 } |
| 389 return fUsed; | 401 return fUsed; |
| 390 } | 402 } |
| OLD | NEW |