base: Change DCHECK_IS_ON to a macro DCHECK_IS_ON().
[chromium-blink-merge.git] / ui / events / gestures / fling_curve.cc
blob00d29a46fd56439cf822beb806376a3c53a7377f
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"
7 #include <algorithm>
8 #include <cmath>
10 #include "base/logging.h"
12 namespace {
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 -
20 kDefaultAlpha;
23 inline double GetVelocityAtTime(double t) {
24 return -kDefaultAlpha * kDefaultGamma * exp(-kDefaultGamma * t) -
25 kDefaultBeta;
28 inline double GetTimeAtVelocity(double v) {
29 return -log((v + kDefaultBeta) / (-kDefaultAlpha * kDefaultGamma)) /
30 kDefaultGamma;
33 } // namespace
35 namespace ui {
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_),
42 time_offset_(0),
43 position_offset_(0) {
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) {
62 DCHECK(offset);
63 DCHECK(velocity);
64 base::TimeDelta elapsed_time = time - start_timestamp_;
65 if (elapsed_time < base::TimeDelta()) {
66 *offset = gfx::Vector2dF();
67 *velocity = gfx::Vector2dF();
68 return true;
71 bool still_active = true;
72 float scalar_offset;
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);
78 } else {
79 scalar_offset = GetPositionAtTime(curve_duration_) - position_offset_;
80 scalar_velocity = 0;
81 still_active = false;
84 *offset = gfx::ScaleVector2d(displacement_ratio_, scalar_offset);
85 *velocity = gfx::ScaleVector2d(displacement_ratio_, scalar_velocity);
86 return still_active;
89 bool FlingCurve::ComputeScrollDeltaAtTime(base::TimeTicks current,
90 gfx::Vector2dF* delta) {
91 DCHECK(delta);
92 if (current <= previous_timestamp_) {
93 *delta = gfx::Vector2dF();
94 return true;
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;
104 return still_active;
107 } // namespace ui