Nao*_*omi 6 python smoothing easing
我一直在努力使用补间来使 Python 中的鼠标移动平滑,我目前正在尝试自动化一些重复性任务。
我尝试使用补间去除一些在没有应用平滑的情况下发生的粗糙度,但是这样做我失去了明显的准确性,因为我的dy和dx值被number我最终得到了余数。这可能会因获得可以解决greatest common factor在我的两个值(因为两者dx并dy需要由同一分number)不幸的是这导致了过小的GCD的。
由于鼠标无法移动屏幕上像素的其余部分,因此我最终会明显降低精度。
问题:如何对鼠标移动应用补间,而不会失去准确性?
import pytweening
import win32api
import win32con
from time import sleep
dy = [50, 46, 42, 38, 33, 29, 24, 20, 15, 10, 10]
dx = [-35, 6, -55, -43, 0, 17, 29, 38, 42, 42, 38]
while True:
count = 0
values = [(pytweening.getPointOnLine(0, 0, x, y, 0.20)) for x, y in zip(dx, dy)]
while win32api.GetAsyncKeyState(win32con.VK_RBUTTON) and win32api.GetAsyncKeyState(win32con.VK_LBUTTON):
if count < len(dx):
for _ in range(5):
win32api.mouse_event(1, int(values[count][0]), int(values[count][1]), 0, 0)
sleep(0.134 / 5)
count += 1
Run Code Online (Sandbox Code Playgroud)
这里的根本问题是您使用的是整数量的相对运动,这不会合计到您正在寻找的总运动量。如果你只想线性移动,你也根本不需要 PyTweening。这个解决方案怎么样?
import win32api
import win32con
from time import sleep
Npoints = 5
sleeptime = 0.134 / Npoints
dys = [50, 46, 42, 38, 33, 29, 24, 20, 15, 10, 10]
dxs = [-35, 6, -55, -43, 0, 17, 29, 38, 42, 42, 38]
x, y = win32api.GetCursorPos()
for dx, dy in zip(dxs, dys):
ddx = dx/Npoints
ddy = dy/Npoints
for _ in range(Npoints):
x += ddx
y += ddy
win32api.SetCursorPos(int(x), int(y))
sleep(sleeptime)
Run Code Online (Sandbox Code Playgroud)
请注意,仍然会有一些非常小的舍入误差,并且光标将在点之间沿直线移动。如果光标从 (0, 0) 开始,这就是它将形成的形状(红色十字是光标将设置到的点):
如果您想通过点以平滑曲线移动并且可以使用 numpy 和 scipy,那么这将处理该问题:
import numpy as np
import scipy.interpolate as sci
totalpoints = 50 # you can set this to a larger number to get closer spaced points
x, y = win32api.GetCursorPos()
# work out absolute coordinates of new points
xs = np.cumsum([x, *dxs])
ys = np.cumsum([y, *dys])
# fit spline between the points (s=0 makes the spline hit all the points)
tck, u = sci.splprep([xs, ys], s=0)
# Evaluate the spline and move to those points
for x, y in zip(*sci.splev(np.linspace(0, 1, totalpoints), tck)):
win32api.SetCursorPos(int(x), int(y))
sleep(sleeptime)
Run Code Online (Sandbox Code Playgroud)
结果如下所示:
问题:补间,而不损失准确性?
参考:
x, y = getLinePoint(startPoint x, startPoint y, endPoint x, endPoint y, intervall)该
getLinePoint()函数在所提供的线上找到一个点。
将您的列表dx和投射dy到以下列表中tuple(x, y)
dx = [-35, 6, -55, -43, 0, 17, 29, 38, 42, 42, 38]
dy = [50, 46, 42, 38, 33, 29, 24, 20, 15, 10, 10]
points = list(zip(dx, dy))
print(points)
Run Code Online (Sandbox Code Playgroud)
输出:
Run Code Online (Sandbox Code Playgroud)[(-35, 50), (6, 46), (-55, 42), (-43, 38), (0, 33), (17, 29), (29, 24), (38, 20), (42, 15), (42, 10), (38, 10)]
points在双循环中处理这个列表for。
import pytweening
for startPoint in points:
for endPoint in points:
x, y = pytweening.getPointOnLine(startPoint[0], startPoint[1],
endPoint[0], endPoint[1],
0.20)
x, y = int(x), int(y)
print('{}, '.format((x, y)), end='')
# win32api.mouse_event(1, x, y, 0, 0)
# sleep(0.134)
Run Code Online (Sandbox Code Playgroud)
输出:终点总是到达!
Run Code Online (Sandbox Code Playgroud)First move from (-35, 50) to (6, 46): (-35, 50), (-26, 49), (-39, 48), (-36, 47), (-28, 46), (-24, 45),(-22, 44), (-20, 44), (-19, 43), (-19, 42), (-20, 42), (-2, 46), (6, 46) ... (omitted for brevity) Last move from (42, 10) to (38, 10): (42, 10), (41, 10), (23, 18), (31, 17), (19, 16), (21, 15), (30, 14), (33, 13), (36, 12), (38, 12), (38, 11), (38, 10), (38, 10)
使用 Python 测试:3.6 - pytweening:1.0.3
| 归档时间: |
|
| 查看次数: |
687 次 |
| 最近记录: |