import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline
import random
import time
import platform
''' 设置字体 可视化画出轨迹'''
def set_chinese_font():
"""自动检测系统并设置中文字体"""
system = platform.system()
# # 设置中文字体 (根据系统选择)
if system == 'Windows':
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei']
elif system == 'Darwin': # macOS
plt.rcParams['font.sans-serif'] = ['PingFang SC', 'STHeiti']
else: # Linux
plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei', 'Noto Sans CJK SC']
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# D:\python310\lib\tkinter\__init__.py:839: UserWarning: Glyph 20687 (\N{CJK UNIFIED IDEOGRAPH-50CF}) missing from font(s) DejaVu Sans.
# func(*args)
# # 设置中文字体 (根据系统选择)
# plt.rcParams['font.sans-serif'] = [
# 'Microsoft YaHei', # Windows
# 'PingFang SC', # macOS
# 'WenQuanYi Micro Hei' # Linux
# ]
# plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 使用示例
set_chinese_font()
def generate_human_like_trajectory(start_point, end_point, num_points=100, jitter_factor=0.3, speed_variation=0.5):
"""
生成类似人类点击的平滑轨迹
:param start_point: 起始坐标 (x, y)
:param end_point: 目标坐标 (x, y)
:param num_points: 轨迹点数
:param jitter_factor: 轨迹抖动程度 (0-1)
:param speed_variation: 速度变化程度 (0-1)
:return: 轨迹点列表 [(x, y)]
"""
# 生成控制点(贝塞尔曲线控制点)
control_points = [np.array(start_point)]
# 在起点和终点之间添加2个随机控制点
for i in range(1, 3):
t = i / 3
# 线性插值基础点
base_point = (1 - t) * np.array(start_point) + t * np.array(end_point)
# 添加随机偏移
offset = np.random.normal(0, jitter_factor * np.linalg.norm(np.array(end_point) - np.array(start_point)) / 4, 2)
control_points.append(base_point + offset)
control_points.append(np.array(end_point))
# 生成三次样条曲线
t_vals = np.linspace(0, 1, len(control_points))
x_vals = [p[0] for p in control_points]
y_vals = [p[1] for p in control_points]
cs_x = CubicSpline(t_vals, x_vals, bc_type='natural')
cs_y = CubicSpline(t_vals, y_vals, bc_type='natural')
# 生成非均匀时间点(模拟人类速度变化)
t_smooth = np.linspace(0, 1, num_points)
speed_factors = np.cumsum(np.random.uniform(1 - speed_variation, 1 + speed_variation, num_points))
t_smooth = t_smooth * (speed_factors / np.max(speed_factors))
# 生成轨迹点
trajectory = []
for t in t_smooth:
x = cs_x(t)
y = cs_y(t)
# 添加微小抖动(模拟人类手部颤动)
x += random.gauss(0, 0.3)
y += random.gauss(0, 0.3)
trajectory.append((x, y))
return trajectory
def plot_trajectory(trajectory, start_point, end_point):
"""
绘制轨迹并验证平滑度
:param trajectory: 轨迹点列表
:param start_point: 起始点
:param end_point: 目标点
"""
x_vals = [p[0] for p in trajectory]
y_vals = [p[1] for p in trajectory]
# 计算速度(变化率)
dx = np.diff(x_vals)
dy = np.diff(y_vals)
speed = np.sqrt(dx**2 + dy**2)
# 计算加速度
acceleration = np.diff(speed)
# 15英寸宽,10英寸高
# plt.figure(figsize=(15, 10))
# plt.figure(figsize=(10, 8))
# 设置图形尺寸和DPI
# plt.figure(figsize=(10, 6), dpi=120) # 总像素尺寸 = (10*120) x (6*120) = 1200x720
# 创建宽屏图表 (16:9比例)
plt.figure(figsize=(16, 9), dpi=80) # 1280x720像素
# 轨迹图
plt.subplot(2, 2, 1)
plt.plot(x_vals, y_vals, 'b-', label='轨迹', linewidth=9 )
plt.plot(start_point[0], start_point[1], 'go', markersize=10, label='起点')
plt.plot(end_point[0], end_point[1], 'ro', markersize=10, label='终点')
plt.title('鼠标移动轨迹', fontsize=19)
plt.xlabel('X 坐标')
plt.ylabel('Y 坐标')
plt.legend()
plt.grid(True)
plt.axis('equal')
# 速度变化图
plt.subplot(2, 2, 2)
plt.plot(speed, 'g-')
plt.title('轨迹速度变化')
plt.xlabel('时间步长')
plt.ylabel('速度 (像素/步)')
plt.grid(True)
# 加速度变化图
plt.subplot(2, 2, 3)
plt.plot(acceleration, 'r-')
plt.title('轨迹加速度变化')
plt.xlabel('时间步长')
plt.ylabel('加速度')
plt.grid(True)
# 曲率图
curvature = np.abs(np.diff(np.arctan2(dy, dx)))
plt.subplot(2, 2, 4)
plt.plot(curvature, 'm-')
plt.title('轨迹曲率变化')
plt.xlabel('时间步长')
plt.ylabel('曲率 (弧度)')
plt.grid(True)
plt.tight_layout()
plt.show()
# 导出控制:保存图片时使用savefig的dpi参数独立控制输出分辨率
plt.savefig('plt-output.png', dpi=300) # 高分辨率输出
# 多子图协调:大尺寸图形可容纳更多子图,但需调整子图间距
# plt.subplots_adjust(wspace=0.3, hspace=0.4) # 调整子图间距
def find_font():
import tkinter as tk
from tkinter import font
root = tk.Tk()
# 获取所有字体
all_fonts = sorted(font.families())
# 筛选中文支持字体 (根据系统不同)
chinese_fonts = [f for f in all_fonts
if "宋体" in f or "黑体" in f or
"YaHei" in f or "PingFang" in f or
"WenQuan" in f]
print("支持中文的字体:", chinese_fonts)
root.destroy() # 关闭临时窗口
# 示例使用
if __name__ == "__main__":
# 设置起点和终点
start = (100, 100)
target = (500, 400)
# 生成轨迹
trajectory = generate_human_like_trajectory(start, target, num_points=150)
# 绘制轨迹和分析图
plot_trajectory(trajectory, start, target)
# 模拟实际移动(可选)
print("模拟移动中...")
for x, y in trajectory:
# 在实际应用中,这里会调用鼠标移动函数
# 例如:pyautogui.moveTo(x, y)
time.sleep(0.01) # 模拟移动间隔
print("到达目标位置")
# find_font()
为什么使用 plt.savefig('plt-output.png', dpi=300) # 高分辨率输出 导出的图片是一片空白
最新发布