| 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 "SkLineParameters.h" | 8 #include "SkLineParameters.h" |
| 9 #include "SkPathOpsCubic.h" | 9 #include "SkPathOpsCubic.h" |
| 10 #include "SkPathOpsQuad.h" | 10 #include "SkPathOpsQuad.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 } | 40 } |
| 41 } | 41 } |
| 42 if (!foundOutlier) { | 42 if (!foundOutlier) { |
| 43 return false; | 43 return false; |
| 44 } | 44 } |
| 45 } | 45 } |
| 46 *isLinear = linear; | 46 *isLinear = linear; |
| 47 return true; | 47 return true; |
| 48 } | 48 } |
| 49 | 49 |
| 50 bool SkDQuad::hullIntersects(const SkDConic& conic, bool* isLinear) const { |
| 51 return conic.hullIntersects(*this, isLinear); |
| 52 } |
| 53 |
| 54 bool SkDQuad::hullIntersects(const SkDCubic& cubic, bool* isLinear) const { |
| 55 return cubic.hullIntersects(*this, isLinear); |
| 56 } |
| 57 |
| 50 /* bit twiddling for finding the off curve index (x&~m is the pair in [0,1,2] ex
cluding oddMan) | 58 /* bit twiddling for finding the off curve index (x&~m is the pair in [0,1,2] ex
cluding oddMan) |
| 51 oddMan opp x=oddMan^opp x=x-oddMan m=x>>2 x&~m | 59 oddMan opp x=oddMan^opp x=x-oddMan m=x>>2 x&~m |
| 52 0 1 1 1 0 1 | 60 0 1 1 1 0 1 |
| 53 2 2 2 0 2 | 61 2 2 2 0 2 |
| 54 1 1 0 -1 -1 0 | 62 1 1 0 -1 -1 0 |
| 55 2 3 2 0 2 | 63 2 3 2 0 2 |
| 56 2 1 3 1 0 1 | 64 2 1 3 1 0 1 |
| 57 2 0 -2 -1 0 | 65 2 0 -2 -1 0 |
| 58 */ | 66 */ |
| 59 void SkDQuad::otherPts(int oddMan, const SkDPoint* endPt[2]) const { | 67 void SkDQuad::otherPts(int oddMan, const SkDPoint* endPt[2]) const { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 lineParameters.normalize(); | 199 lineParameters.normalize(); |
| 192 double distance = lineParameters.controlPtDistance(*this); | 200 double distance = lineParameters.controlPtDistance(*this); |
| 193 double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), | 201 double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), |
| 194 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); | 202 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); |
| 195 double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), | 203 double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), |
| 196 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); | 204 fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY); |
| 197 largest = SkTMax(largest, -tiniest); | 205 largest = SkTMax(largest, -tiniest); |
| 198 return approximately_zero_when_compared_to(distance, largest); | 206 return approximately_zero_when_compared_to(distance, largest); |
| 199 } | 207 } |
| 200 | 208 |
| 209 SkDConic SkDQuad::toConic() const { |
| 210 SkDConic conic; |
| 211 memcpy(conic.fPts.fPts, fPts, sizeof(fPts)); |
| 212 conic.fWeight = 1; |
| 213 return conic; |
| 214 } |
| 215 |
| 201 SkDCubic SkDQuad::toCubic() const { | 216 SkDCubic SkDQuad::toCubic() const { |
| 202 SkDCubic cubic; | 217 SkDCubic cubic; |
| 203 cubic[0] = fPts[0]; | 218 cubic[0] = fPts[0]; |
| 204 cubic[2] = fPts[1]; | 219 cubic[2] = fPts[1]; |
| 205 cubic[3] = fPts[2]; | 220 cubic[3] = fPts[2]; |
| 206 cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3; | 221 cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3; |
| 207 cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3; | 222 cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3; |
| 208 cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3; | 223 cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3; |
| 209 cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3; | 224 cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3; |
| 210 return cubic; | 225 return cubic; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 229 } | 244 } |
| 230 double one_t = 1 - t; | 245 double one_t = 1 - t; |
| 231 double a = one_t * one_t; | 246 double a = one_t * one_t; |
| 232 double b = 2 * one_t * t; | 247 double b = 2 * one_t * t; |
| 233 double c = t * t; | 248 double c = t * t; |
| 234 SkDPoint result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, | 249 SkDPoint result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX, |
| 235 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; | 250 a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY }; |
| 236 return result; | 251 return result; |
| 237 } | 252 } |
| 238 | 253 |
| 254 static double interp_quad_coords(const double* src, double t) { |
| 255 double ab = SkDInterp(src[0], src[2], t); |
| 256 double bc = SkDInterp(src[2], src[4], t); |
| 257 double abc = SkDInterp(ab, bc, t); |
| 258 return abc; |
| 259 } |
| 260 |
| 261 bool SkDQuad::monotonicInY() const { |
| 262 return between(fPts[0].fY, fPts[1].fY, fPts[2].fY); |
| 263 } |
| 264 |
| 239 /* | 265 /* |
| 240 Given a quadratic q, t1, and t2, find a small quadratic segment. | 266 Given a quadratic q, t1, and t2, find a small quadratic segment. |
| 241 | 267 |
| 242 The new quadratic is defined by A, B, and C, where | 268 The new quadratic is defined by A, B, and C, where |
| 243 A = c[0]*(1 - t1)*(1 - t1) + 2*c[1]*t1*(1 - t1) + c[2]*t1*t1 | 269 A = c[0]*(1 - t1)*(1 - t1) + 2*c[1]*t1*(1 - t1) + c[2]*t1*t1 |
| 244 C = c[3]*(1 - t1)*(1 - t1) + 2*c[2]*t1*(1 - t1) + c[1]*t1*t1 | 270 C = c[3]*(1 - t1)*(1 - t1) + 2*c[2]*t1*(1 - t1) + c[1]*t1*t1 |
| 245 | 271 |
| 246 To find B, compute the point halfway between t1 and t2: | 272 To find B, compute the point halfway between t1 and t2: |
| 247 | 273 |
| 248 q(at (t1 + t2)/2) == D | 274 q(at (t1 + t2)/2) == D |
| 249 | 275 |
| 250 Next, compute where D must be if we know the value of B: | 276 Next, compute where D must be if we know the value of B: |
| 251 | 277 |
| 252 _12 = A/2 + B/2 | 278 _12 = A/2 + B/2 |
| 253 12_ = B/2 + C/2 | 279 12_ = B/2 + C/2 |
| 254 123 = A/4 + B/2 + C/4 | 280 123 = A/4 + B/2 + C/4 |
| 255 = D | 281 = D |
| 256 | 282 |
| 257 Group the known values on one side: | 283 Group the known values on one side: |
| 258 | 284 |
| 259 B = D*2 - A/2 - C/2 | 285 B = D*2 - A/2 - C/2 |
| 260 */ | 286 */ |
| 261 | 287 |
| 262 static double interp_quad_coords(const double* src, double t) { | 288 // OPTIMIZE : special case either or both of t1 = 0, t2 = 1 |
| 263 double ab = SkDInterp(src[0], src[2], t); | |
| 264 double bc = SkDInterp(src[2], src[4], t); | |
| 265 double abc = SkDInterp(ab, bc, t); | |
| 266 return abc; | |
| 267 } | |
| 268 | |
| 269 bool SkDQuad::monotonicInY() const { | |
| 270 return between(fPts[0].fY, fPts[1].fY, fPts[2].fY); | |
| 271 } | |
| 272 | |
| 273 SkDQuad SkDQuad::subDivide(double t1, double t2) const { | 289 SkDQuad SkDQuad::subDivide(double t1, double t2) const { |
| 274 SkDQuad dst; | 290 SkDQuad dst; |
| 275 double ax = dst[0].fX = interp_quad_coords(&fPts[0].fX, t1); | 291 double ax = dst[0].fX = interp_quad_coords(&fPts[0].fX, t1); |
| 276 double ay = dst[0].fY = interp_quad_coords(&fPts[0].fY, t1); | 292 double ay = dst[0].fY = interp_quad_coords(&fPts[0].fY, t1); |
| 277 double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2); | 293 double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2); |
| 278 double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2); | 294 double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2); |
| 279 double cx = dst[2].fX = interp_quad_coords(&fPts[0].fX, t2); | 295 double cx = dst[2].fX = interp_quad_coords(&fPts[0].fX, t2); |
| 280 double cy = dst[2].fY = interp_quad_coords(&fPts[0].fY, t2); | 296 double cy = dst[2].fY = interp_quad_coords(&fPts[0].fY, t2); |
| 281 /* bx = */ dst[1].fX = 2*dx - (ax + cx)/2; | 297 /* bx = */ dst[1].fX = 2 * dx - (ax + cx) / 2; |
| 282 /* by = */ dst[1].fY = 2*dy - (ay + cy)/2; | 298 /* by = */ dst[1].fY = 2 * dy - (ay + cy) / 2; |
| 283 return dst; | 299 return dst; |
| 284 } | 300 } |
| 285 | 301 |
| 286 void SkDQuad::align(int endIndex, SkDPoint* dstPt) const { | 302 void SkDQuad::align(int endIndex, SkDPoint* dstPt) const { |
| 287 if (fPts[endIndex].fX == fPts[1].fX) { | 303 if (fPts[endIndex].fX == fPts[1].fX) { |
| 288 dstPt->fX = fPts[endIndex].fX; | 304 dstPt->fX = fPts[endIndex].fX; |
| 289 } | 305 } |
| 290 if (fPts[endIndex].fY == fPts[1].fY) { | 306 if (fPts[endIndex].fY == fPts[1].fY) { |
| 291 dstPt->fY = fPts[endIndex].fY; | 307 dstPt->fY = fPts[endIndex].fY; |
| 292 } | 308 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 * c = C | 396 * c = C |
| 381 */ | 397 */ |
| 382 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { | 398 void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) { |
| 383 *a = quad[0]; // a = A | 399 *a = quad[0]; // a = A |
| 384 *b = 2 * quad[2]; // b = 2*B | 400 *b = 2 * quad[2]; // b = 2*B |
| 385 *c = quad[4]; // c = C | 401 *c = quad[4]; // c = C |
| 386 *b -= *c; // b = 2*B - C | 402 *b -= *c; // b = 2*B - C |
| 387 *a -= *b; // a = A - 2*B + C | 403 *a -= *b; // a = A - 2*B + C |
| 388 *b -= *c; // b = 2*B - 2*C | 404 *b -= *c; // b = 2*B - 2*C |
| 389 } | 405 } |
| OLD | NEW |