1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/gestures/velocity_tracker.h"
17
18 #include <chrono>
19
20 namespace OHOS::Ace {
21
UpdateTouchPoint(const TouchEvent & event,bool end)22 void VelocityTracker::UpdateTouchPoint(const TouchEvent& event, bool end)
23 {
24 isVelocityDone_ = false;
25 currentTrackPoint_ = event;
26 if (isFirstPoint_) {
27 firstTrackPoint_ = event;
28 isFirstPoint_ = false;
29 } else {
30 delta_ = event.GetOffset() - lastPosition_;
31 lastPosition_ = event.GetOffset();
32 }
33 std::chrono::duration<double> diffTime = event.time - lastTimePoint_;
34 lastTimePoint_ = event.time;
35 lastPosition_ = event.GetOffset();
36 // judge duration is 500ms.
37 static const double range = 0.5;
38 if (delta_.IsZero() && end && (diffTime.count() < range)) {
39 return;
40 }
41 // nanoseconds duration to seconds.
42 std::chrono::duration<double> duration = event.time - firstTrackPoint_.time;
43 auto seconds = duration.count();
44 xAxis_.UpdatePoint(seconds, event.x);
45 yAxis_.UpdatePoint(seconds, event.y);
46 }
47
UpdateTrackerPoint(double x,double y,const TimeStamp & time,bool end)48 void VelocityTracker::UpdateTrackerPoint(double x, double y, const TimeStamp& time, bool end)
49 {
50 Offset trackerPoint(x, y);
51 isVelocityDone_ = false;
52 if (isFirstPoint_) {
53 firstPointTime_ = time;
54 isFirstPoint_ = false;
55 } else {
56 delta_ = trackerPoint - lastPosition_;
57 lastPosition_ = trackerPoint;
58 }
59 std::chrono::duration<double> diffTime = time - lastTimePoint_;
60 lastTimePoint_ = time;
61 lastPosition_ = trackerPoint;
62 // judge duration is 500ms.
63 static const double range = 0.5;
64 if (delta_.IsZero() && end && (diffTime.count() < range)) {
65 return;
66 }
67 // nanoseconds duration to seconds.
68 std::chrono::duration<double> duration = time - firstPointTime_;
69 auto seconds = duration.count();
70 xAxis_.UpdatePoint(seconds, x);
71 yAxis_.UpdatePoint(seconds, y);
72 }
73
UpdateVelocity()74 void VelocityTracker::UpdateVelocity()
75 {
76 if (isVelocityDone_) {
77 return;
78 }
79 // the least square method three params curve is 0 * x^3 + a2 * x^2 + a1 * x + a0
80 // the velocity is 2 * a2 * x + a1;
81 static const int32_t linearParam = 2;
82 std::vector<double> xAxis { 3, 0 };
83 auto xValue = xAxis_.GetXVals().back();
84 double xVelocity = 0.0;
85 if (xAxis_.GetLeastSquareParams(xAxis)) {
86 xVelocity = linearParam * xAxis[0] * xValue + xAxis[1];
87 }
88 std::vector<double> yAxis { 3, 0 };
89 auto yValue = yAxis_.GetXVals().back();
90 double yVelocity = 0.0;
91 if (yAxis_.GetLeastSquareParams(yAxis)) {
92 yVelocity = linearParam * yAxis[0] * yValue + yAxis[1];
93 }
94
95 velocity_.SetOffsetPerSecond({ xVelocity, yVelocity });
96 isVelocityDone_ = true;
97 }
98
99 } // namespace OHOS::Ace
100