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
3 // found in the LICENSE file.
5 #include "ui/events/gestures/fling_curve.h"
10 #include "base/logging.h"
14 const float kDefaultAlpha
= -5.70762e+03f
;
15 const float kDefaultBeta
= 1.72e+02f
;
16 const float kDefaultGamma
= 3.7e+00f
;
18 inline double GetPositionAtTime(double t
) {
19 return kDefaultAlpha
* exp(-kDefaultGamma
* t
) - kDefaultBeta
* t
-
23 inline double GetVelocityAtTime(double t
) {
24 return -kDefaultAlpha
* kDefaultGamma
* exp(-kDefaultGamma
* t
) -
28 inline double GetTimeAtVelocity(double v
) {
29 return -log((v
+ kDefaultBeta
) / (-kDefaultAlpha
* kDefaultGamma
)) /
37 FlingCurve::FlingCurve(const gfx::Vector2dF
& velocity
,
38 base::TimeTicks start_timestamp
)
39 : curve_duration_(GetTimeAtVelocity(0)),
40 start_timestamp_(start_timestamp
),
41 previous_timestamp_(start_timestamp_
),
44 DCHECK(!velocity
.IsZero());
45 float max_start_velocity
= std::max(fabs(velocity
.x()), fabs(velocity
.y()));
46 if (max_start_velocity
> GetVelocityAtTime(0))
47 max_start_velocity
= GetVelocityAtTime(0);
48 CHECK_GT(max_start_velocity
, 0);
50 displacement_ratio_
= gfx::Vector2dF(velocity
.x() / max_start_velocity
,
51 velocity
.y() / max_start_velocity
);
52 time_offset_
= GetTimeAtVelocity(max_start_velocity
);
53 position_offset_
= GetPositionAtTime(time_offset_
);
56 FlingCurve::~FlingCurve() {
59 bool FlingCurve::ComputeScrollOffset(base::TimeTicks time
,
60 gfx::Vector2dF
* offset
,
61 gfx::Vector2dF
* velocity
) {
64 base::TimeDelta elapsed_time
= time
- start_timestamp_
;
65 if (elapsed_time
< base::TimeDelta()) {
66 *offset
= gfx::Vector2dF();
67 *velocity
= gfx::Vector2dF();
71 bool still_active
= true;
73 float scalar_velocity
;
74 double offset_time
= elapsed_time
.InSecondsF() + time_offset_
;
75 if (offset_time
< curve_duration_
) {
76 scalar_offset
= GetPositionAtTime(offset_time
) - position_offset_
;
77 scalar_velocity
= GetVelocityAtTime(offset_time
);
79 scalar_offset
= GetPositionAtTime(curve_duration_
) - position_offset_
;
84 *offset
= gfx::ScaleVector2d(displacement_ratio_
, scalar_offset
);
85 *velocity
= gfx::ScaleVector2d(displacement_ratio_
, scalar_velocity
);
89 bool FlingCurve::ComputeScrollDeltaAtTime(base::TimeTicks current
,
90 gfx::Vector2dF
* delta
) {
92 if (current
<= previous_timestamp_
) {
93 *delta
= gfx::Vector2dF();
97 previous_timestamp_
= current
;
99 gfx::Vector2dF offset
, velocity
;
100 bool still_active
= ComputeScrollOffset(current
, &offset
, &velocity
);
102 *delta
= offset
- cumulative_scroll_
;
103 cumulative_scroll_
= offset
;