C++ 使用具有设置延迟C+的鼠标事件平滑鼠标移动+;
我正在编写一个鼠标宏。它需要在每个点之间的设置延迟内满足屏幕上的某些点。例如,它必须在132ms内移动(x14,y30)。我遇到的问题是鼠标事件会跳到那个确切的位置,所以我需要包括一些平滑方法,以便它平滑地移动到每个点。(移动越平滑,宏效果越好)。目前我正在使用这种平滑每个动作的方法 这很好,但也有其局限性,例如,如果需要向左移动10个像素,并且平滑设置为20,它将继续跳跃 有人知道更精确的平滑鼠标移动的方法吗?(要求准确、流畅)C++ 使用具有设置延迟C+的鼠标事件平滑鼠标移动+;,c++,macros,mouseevent,mouse,smoothing,C++,Macros,Mouseevent,Mouse,Smoothing,我正在编写一个鼠标宏。它需要在每个点之间的设置延迟内满足屏幕上的某些点。例如,它必须在132ms内移动(x14,y30)。我遇到的问题是鼠标事件会跳到那个确切的位置,所以我需要包括一些平滑方法,以便它平滑地移动到每个点。(移动越平滑,宏效果越好)。目前我正在使用这种平滑每个动作的方法 这很好,但也有其局限性,例如,如果需要向左移动10个像素,并且平滑设置为20,它将继续跳跃 有人知道更精确的平滑鼠标移动的方法吗?(要求准确、流畅) void平滑(整数平滑、整数延迟、整数x、整数y){ 对于(in
void平滑(整数平滑、整数延迟、整数x、整数y){
对于(int i=0;i<平滑;i++){
鼠标事件(1,x/平滑,y/平滑,0,0);
准确睡眠(延迟/平滑);
}
鼠标事件(1,x%平滑,y%平滑,0,0);
睡眠(延迟%平滑);
}
将点视为向量并在它们之间插值。
这通常被称为线性插值的“lerping”排序。
如果搜索线性插值,您可以找到许多可能有帮助的资源。
下面是一些可能有助于理解它是什么的信息
因为我手头有多余的时间,所以我打了一个程序的例子,这个程序也能做到这一点
#include <iostream>
#include <chrono>
struct Vec2d {
double x;
double y;
Vec2d(double x, double y) : x(x), y(y) {};
};
Vec2d lerp(Vec2d const& a, Vec2d const& b, double t) {
double x((1.0 - t) * a.x + t * b.x);
double y((1.0 - t) * a.y + t * b.y);
return Vec2d(x, y);
}
int main(int argc, char* argv[]) {
Vec2d p1(10, 10);
Vec2d p2(20, 40);
double maxTime(100); //max time 100 milliseconds
double elapsedTime(0);
std::chrono::time_point<std::chrono::system_clock> start(std::chrono::system_clock::now());
std::chrono::time_point<std::chrono::system_clock> end(start);
while(elapsedTime < maxTime) {
elapsedTime += std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
start = end;
//This is where the lerping happens
double t(elapsedTime / maxTime);
Vec2d p3(lerp(p1, p2, t));
//Show what's happening.
std::cout << "p3: " << p3.x << ", " << p3.y << std::endl;
end = std::chrono::system_clock::now();
}
return 0;
}
#包括
#包括
结构向量2D{
双x;
双y;
Vec2d(双x,双y):x(x),y(y){};
};
Vec2d lerp(Vec2d常量a、Vec2d常量b、双t){
双x((1.0-t)*a.x+t*b.x);
双y((1.0-t)*a.y+t*b.y);
返回向量2d(x,y);
}
int main(int argc,char*argv[]){
vec2dp1(10,10);
vec2dp2(20,40);
双最大时间(100);//最大时间100毫秒
双延时(0);
std::chrono::time_point start(std::chrono::system_clock::now());
std::chrono::时间点结束(开始);
while(elapsedTime std::cout将点视为向量并在它们之间插值。
这通常被称为线性插值的“lerping”排序。
如果搜索线性插值,您可以找到许多可能有帮助的资源。
下面是一些可能有助于理解它是什么的信息
因为我手头有多余的时间,所以我打了一个程序的例子,这个程序也能做到这一点
#include <iostream>
#include <chrono>
struct Vec2d {
double x;
double y;
Vec2d(double x, double y) : x(x), y(y) {};
};
Vec2d lerp(Vec2d const& a, Vec2d const& b, double t) {
double x((1.0 - t) * a.x + t * b.x);
double y((1.0 - t) * a.y + t * b.y);
return Vec2d(x, y);
}
int main(int argc, char* argv[]) {
Vec2d p1(10, 10);
Vec2d p2(20, 40);
double maxTime(100); //max time 100 milliseconds
double elapsedTime(0);
std::chrono::time_point<std::chrono::system_clock> start(std::chrono::system_clock::now());
std::chrono::time_point<std::chrono::system_clock> end(start);
while(elapsedTime < maxTime) {
elapsedTime += std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
start = end;
//This is where the lerping happens
double t(elapsedTime / maxTime);
Vec2d p3(lerp(p1, p2, t));
//Show what's happening.
std::cout << "p3: " << p3.x << ", " << p3.y << std::endl;
end = std::chrono::system_clock::now();
}
return 0;
}
#包括
#包括
结构向量2D{
双x;
双y;
Vec2d(双x,双y):x(x),y(y){};
};
Vec2d lerp(Vec2d常量a、Vec2d常量b、双t){
双x((1.0-t)*a.x+t*b.x);
双y((1.0-t)*a.y+t*b.y);
返回向量2d(x,y);
}
int main(int argc,char*argv[]){
vec2dp1(10,10);
vec2dp2(20,40);
双最大时间(100);//最大时间100毫秒
双延时(0);
std::chrono::time_point start(std::chrono::system_clock::now());
std::chrono::时间点结束(开始);
while(elapsedTime
插值的一般公式为:
x=(1-t)·x0+t·x1
x…插值
x0…开始值
x1…目标值
t…插值参数在[0,1]范围内
当我意识到一些可能形成约束的事实时,我甚至打算写这篇文章作为答案(遗憾的是,OP没有明确提到)
所有的运算都是关于整数值的。所以,做整数运算可能是首选
使用增量值调用鼠标事件()
以及AccurateSleep()
。这可能由OP使用的API决定
因此,我三思而后行,提出了以下类似于OPs的问题:
#include <iostream>
static int xMouse = 0, yMouse = 0, t = 0;
void mouse_event(int _1, int dx, int dy, int _4, int _5)
{
xMouse += dx; yMouse += dy;
std::cout << "mouse_event(" << _1 << ", " << dx << ", " << dy << ", " << _4 << ", " << _5 << "): "
<< xMouse << ", " << yMouse << '\n';
}
void AccurateSleep(int delay)
{
t += delay;
std::cout << "AccurateSleep(" << delay << "): " << t << '\n';
}
void Sleep(int delay)
{
t += delay;
std::cout << "Sleep(" << delay << "): " << t << '\n';
}
void Smoothing(int smoothing, int delay, int x, int y)
{
for (int i = 0; i < smoothing; i++) {
mouse_event(1, x / smoothing, y / smoothing, 0, 0);
AccurateSleep(delay / smoothing);
}
mouse_event(1, x % smoothing, y % smoothing, 0, 0);
Sleep(delay % smoothing);
}
#define PRINT_AND_DO(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__
int main()
{
PRINT_AND_DO(xMouse = 0; yMouse = 0; t = 0);
PRINT_AND_DO(Smoothing(10, 132, 14, 30));
PRINT_AND_DO(xMouse = 0; yMouse = 0; t = 0);
PRINT_AND_DO(Smoothing(20, 15, 10, 0));
}
然后我修改了平滑()
实现上述插值公式,并根据具体情况进行了一些调整:
对于t,使用i/平滑
(在[1,平滑]范围内使用i
)
当循环对每个i
进行插值时,保留上一次迭代的值,并用于计算mouse\u event()
和AccurateSleep()函数调用的增量值
当然,运算顺序很重要,因为这是整数运算。因此,xI=i*x/平滑
并不等同于xI=i/smoothing*x
(即,这些积分运算不提供交换性)
修改后的平滑()
void平滑(整数平滑、整数延迟、整数x、整数y)
{
int x=0,y=0,t=0;
for(inti=1;i是我阅读问题时的第一个想法(以及中提到的)
插值的一般公式为:
x=(1-t)·x0+t·x1
x…插值
x0…开始值
x1…目标值
t…插值参数在[0,1]范围内
当我意识到一些可能形成约束的事实时,我甚至打算写这篇文章作为答案(遗憾的是,OP没有明确提到)
所有的运算都是关于整数值的。所以,做整数运算可能是首选
使用增量值调用鼠标事件()
以及AccurateSleep()
。这可能由OP使用的API决定
因此,我再三考虑,并提出了以下类似于OPs的问题