OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 | 7 |
8 #include "SkGeometry.h" | 8 #include "SkGeometry.h" |
9 #include "SkMatrix.h" | 9 #include "SkMatrix.h" |
10 | 10 |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 if (dst) { | 647 if (dst) { |
648 if (count == 0) { | 648 if (count == 0) { |
649 memcpy(dst, src, 4 * sizeof(SkPoint)); | 649 memcpy(dst, src, 4 * sizeof(SkPoint)); |
650 } else { | 650 } else { |
651 SkChopCubicAt(src, dst, tValues, count); | 651 SkChopCubicAt(src, dst, tValues, count); |
652 } | 652 } |
653 } | 653 } |
654 return count + 1; | 654 return count + 1; |
655 } | 655 } |
656 | 656 |
| 657 // See http://http.developer.nvidia.com/GPUGems3/gpugems3_ch25.html (from the bo
ok GPU Gems 3) |
| 658 // discr(I) = d0^2 * (3*d1^2 - 4*d0*d2) |
| 659 // Classification: |
| 660 // discr(I) > 0 Serpentine |
| 661 // discr(I) = 0 Cusp |
| 662 // discr(I) < 0 Loop |
| 663 // d0 = d1 = 0 Quadratic |
| 664 // d0 = d1 = d2 = 0 Line |
| 665 // p0 = p1 = p2 = p3 Point |
| 666 static SkCubicType classify_cubic(const SkPoint p[4], const SkScalar d[3]) { |
| 667 if (p[0] == p[1] && p[0] == p[2] && p[0] == p[3]) { |
| 668 return kPoint_SkCubicType; |
| 669 } |
| 670 const SkScalar discr = d[0] * d[0] * (3.f * d[1] * d[1] - 4.f * d[0] * d[2])
; |
| 671 if (discr > SK_ScalarNearlyZero) { |
| 672 return kSerpentine_SkCubicType; |
| 673 } else if (discr < -SK_ScalarNearlyZero) { |
| 674 return kLoop_SkCubicType; |
| 675 } else { |
| 676 if (0.f == d[0] && 0.f == d[1]) { |
| 677 return (0.f == d[2] ? kLine_SkCubicType : kQuadratic_SkCubicType); |
| 678 } else { |
| 679 return kCusp_SkCubicType; |
| 680 } |
| 681 } |
| 682 } |
| 683 |
| 684 // Assumes the third component of points is 1. |
| 685 // Calcs p0 . (p1 x p2) |
| 686 static SkScalar calc_dot_cross_cubic(const SkPoint& p0, const SkPoint& p1, const
SkPoint& p2) { |
| 687 const SkScalar xComp = p0.fX * (p1.fY - p2.fY); |
| 688 const SkScalar yComp = p0.fY * (p2.fX - p1.fX); |
| 689 const SkScalar wComp = p1.fX * p2.fY - p1.fY * p2.fX; |
| 690 return (xComp + yComp + wComp); |
| 691 } |
| 692 |
| 693 // Calc coefficients of I(s,t) where roots of I are inflection points of curve |
| 694 // I(s,t) = t*(3*d0*s^2 - 3*d1*s*t + d2*t^2) |
| 695 // d0 = a1 - 2*a2+3*a3 |
| 696 // d1 = -a2 + 3*a3 |
| 697 // d2 = 3*a3 |
| 698 // a1 = p0 . (p3 x p2) |
| 699 // a2 = p1 . (p0 x p3) |
| 700 // a3 = p2 . (p1 x p0) |
| 701 // Places the values of d1, d2, d3 in array d passed in |
| 702 static void calc_cubic_inflection_func(const SkPoint p[4], SkScalar d[3]) { |
| 703 SkScalar a1 = calc_dot_cross_cubic(p[0], p[3], p[2]); |
| 704 SkScalar a2 = calc_dot_cross_cubic(p[1], p[0], p[3]); |
| 705 SkScalar a3 = calc_dot_cross_cubic(p[2], p[1], p[0]); |
| 706 |
| 707 // need to scale a's or values in later calculations will grow to high |
| 708 SkScalar max = SkScalarAbs(a1); |
| 709 max = SkMaxScalar(max, SkScalarAbs(a2)); |
| 710 max = SkMaxScalar(max, SkScalarAbs(a3)); |
| 711 max = 1.f/max; |
| 712 a1 = a1 * max; |
| 713 a2 = a2 * max; |
| 714 a3 = a3 * max; |
| 715 |
| 716 d[2] = 3.f * a3; |
| 717 d[1] = d[2] - a2; |
| 718 d[0] = d[1] - a2 + a1; |
| 719 } |
| 720 |
| 721 SkCubicType SkClassifyCubic(const SkPoint src[4], SkScalar d[3]) { |
| 722 calc_cubic_inflection_func(src, d); |
| 723 return classify_cubic(src, d); |
| 724 } |
| 725 |
657 template <typename T> void bubble_sort(T array[], int count) { | 726 template <typename T> void bubble_sort(T array[], int count) { |
658 for (int i = count - 1; i > 0; --i) | 727 for (int i = count - 1; i > 0; --i) |
659 for (int j = i; j > 0; --j) | 728 for (int j = i; j > 0; --j) |
660 if (array[j] < array[j-1]) | 729 if (array[j] < array[j-1]) |
661 { | 730 { |
662 T tmp(array[j]); | 731 T tmp(array[j]); |
663 array[j] = array[j-1]; | 732 array[j] = array[j-1]; |
664 array[j-1] = tmp; | 733 array[j-1] = tmp; |
665 } | 734 } |
666 } | 735 } |
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1459 } | 1528 } |
1460 | 1529 |
1461 void SkConic::computeFastBounds(SkRect* bounds) const { | 1530 void SkConic::computeFastBounds(SkRect* bounds) const { |
1462 bounds->set(fPts, 3); | 1531 bounds->set(fPts, 3); |
1463 } | 1532 } |
1464 | 1533 |
1465 bool SkConic::findMaxCurvature(SkScalar* t) const { | 1534 bool SkConic::findMaxCurvature(SkScalar* t) const { |
1466 // TODO: Implement me | 1535 // TODO: Implement me |
1467 return false; | 1536 return false; |
1468 } | 1537 } |
OLD | NEW |