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 "SkPathOpsCurve.h" | 10 #include "SkPathOpsCurve.h" |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 return result; | 233 return result; |
234 } | 234 } |
235 | 235 |
236 static double interp_quad_coords(const double* src, double t) { | 236 static double interp_quad_coords(const double* src, double t) { |
237 double ab = SkDInterp(src[0], src[2], t); | 237 double ab = SkDInterp(src[0], src[2], t); |
238 double bc = SkDInterp(src[2], src[4], t); | 238 double bc = SkDInterp(src[2], src[4], t); |
239 double abc = SkDInterp(ab, bc, t); | 239 double abc = SkDInterp(ab, bc, t); |
240 return abc; | 240 return abc; |
241 } | 241 } |
242 | 242 |
| 243 bool SkDQuad::monotonicInX() const { |
| 244 return between(fPts[0].fX, fPts[1].fX, fPts[2].fX); |
| 245 } |
| 246 |
243 bool SkDQuad::monotonicInY() const { | 247 bool SkDQuad::monotonicInY() const { |
244 return between(fPts[0].fY, fPts[1].fY, fPts[2].fY); | 248 return between(fPts[0].fY, fPts[1].fY, fPts[2].fY); |
245 } | 249 } |
246 | 250 |
247 /* | 251 /* |
248 Given a quadratic q, t1, and t2, find a small quadratic segment. | 252 Given a quadratic q, t1, and t2, find a small quadratic segment. |
249 | 253 |
250 The new quadratic is defined by A, B, and C, where | 254 The new quadratic is defined by A, B, and C, where |
251 A = c[0]*(1 - t1)*(1 - t1) + 2*c[1]*t1*(1 - t1) + c[2]*t1*t1 | 255 A = c[0]*(1 - t1)*(1 - t1) + 2*c[1]*t1*(1 - t1) + c[2]*t1*t1 |
252 C = c[3]*(1 - t1)*(1 - t1) + 2*c[2]*t1*(1 - t1) + c[1]*t1*t1 | 256 C = c[3]*(1 - t1)*(1 - t1) + 2*c[2]*t1*(1 - t1) + c[1]*t1*t1 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 b.fX = c.fX; | 320 b.fX = c.fX; |
317 } | 321 } |
318 if (AlmostBequalUlps(b.fY, a.fY)) { | 322 if (AlmostBequalUlps(b.fY, a.fY)) { |
319 b.fY = a.fY; | 323 b.fY = a.fY; |
320 } else if (AlmostBequalUlps(b.fY, c.fY)) { | 324 } else if (AlmostBequalUlps(b.fY, c.fY)) { |
321 b.fY = c.fY; | 325 b.fY = c.fY; |
322 } | 326 } |
323 return b; | 327 return b; |
324 } | 328 } |
325 | 329 |
326 SkDPoint SkDQuad::top(double startT, double endT, double* topT) const { | |
327 SkDQuad sub = subDivide(startT, endT); | |
328 SkDPoint topPt = sub[0]; | |
329 *topT = startT; | |
330 if (topPt.fY > sub[2].fY || (topPt.fY == sub[2].fY && topPt.fX > sub[2].fX))
{ | |
331 *topT = endT; | |
332 topPt = sub[2]; | |
333 } | |
334 if (!between(sub[0].fY, sub[1].fY, sub[2].fY)) { | |
335 double extremeT; | |
336 if (FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, &extremeT)) { | |
337 extremeT = startT + (endT - startT) * extremeT; | |
338 SkDPoint test = ptAtT(extremeT); | |
339 if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX
)) { | |
340 *topT = extremeT; | |
341 topPt = test; | |
342 } | |
343 } | |
344 } | |
345 return topPt; | |
346 } | |
347 | |
348 /* classic one t subdivision */ | 330 /* classic one t subdivision */ |
349 static void interp_quad_coords(const double* src, double* dst, double t) { | 331 static void interp_quad_coords(const double* src, double* dst, double t) { |
350 double ab = SkDInterp(src[0], src[2], t); | 332 double ab = SkDInterp(src[0], src[2], t); |
351 double bc = SkDInterp(src[2], src[4], t); | 333 double bc = SkDInterp(src[2], src[4], t); |
352 dst[0] = src[0]; | 334 dst[0] = src[0]; |
353 dst[2] = ab; | 335 dst[2] = ab; |
354 dst[4] = SkDInterp(ab, bc, t); | 336 dst[4] = SkDInterp(ab, bc, t); |
355 dst[6] = bc; | 337 dst[6] = bc; |
356 dst[8] = src[4]; | 338 dst[8] = src[4]; |
357 } | 339 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 } | 372 } |
391 *ratio = r; | 373 *ratio = r; |
392 return 1; | 374 return 1; |
393 } | 375 } |
394 | 376 |
395 /** Quad'(t) = At + B, where | 377 /** Quad'(t) = At + B, where |
396 A = 2(a - 2b + c) | 378 A = 2(a - 2b + c) |
397 B = 2(b - a) | 379 B = 2(b - a) |
398 Solve for t, only if it fits between 0 < t < 1 | 380 Solve for t, only if it fits between 0 < t < 1 |
399 */ | 381 */ |
400 int SkDQuad::FindExtrema(double a, double b, double c, double tValue[1]) { | 382 int SkDQuad::FindExtrema(const double src[], double tValue[1]) { |
401 /* At + B == 0 | 383 /* At + B == 0 |
402 t = -B / A | 384 t = -B / A |
403 */ | 385 */ |
| 386 double a = src[0]; |
| 387 double b = src[2]; |
| 388 double c = src[4]; |
404 return valid_unit_divide(a - b, a - b - b + c, tValue); | 389 return valid_unit_divide(a - b, a - b - b + c, tValue); |
405 } | 390 } |
406 | 391 |
407 /* Parameterization form, given A*t*t + 2*B*t*(1-t) + C*(1-t)*(1-t) | 392 /* Parameterization form, given A*t*t + 2*B*t*(1-t) + C*(1-t)*(1-t) |
408 * | 393 * |
409 * a = A - 2*B + C | 394 * a = A - 2*B + C |
410 * b = 2*B - 2*C | 395 * b = 2*B - 2*C |
411 * c = C | 396 * c = C |
412 */ | 397 */ |
413 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) { |
414 *a = quad[0]; // a = A | 399 *a = quad[0]; // a = A |
415 *b = 2 * quad[2]; // b = 2*B | 400 *b = 2 * quad[2]; // b = 2*B |
416 *c = quad[4]; // c = C | 401 *c = quad[4]; // c = C |
417 *b -= *c; // b = 2*B - C | 402 *b -= *c; // b = 2*B - C |
418 *a -= *b; // a = A - 2*B + C | 403 *a -= *b; // a = A - 2*B + C |
419 *b -= *c; // b = 2*B - 2*C | 404 *b -= *c; // b = 2*B - 2*C |
420 } | 405 } |
OLD | NEW |