OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef UI_GFX_GEOMETRY_CUBIC_BEZIER_H_ | 5 #ifndef UI_GFX_GEOMETRY_CUBIC_BEZIER_H_ |
6 #define UI_GFX_GEOMETRY_CUBIC_BEZIER_H_ | 6 #define UI_GFX_GEOMETRY_CUBIC_BEZIER_H_ |
7 | 7 |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "ui/gfx/gfx_export.h" | 9 #include "ui/gfx/gfx_export.h" |
10 | 10 |
11 namespace gfx { | 11 namespace gfx { |
12 | 12 |
13 class GFX_EXPORT CubicBezier { | 13 class GFX_EXPORT CubicBezier { |
14 public: | 14 public: |
15 CubicBezier(double x1, double y1, double x2, double y2); | 15 CubicBezier(double p1x, double p1y, double p2x, double p2y); |
16 ~CubicBezier(); | |
17 | 16 |
18 // Returns an approximation of y at the given x. | 17 double SampleCurveX(double t) const { |
| 18 // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule. |
| 19 return ((ax_ * t + bx_) * t + cx_) * t; |
| 20 } |
| 21 |
| 22 double SampleCurveY(double t) const { |
| 23 return ((ay_ * t + by_) * t + cy_) * t; |
| 24 } |
| 25 |
| 26 double SampleCurveDerivativeX(double t) const { |
| 27 return (3.0 * ax_ * t + 2.0 * bx_) * t + cx_; |
| 28 } |
| 29 |
| 30 double SampleCurveDerivativeY(double t) const { |
| 31 return (3.0 * ay_ * t + 2.0 * by_) * t + cy_; |
| 32 } |
| 33 |
| 34 // Given an x value, find a parametric value it came from. |
| 35 double SolveCurveX(double x, double epsilon) const; |
| 36 |
| 37 // Evaluates y at the given x with default epsilon. |
19 double Solve(double x) const; | 38 double Solve(double x) const; |
20 | 39 |
| 40 // Evaluates y at the given x. The epsilon parameter provides a hint as to the |
| 41 // required accuracy and is not guaranteed. |
| 42 double SolveWithEpsilon(double x, double epsilon) const { |
| 43 if (x < 0.0) |
| 44 return 0.0 + start_gradient_ * x; |
| 45 if (x > 1.0) |
| 46 return 1.0 + end_gradient_ * (x - 1.0); |
| 47 return SampleCurveY(SolveCurveX(x, epsilon)); |
| 48 } |
| 49 |
| 50 // Returns an approximation of dy/dx at the given x with default epsilon. |
| 51 double Slope(double x) const; |
| 52 |
21 // Returns an approximation of dy/dx at the given x. | 53 // Returns an approximation of dy/dx at the given x. |
22 double Slope(double x) const; | 54 double SlopeWithEpsilon(double x, double epsilon) const { |
| 55 double t = SolveCurveX(x, epsilon); |
| 56 double dx = SampleCurveDerivativeX(t); |
| 57 double dy = SampleCurveDerivativeY(t); |
| 58 return dy / dx; |
| 59 } |
23 | 60 |
24 // Sets |min| and |max| to the bezier's minimum and maximium y values in the | 61 // Sets |min| and |max| to the bezier's minimum and maximium y values in the |
25 // interval [0, 1]. | 62 // interval [0, 1]. |
26 void Range(double* min, double* max) const; | 63 void Range(double* min, double* max) const { |
| 64 *min = range_min_; |
| 65 *max = range_max_; |
| 66 } |
27 | 67 |
28 private: | 68 private: |
29 void InitGradients(); | 69 void InitCoefficients(double p1x, double p1y, double p2x, double p2y); |
| 70 void InitGradients(double p1x, double p1y, double p2x, double p2y); |
| 71 void InitRange(double p1y, double p2y); |
30 | 72 |
31 double x1_; | 73 double ax_; |
32 double y1_; | 74 double bx_; |
33 double x2_; | 75 double cx_; |
34 double y2_; | 76 |
| 77 double ay_; |
| 78 double by_; |
| 79 double cy_; |
35 | 80 |
36 double start_gradient_; | 81 double start_gradient_; |
37 double end_gradient_; | 82 double end_gradient_; |
38 | 83 |
| 84 double range_min_; |
| 85 double range_max_; |
| 86 |
39 DISALLOW_ASSIGN(CubicBezier); | 87 DISALLOW_ASSIGN(CubicBezier); |
40 }; | 88 }; |
41 | 89 |
42 } // namespace gfx | 90 } // namespace gfx |
43 | 91 |
44 #endif // UI_GFX_GEOMETRY_CUBIC_BEZIER_H_ | 92 #endif // UI_GFX_GEOMETRY_CUBIC_BEZIER_H_ |
OLD | NEW |