整数除法缩放坐标时像素丢失,求鼠标移动灵敏度适配解决方案
解决方案
核心思路
采用误差累积补偿的逻辑(和计算机图形学中Bresenham直线绘制算法原理一致),缓存每次整数除法产生的余数,当累积余数的绝对值达到除数阈值(此处为4)时,主动对当前移动量补±1像素抵消误差,可保证全局总移动量和理论值完全匹配,单次最大误差不会超过3像素,不会出现误差随移动次数持续放大的问题。
你现有代码存在一处逻辑错误:计算余数时误用了已经除以4的dx/dy,拿到的余数和原坐标无关,完全无法用于误差补偿。
修改后的代码实现
private void _MoveMouse() { while (appRunning) { if (Utility.bGetAsyncKeyState(Keys.LButton)) { int[,] pattern = Current_Table().Item1; int sleep = Current_Table().Item2; if (_ENABLED == true) { // 每次启动新的移动序列时初始化余数累积变量 int xAccum = 0; int yAccum = 0; for (int i = 0; i < 30; i++) { int rawDx = pattern[i, 0]; int rawDy = pattern[i, 1]; // 计算原坐标除以4的商和余数 int dx = rawDx / 4; int dy = rawDy / 4; int dxRest = rawDx % 4; int dyRest = rawDy % 4; // 累积余数 xAccum += dxRest; yAccum += dyRest; // 累积余数达到阈值时补像素 if (Math.Abs(xAccum) >= 4) { int offset = xAccum / 4; dx += offset; xAccum -= offset * 4; } if (Math.Abs(yAccum) >= 4) { int offset = yAccum / 4; dy += offset; yAccum -= offset * 4; } Utility.Move(dx, dy); Thread.Sleep(sleep); if (Utility.bGetAsyncKeyState(Keys.LButton) == false) { break; } } } } } }
优化建议
- 如果你的移动序列数组是固定不变的,可以提前预处理所有坐标,直接生成适配灵敏度1的新数组,运行时无需实时计算余数,性能更高。
- 余数累积变量必须在每次启动新移动序列时重置为0,不要跨不同的移动操作累积,避免引入无关误差。
内容的提问来源于stack exchange,提问作者zjebinsky
相关产品推荐
相关产品推荐

