Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1028)

Side by Side Diff: third_party/WebKit/Source/platform/animation/UnitBezier.h

Issue 1846733003: UI GFX Geometry: Make UnitBezier a wrapper for gfx::CubicBezier (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add one more TODO for Range. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 // Use of this source code is governed by a BSD-style license that can be
3 * 3 // found in the LICENSE file.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25 4
26 #ifndef UnitBezier_h 5 #ifndef UnitBezier_h
27 #define UnitBezier_h 6 #define UnitBezier_h
28 7
29 #include "platform/PlatformExport.h" 8 #include "ui/gfx/geometry/cubic_bezier.h"
30 #include "wtf/Allocator.h" 9 #include "wtf/Allocator.h"
31 #include "wtf/Assertions.h"
32
33 #include <algorithm>
34 #include <cmath>
35 10
36 namespace blink { 11 namespace blink {
37 12
38 struct PLATFORM_EXPORT UnitBezier { 13 // TODO(loyso): Erase blink::UnitBezier and use gfx::CubicBezier directly.
14 struct UnitBezier {
39 USING_FAST_MALLOC(UnitBezier); 15 USING_FAST_MALLOC(UnitBezier);
40 public: 16 public:
41 UnitBezier(double p1x, double p1y, double p2x, double p2y); 17 UnitBezier(double p1x, double p1y, double p2x, double p2y)
42 18 : m_cubicBezier(p1x, p1y, p2x, p2y)
43 static const double kBezierEpsilon; 19 {
20 }
44 21
45 double sampleCurveX(double t) const 22 double sampleCurveX(double t) const
46 { 23 {
47 // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule. 24 return m_cubicBezier.SampleCurveX(t);
48 return ((ax * t + bx) * t + cx) * t;
49 } 25 }
50 26
51 double sampleCurveY(double t) const 27 double sampleCurveY(double t) const
52 { 28 {
53 return ((ay * t + by) * t + cy) * t; 29 return m_cubicBezier.SampleCurveY(t);
54 }
55
56 double sampleCurveDerivativeX(double t) const
57 {
58 return (3.0 * ax * t + 2.0 * bx) * t + cx;
59 }
60
61 double sampleCurveDerivativeY(double t) const
62 {
63 return (3.0 * ay * t + 2.0 * by) * t + cy;
64 }
65
66 // Given an x value, find a parametric value it came from.
67 double solveCurveX(double x, double epsilon) const
68 {
69 ASSERT(x >= 0.0);
70 ASSERT(x <= 1.0);
71
72 double t0;
73 double t1;
74 double t2;
75 double x2;
76 double d2;
77 int i;
78
79 // First try a few iterations of Newton's method -- normally very fast.
80 for (t2 = x, i = 0; i < 8; i++) {
81 x2 = sampleCurveX(t2) - x;
82 if (fabs (x2) < epsilon)
83 return t2;
84 d2 = sampleCurveDerivativeX(t2);
85 if (fabs(d2) < 1e-6)
86 break;
87 t2 = t2 - x2 / d2;
88 }
89
90 // Fall back to the bisection method for reliability.
91 t0 = 0.0;
92 t1 = 1.0;
93 t2 = x;
94
95 while (t0 < t1) {
96 x2 = sampleCurveX(t2);
97 if (fabs(x2 - x) < epsilon)
98 return t2;
99 if (x > x2)
100 t0 = t2;
101 else
102 t1 = t2;
103 t2 = (t1 - t0) * .5 + t0;
104 }
105
106 // Failure.
107 return t2;
108 } 30 }
109 31
110 // Evaluates y at the given x. 32 // Evaluates y at the given x.
111 double solve(double x) const 33 double solve(double x) const
112 { 34 {
113 return solveWithEpsilon(x, kBezierEpsilon); 35 return m_cubicBezier.Solve(x);
114 } 36 }
115 37
116 // Evaluates y at the given x. The epsilon parameter provides a hint as to t he required 38 // Evaluates y at the given x. The epsilon parameter provides a hint as to t he required
117 // accuracy and is not guaranteed. 39 // accuracy and is not guaranteed.
118 double solveWithEpsilon(double x, double epsilon) const 40 double solveWithEpsilon(double x, double epsilon) const
119 { 41 {
120 if (x < 0.0) 42 return m_cubicBezier.SolveWithEpsilon(x, epsilon);
121 return 0.0 + m_startGradient * x;
122 if (x > 1.0)
123 return 1.0 + m_endGradient * (x - 1.0);
124 return sampleCurveY(solveCurveX(x, epsilon));
125 }
126
127 // Returns an approximation of dy/dx at the given x.
128 double slope(double x) const
129 {
130 return slopeWithEpsilon(x, kBezierEpsilon);
131 }
132
133 double slopeWithEpsilon(double x, double epsilon) const
134 {
135 double t = solveCurveX(x, epsilon);
136 double dx = sampleCurveDerivativeX(t);
137 double dy = sampleCurveDerivativeY(t);
138 return dy / dx;
139 }
140
141 // Sets |min| and |max| to the bezier's minimum and maximium y values in the
142 // interval [0, 1].
143 void range(double* min, double* max) const
144 {
145 *min = m_rangeMin;
146 *max = m_rangeMax;
147 } 43 }
148 44
149 private: 45 private:
150 void initCoefficients(double p1x, double p1y, double p2x, double p2y); 46 gfx::CubicBezier m_cubicBezier;
151 void initGradients(double p1x, double p1y, double p2x, double p2y);
152 void initRange(double p1y, double p2y);
153
154 double ax;
155 double bx;
156 double cx;
157
158 double ay;
159 double by;
160 double cy;
161
162 double m_startGradient;
163 double m_endGradient;
164
165 double m_rangeMin;
166 double m_rangeMax;
167 }; 47 };
168 48
169 } // namespace blink 49 } // namespace blink
170 50
171 #endif // UnitBezier_h 51 #endif // UnitBezier_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/core.gyp ('k') | third_party/WebKit/Source/platform/animation/UnitBezier.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698