1886da342Sopenharmony_ci/*
2886da342Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3886da342Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4886da342Sopenharmony_ci * you may not use this file except in compliance with the License.
5886da342Sopenharmony_ci * You may obtain a copy of the License at
6886da342Sopenharmony_ci *
7886da342Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8886da342Sopenharmony_ci *
9886da342Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10886da342Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11886da342Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12886da342Sopenharmony_ci * See the License for the specific language governing permissions and
13886da342Sopenharmony_ci * limitations under the License.
14886da342Sopenharmony_ci */
15886da342Sopenharmony_ci
16886da342Sopenharmony_ci#ifndef VELOCITY_TRACKER_H
17886da342Sopenharmony_ci#define VELOCITY_TRACKER_H
18886da342Sopenharmony_ci#include <regex>
19886da342Sopenharmony_ci#include <cmath>
20886da342Sopenharmony_ci#include <atomic>
21886da342Sopenharmony_ci#include "least_square_impl.h"
22886da342Sopenharmony_ci#include "touch_event.h"
23886da342Sopenharmony_ci#include "offset.h"
24886da342Sopenharmony_ci#include "velocity.h"
25886da342Sopenharmony_ci
26886da342Sopenharmony_cinamespace OHOS::uitest {
27886da342Sopenharmony_cienum class Axis {
28886da342Sopenharmony_ci    VERTICAL = 0,
29886da342Sopenharmony_ci    HORIZONTAL,
30886da342Sopenharmony_ci    FREE,
31886da342Sopenharmony_ci    NONE,
32886da342Sopenharmony_ci};
33886da342Sopenharmony_ciclass VelocityTracker final {
34886da342Sopenharmony_cipublic:
35886da342Sopenharmony_ci    VelocityTracker() = default;
36886da342Sopenharmony_ci    explicit VelocityTracker(Axis mainAxis) : mainAxis_(mainAxis) {}
37886da342Sopenharmony_ci    ~VelocityTracker() = default;
38886da342Sopenharmony_ci
39886da342Sopenharmony_ci    static constexpr int TIME_INDEX = 1000;
40886da342Sopenharmony_ci    void TrackResets()
41886da342Sopenharmony_ci    {
42886da342Sopenharmony_ci        lastTrackPoint_.Resets();
43886da342Sopenharmony_ci    }
44886da342Sopenharmony_ci
45886da342Sopenharmony_ci    void UpdateTouchEvent(const TouchEventInfo& event, bool end = false);
46886da342Sopenharmony_ci
47886da342Sopenharmony_ci    void SetMainVelocity(double mainVelocity)
48886da342Sopenharmony_ci    {
49886da342Sopenharmony_ci        mainVelocity_ = mainVelocity;
50886da342Sopenharmony_ci    }
51886da342Sopenharmony_ci
52886da342Sopenharmony_ci    int GetStepCount() const
53886da342Sopenharmony_ci    {
54886da342Sopenharmony_ci        return xAxis_.GetPVals().size();
55886da342Sopenharmony_ci    }
56886da342Sopenharmony_ci
57886da342Sopenharmony_ci    void UpdateStepLength()
58886da342Sopenharmony_ci    {
59886da342Sopenharmony_ci        stepCount = GetStepCount();
60886da342Sopenharmony_ci        std::vector<double> xs = xAxis_.GetPVals();
61886da342Sopenharmony_ci        std::vector<double> ys = yAxis_.GetPVals();
62886da342Sopenharmony_ci        if (stepCount == 1) {
63886da342Sopenharmony_ci            return;
64886da342Sopenharmony_ci        }
65886da342Sopenharmony_ci        if (stepCount < useToCount) {
66886da342Sopenharmony_ci            useToCount = stepCount;
67886da342Sopenharmony_ci        }
68886da342Sopenharmony_ci        for (int i = 1; i < useToCount; i++) {
69886da342Sopenharmony_ci            totalDelta_ += Offset(xs.at(stepCount - i), ys.at(stepCount - i)) - \
70886da342Sopenharmony_ci                            Offset(xs.at(stepCount - i - 1), ys.at(stepCount - i - 1));
71886da342Sopenharmony_ci        }
72886da342Sopenharmony_ci        stepLength = (totalDelta_ / (useToCount - 1)).GetDistance();
73886da342Sopenharmony_ci    }
74886da342Sopenharmony_ci
75886da342Sopenharmony_ci    int GetStepLength()
76886da342Sopenharmony_ci    {
77886da342Sopenharmony_ci        UpdateStepLength();
78886da342Sopenharmony_ci        return stepLength;
79886da342Sopenharmony_ci    }
80886da342Sopenharmony_ci
81886da342Sopenharmony_ci    const Point& GetPosition() const
82886da342Sopenharmony_ci    {
83886da342Sopenharmony_ci        return lastPosition_;
84886da342Sopenharmony_ci    }
85886da342Sopenharmony_ci
86886da342Sopenharmony_ci    const Point& GetFirstPosition() const
87886da342Sopenharmony_ci    {
88886da342Sopenharmony_ci        return firstPosition_;
89886da342Sopenharmony_ci    }
90886da342Sopenharmony_ci
91886da342Sopenharmony_ci    const Offset& GetDelta() const
92886da342Sopenharmony_ci    {
93886da342Sopenharmony_ci        return delta_;
94886da342Sopenharmony_ci    }
95886da342Sopenharmony_ci
96886da342Sopenharmony_ci    const Velocity& GetVelo()
97886da342Sopenharmony_ci    {
98886da342Sopenharmony_ci        UpdateVelocity();
99886da342Sopenharmony_ci        return velocity_;
100886da342Sopenharmony_ci    }
101886da342Sopenharmony_ci
102886da342Sopenharmony_ci    double GetMainVelocity() const
103886da342Sopenharmony_ci    {
104886da342Sopenharmony_ci        return mainVelocity_;
105886da342Sopenharmony_ci    }
106886da342Sopenharmony_ci
107886da342Sopenharmony_ci    Axis GetMaxAxis()
108886da342Sopenharmony_ci    {
109886da342Sopenharmony_ci        UpdateVelocity();
110886da342Sopenharmony_ci        if (fabs(velocity_.GetVeloX()) > fabs(velocity_.GetVeloY())) {
111886da342Sopenharmony_ci            maxAxis_ = Axis::HORIZONTAL;
112886da342Sopenharmony_ci        } else {
113886da342Sopenharmony_ci            maxAxis_ = Axis::VERTICAL;
114886da342Sopenharmony_ci        }
115886da342Sopenharmony_ci        return maxAxis_;
116886da342Sopenharmony_ci    }
117886da342Sopenharmony_ci
118886da342Sopenharmony_ci    double GetMainAxisDeltaPos() const
119886da342Sopenharmony_ci    {
120886da342Sopenharmony_ci        switch (mainAxis_) {
121886da342Sopenharmony_ci            case Axis::FREE:
122886da342Sopenharmony_ci                return delta_.GetDistance();
123886da342Sopenharmony_ci            case Axis::HORIZONTAL:
124886da342Sopenharmony_ci                return delta_.GetX();
125886da342Sopenharmony_ci            case Axis::VERTICAL:
126886da342Sopenharmony_ci                return delta_.GetY();
127886da342Sopenharmony_ci            default:
128886da342Sopenharmony_ci                return 0.0;
129886da342Sopenharmony_ci        }
130886da342Sopenharmony_ci    }
131886da342Sopenharmony_ci
132886da342Sopenharmony_ci    double GetMainAxisVelocity()
133886da342Sopenharmony_ci    {
134886da342Sopenharmony_ci        UpdateVelocity();
135886da342Sopenharmony_ci        switch (mainAxis_) {
136886da342Sopenharmony_ci            case Axis::FREE:
137886da342Sopenharmony_ci                mainVelocity_ =  velocity_.GetVeloValue();
138886da342Sopenharmony_ci                break;
139886da342Sopenharmony_ci            case Axis::HORIZONTAL:
140886da342Sopenharmony_ci                mainVelocity_ = velocity_.GetVeloX();
141886da342Sopenharmony_ci                break;
142886da342Sopenharmony_ci            case Axis::VERTICAL:
143886da342Sopenharmony_ci                mainVelocity_ = velocity_.GetVeloY();
144886da342Sopenharmony_ci                break;
145886da342Sopenharmony_ci            default:
146886da342Sopenharmony_ci                mainVelocity_ = 0.0;
147886da342Sopenharmony_ci        }
148886da342Sopenharmony_ci        return mainVelocity_;
149886da342Sopenharmony_ci    }
150886da342Sopenharmony_ci
151886da342Sopenharmony_ci    TouchEventInfo& GetLastTrackPoint()
152886da342Sopenharmony_ci    {
153886da342Sopenharmony_ci        return lastTrackPoint_;
154886da342Sopenharmony_ci    }
155886da342Sopenharmony_ci
156886da342Sopenharmony_ci    void SetClickInterVal(double interVal)
157886da342Sopenharmony_ci    {
158886da342Sopenharmony_ci        clickInterVal = interVal;
159886da342Sopenharmony_ci    }
160886da342Sopenharmony_ci
161886da342Sopenharmony_ci    TimeStamp GetLastTimePoint()
162886da342Sopenharmony_ci    {
163886da342Sopenharmony_ci        return lastTimePoint_;
164886da342Sopenharmony_ci    }
165886da342Sopenharmony_ci
166886da342Sopenharmony_ci    int GetAxisSize()
167886da342Sopenharmony_ci    {
168886da342Sopenharmony_ci        return xAxis_.GetTVals().size();
169886da342Sopenharmony_ci    }
170886da342Sopenharmony_ci
171886da342Sopenharmony_ci    double GetPreTime(int num)
172886da342Sopenharmony_ci    {
173886da342Sopenharmony_ci        return xAxis_.GetTVals().at(xAxis_.GetTVals().size() - num);
174886da342Sopenharmony_ci    }
175886da342Sopenharmony_ci
176886da342Sopenharmony_ci    double GetPreX(int num)
177886da342Sopenharmony_ci    {
178886da342Sopenharmony_ci        return xAxis_.GetPVals().at(xAxis_.GetPVals().size() - num);
179886da342Sopenharmony_ci    }
180886da342Sopenharmony_ci
181886da342Sopenharmony_ci    double GetPreY(int num)
182886da342Sopenharmony_ci    {
183886da342Sopenharmony_ci        return yAxis_.GetPVals().at(yAxis_.GetPVals().size() - num);
184886da342Sopenharmony_ci    }
185886da342Sopenharmony_ci
186886da342Sopenharmony_ciprivate:
187886da342Sopenharmony_ci    void UpdateVelocity();
188886da342Sopenharmony_ci    Axis mainAxis_ { Axis::FREE };
189886da342Sopenharmony_ci    Axis maxAxis_  {Axis::VERTICAL };
190886da342Sopenharmony_ci    TouchEventInfo lastTrackPoint_;
191886da342Sopenharmony_ci    Point firstPosition_;
192886da342Sopenharmony_ci    Point lastPosition_;
193886da342Sopenharmony_ci    Offset totalDelta_;
194886da342Sopenharmony_ci    Velocity velocity_;
195886da342Sopenharmony_ci    double mainVelocity_ = 0.0;
196886da342Sopenharmony_ci    Offset delta_;
197886da342Sopenharmony_ci    bool isFirstPoint_ = true;
198886da342Sopenharmony_ci    int useToCount = 4;
199886da342Sopenharmony_ci    int stepLength = 0;
200886da342Sopenharmony_ci    int stepCount = 0;
201886da342Sopenharmony_ci    TimeStamp firstTimePoint_;
202886da342Sopenharmony_ci    TimeStamp lastTimePoint_;
203886da342Sopenharmony_ci    LeastSquareImpl xAxis_ { 3, 5 };
204886da342Sopenharmony_ci    LeastSquareImpl yAxis_ { 3, 5 };
205886da342Sopenharmony_ci    bool isVelocityDone_ = false;
206886da342Sopenharmony_ci    double clickInterVal = 0;
207886da342Sopenharmony_ci};
208886da342Sopenharmony_ci} // namespace OHOS::uitest
209886da342Sopenharmony_ci#endif // VELOCITY_TRACKER_H