feat: use cubic interpolation in minitouch swipe

This commit is contained in:
Horror Proton
2022-11-15 11:33:29 +08:00
parent 44dad17b08
commit af981d43bf
7 changed files with 49 additions and 35 deletions

View File

@@ -1016,7 +1016,8 @@ bool asst::Controller::click_without_scale(const Rect& rect)
return click_without_scale(rand_point_in_rect(rect));
}
bool asst::Controller::swipe(const Point& p1, const Point& p2, int duration, bool extra_swipe, double acceleration_coef)
bool asst::Controller::swipe(const Point& p1, const Point& p2, int duration, bool extra_swipe, double slope_in,
double slope_out)
{
int x1 = static_cast<int>(p1.x * m_control_scale);
int y1 = static_cast<int>(p1.y * m_control_scale);
@@ -1024,16 +1025,17 @@ bool asst::Controller::swipe(const Point& p1, const Point& p2, int duration, boo
int y2 = static_cast<int>(p2.y * m_control_scale);
// log.trace("Swipe, raw:", p1.x, p1.y, p2.x, p2.y, "corr:", x1, y1, x2, y2);
return swipe_without_scale(Point(x1, y1), Point(x2, y2), duration, extra_swipe, acceleration_coef);
return swipe_without_scale(Point(x1, y1), Point(x2, y2), duration, extra_swipe, slope_in, slope_out);
}
bool asst::Controller::swipe(const Rect& r1, const Rect& r2, int duration, bool extra_swipe, double acceleration_coef)
bool asst::Controller::swipe(const Rect& r1, const Rect& r2, int duration, bool extra_swipe, double slope_in,
double slope_out)
{
return swipe(rand_point_in_rect(r1), rand_point_in_rect(r2), duration, extra_swipe, acceleration_coef);
return swipe(rand_point_in_rect(r1), rand_point_in_rect(r2), duration, extra_swipe, slope_in, slope_out);
}
bool asst::Controller::swipe_without_scale(const Point& p1, const Point& p2, int duration, bool extra_swipe,
double acceleration_coef)
double slope_in, double slope_out)
{
int x1 = p1.x, y1 = p1.y;
int x2 = p2.x, y2 = p2.y;
@@ -1052,16 +1054,21 @@ bool asst::Controller::swipe_without_scale(const Point& p1, const Point& p2, int
if (duration == 0) {
duration = 150;
}
auto minitouch_move = [&](int _x1, int _y1, int _x2, int _y2, int _duration) {
double accelerationx = acceleration_coef * static_cast<double>(_x2 - _x1) / (_duration * _duration);
double accelerationy = acceleration_coef * static_cast<double>(_y2 - _y1) / (_duration * _duration);
double v0x = static_cast<double>(_x2 - _x1) / _duration - accelerationx * _duration;
double v0y = static_cast<double>(_y2 - _y1) / _duration - accelerationy * _duration;
constexpr int TimeInterval = Minitoucher::DefaultSwipeDelay;
constexpr int TimeInterval = Minitoucher::DefaultSwipeDelay;
auto cubic_spline = [](double slope_0, double slope_1, double t) {
const double a = slope_0;
const double b = -(2 * slope_0 + slope_1 - 3);
const double c = -(-slope_0 - slope_1 + 2);
return a * t + b * std::pow(t, 2) + c * std::pow(t, 3);
}; // TODO: move this to math.hpp
auto minitouch_move = [&](int _x1, int _y1, int _x2, int _y2, int _duration) {
for (int cur_time = TimeInterval; cur_time < _duration; cur_time += TimeInterval) {
int cur_x = _x1 + static_cast<int>(v0x * cur_time + accelerationx * cur_time * cur_time);
int cur_y = _y1 + static_cast<int>(v0y * cur_time + accelerationy * cur_time * cur_time);
double progress = cubic_spline(slope_in, slope_out, static_cast<double>(cur_time) / duration);
int cur_x = static_cast<int>(std::lerp(_x1, _x2, progress));
int cur_y = static_cast<int>(std::lerp(_y1, _y2, progress));
if (cur_x < 0 || cur_x > m_minitouch_props.max_x || cur_y < 0 || cur_y > m_minitouch_props.max_y) {
continue;
}
@@ -1108,11 +1115,10 @@ bool asst::Controller::swipe_without_scale(const Point& p1, const Point& p2, int
}
}
bool asst::Controller::swipe_without_scale(const Rect& r1, const Rect& r2, int duration, bool extra_swipe,
double acceleration_coef)
bool asst::Controller::swipe_without_scale(const Rect& r1, const Rect& r2, int duration, bool extra_swipe, double v0,
double v1)
{
return swipe_without_scale(rand_point_in_rect(r1), rand_point_in_rect(r2), duration, extra_swipe,
acceleration_coef);
return swipe_without_scale(rand_point_in_rect(r1), rand_point_in_rect(r2), duration, extra_swipe, v0, v1);
}
bool asst::Controller::connect(const std::string& adb_path, const std::string& address, const std::string& config)

View File

@@ -57,14 +57,14 @@ namespace asst
bool click_without_scale(const Point& p);
bool click_without_scale(const Rect& rect);
bool swipe(const Point& p1, const Point& p2, int duration = 0, bool extra_swipe = false,
double acceleration_coef = 0);
bool swipe(const Rect& r1, const Rect& r2, int duration = 0, bool extra_swipe = false,
double acceleration_coef = 0);
bool swipe(const Point& p1, const Point& p2, int duration = 0, bool extra_swipe = false, double slope_in = 1,
double slope_out = 1);
bool swipe(const Rect& r1, const Rect& r2, int duration = 0, bool extra_swipe = false, double slope_in = 1,
double slope_out = 1);
bool swipe_without_scale(const Point& p1, const Point& p2, int duration = 0, bool extra_swipe = false,
double acceleration_coef = 0);
double slope_in = 1, double slope_out = 1);
bool swipe_without_scale(const Rect& r1, const Rect& r2, int duration = 0, bool extra_swipe = false,
double acceleration_coef = 0);
double slope_in = 1, double slope_out = 1);
std::pair<int, int> get_scale_size() const noexcept;

View File

@@ -721,7 +721,7 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle()
placed_point, { opt_oper.rect.x + opt_oper.rect.width / 2, opt_oper.rect.y + opt_oper.rect.height / 2 }));
// 1000 是随便取的一个系数,把整数的 pre_delay 转成小数用的
int duration = static_cast<int>(dist / 800.0 * swipe_oper_task_ptr->pre_delay);
m_ctrler->swipe(opt_oper.rect, placed_rect, duration);
m_ctrler->swipe(opt_oper.rect, placed_rect, duration, false, 0, 0);
sleep(use_oper_task_ptr->post_delay);
// 将方向转换为实际的 swipe end 坐标点

View File

@@ -548,7 +548,7 @@ bool asst::BattleProcessTask::oper_deploy(const BattleAction& action, bool only_
Point::distance(placed_point, { oper_rect.x + oper_rect.width / 2, oper_rect.y + oper_rect.height / 2 }));
// 1000 是随便取的一个系数,把整数的 pre_delay 转成小数用的
int duration = static_cast<int>(dist / 800.0 * swipe_oper_task_ptr->pre_delay);
m_ctrler->swipe(oper_rect, placed_rect, duration);
m_ctrler->swipe(oper_rect, placed_rect, duration, false, 0, 0);
sleep(use_oper_task_ptr->post_delay);

View File

@@ -187,7 +187,8 @@ bool ProcessTask::_run()
exec_swipe_task(m_cur_task_ptr->specific_rect, m_cur_task_ptr->rect_move,
m_cur_task_ptr->special_params.empty() ? 0 : m_cur_task_ptr->special_params.at(0),
(m_cur_task_ptr->special_params.size() < 2) ? false : m_cur_task_ptr->special_params.at(1),
(m_cur_task_ptr->special_params.size() < 3) ? 0 : m_cur_task_ptr->special_params.at(2));
(m_cur_task_ptr->special_params.size() < 3) ? 1 : m_cur_task_ptr->special_params.at(2),
(m_cur_task_ptr->special_params.size() < 4) ? 1 : m_cur_task_ptr->special_params.at(3));
break;
case ProcessTaskAction::DoNothing:
break;
@@ -306,9 +307,9 @@ void ProcessTask::exec_click_task(const Rect& matched_rect)
m_ctrler->click(matched_rect);
}
void asst::ProcessTask::exec_swipe_task(const Rect& r1, const Rect& r2, int duration, bool extra_swipe,
double acceleration_coef)
void asst::ProcessTask::exec_swipe_task(const Rect& r1, const Rect& r2, int duration, bool extra_swipe, double slope_in,
double slope_out)
{
MinitouchTempSwitcher switcher(m_ctrler);
m_ctrler->swipe(r1, r2, duration, extra_swipe, acceleration_coef);
m_ctrler->swipe(r1, r2, duration, extra_swipe, slope_in, slope_out);
}

View File

@@ -42,7 +42,8 @@ namespace asst
std::pair<int, TimesLimitType> calc_time_limit() const;
void exec_click_task(const Rect& matched_rect);
void exec_swipe_task(const Rect& r1, const Rect& r2, int duration, bool extra_swipe, double acceleration_coef);
void exec_swipe_task(const Rect& r1, const Rect& r2, int duration, bool extra_swipe, double slope_in,
double slope_out);
std::shared_ptr<TaskInfo> m_cur_task_ptr = nullptr;
std::vector<std::string> m_raw_tasks_name;