OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 25 matching lines...) Expand all Loading... |
36 UnitBezier(double p1x, double p1y, double p2x, double p2y) | 36 UnitBezier(double p1x, double p1y, double p2x, double p2y) |
37 { | 37 { |
38 // Calculate the polynomial coefficients, implicit first and last contro
l points are (0,0) and (1,1). | 38 // Calculate the polynomial coefficients, implicit first and last contro
l points are (0,0) and (1,1). |
39 cx = 3.0 * p1x; | 39 cx = 3.0 * p1x; |
40 bx = 3.0 * (p2x - p1x) - cx; | 40 bx = 3.0 * (p2x - p1x) - cx; |
41 ax = 1.0 - cx -bx; | 41 ax = 1.0 - cx -bx; |
42 | 42 |
43 cy = 3.0 * p1y; | 43 cy = 3.0 * p1y; |
44 by = 3.0 * (p2y - p1y) - cy; | 44 by = 3.0 * (p2y - p1y) - cy; |
45 ay = 1.0 - cy - by; | 45 ay = 1.0 - cy - by; |
| 46 |
| 47 // End-point gradients are used to calculate timing function results |
| 48 // outside the range [0, 1]. |
| 49 // |
| 50 // There are three possibilities for the gradient at each end: |
| 51 // (1) the closest control point is not horizontally coincident with reg
ard to |
| 52 // (0, 0) or (1, 1). In this case the line between the end point and |
| 53 // the control point is tangent to the bezier at the end point. |
| 54 // (2) the closest control point is coincident with the end point. In |
| 55 // this case the line between the end point and the far control |
| 56 // point is tangent to the bezier at the end point. |
| 57 // (3) the closest control point is horizontally coincident with the end |
| 58 // point, but vertically distinct. In this case the gradient at the |
| 59 // end point is Infinite. However, this causes issues when |
| 60 // interpolating. As a result, we break down to a simple case of |
| 61 // 0 gradient under these conditions. |
| 62 |
| 63 if (p1x > 0) |
| 64 m_startGradient = p1y / p1x; |
| 65 else if (!p1y && p2x > 0) |
| 66 m_startGradient = p2y / p2x; |
| 67 else |
| 68 m_startGradient = 0; |
| 69 |
| 70 if (p2x < 1) |
| 71 m_endGradient = (p2y - 1) / (p2x - 1); |
| 72 else if (p2x == 1 && p1x < 1) |
| 73 m_endGradient = (p1y - 1) / (p1x - 1); |
| 74 else |
| 75 m_endGradient = 0; |
46 } | 76 } |
47 | 77 |
48 double sampleCurveX(double t) | 78 double sampleCurveX(double t) |
49 { | 79 { |
50 // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule. | 80 // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule. |
51 return ((ax * t + bx) * t + cx) * t; | 81 return ((ax * t + bx) * t + cx) * t; |
52 } | 82 } |
53 | 83 |
54 double sampleCurveY(double t) | 84 double sampleCurveY(double t) |
55 { | 85 { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 133 |
104 // Failure. | 134 // Failure. |
105 return t2; | 135 return t2; |
106 } | 136 } |
107 | 137 |
108 // Evaluates y at the given x. The epsilon parameter provides a hint as to t
he required | 138 // Evaluates y at the given x. The epsilon parameter provides a hint as to t
he required |
109 // accuracy and is not guaranteed. | 139 // accuracy and is not guaranteed. |
110 double solve(double x, double epsilon) | 140 double solve(double x, double epsilon) |
111 { | 141 { |
112 if (x < 0.0) | 142 if (x < 0.0) |
113 return 0.0; | 143 return 0.0 + m_startGradient * x; |
114 if (x > 1.0) | 144 if (x > 1.0) |
115 return 1.0; | 145 return 1.0 + m_endGradient * (x - 1.0); |
116 return sampleCurveY(solveCurveX(x, epsilon)); | 146 return sampleCurveY(solveCurveX(x, epsilon)); |
117 } | 147 } |
118 | 148 |
119 private: | 149 private: |
120 double ax; | 150 double ax; |
121 double bx; | 151 double bx; |
122 double cx; | 152 double cx; |
123 | 153 |
124 double ay; | 154 double ay; |
125 double by; | 155 double by; |
126 double cy; | 156 double cy; |
| 157 |
| 158 double m_startGradient; |
| 159 double m_endGradient; |
127 }; | 160 }; |
128 | 161 |
129 } // namespace WebCore | 162 } // namespace WebCore |
130 | 163 |
131 #endif // UnitBezier_h | 164 #endif // UnitBezier_h |
OLD | NEW |