【绘制】HTML5 Canvas绘画画板小项目:可编辑控制的贝塞尔曲线(可控制锚点和控制点的位置)

介绍

之前,我们说了贝塞尔曲线的绘制,但那个演示效果只是演示贝塞尔曲线但死页面,这节来实现一个可以编辑和控制的贝塞尔曲线。

在线演示  详细代码

代码解读

在详细代码中,综合了直线圆弧阴影背景网格线辅助线等之前的Demo,也利用了拖拽绘图表面的保存恢复等之前的原理,这里不再过多介绍。

现在阐述如何实现的可编辑贝塞尔曲线

和之前实现拖拽效果的原理类似,通过不断地重绘下一时刻的图像。

不过这里要判断两个状态,当是绘制曲线状态时,鼠标移动事件处理器就会重绘曲线本身、控制端点和锚点,其中控制端点和锚点会随着曲线拉伸移动。当用户正在拖动端点和控制点时,应用程序会更新该点的位置,然后再重绘曲线本身和端点与控制点,(这里另一个端点和两个控制点不随着移动)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现通过鼠标左键按住不放来移动贝塞尔曲线控制点,你可以使用matplotlib的事件处理机制。下面是修改后的代码: ```python import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Rectangle from scipy.special import comb def bezier_curve(points, t): n = len(points) - 1 curve = np.zeros(2) for i in range(n+1): curve += comb(n, i) * (1-t)**(n-i) * t**i * points[i] return curve def bezier_tangent(points, t): n = len(points) - 1 tangent = np.zeros(2) for i in range(n): tangent += n * (points[i+1] - points[i]) * comb(n-1, i) * (1-t)**(n-i-1) * t**i return tangent / np.linalg.norm(tangent) def on_mouse_move(event): if event.button == 1 and event.inaxes == ax: control_points[control_point_index] = [event.xdata, event.ydata] fig.canvas.draw_idle() # 控制点坐标,可以根据需要进行修改 control_points = np.array([[0, 0], [2, 4], [6, 5], [8, 2]]) # 小车初始位置和朝向 car_pos = control_points[0] car_dir = bezier_tangent(control_points, 0) # 小车形状 car_width = 0.5 car_length = 1.0 # 模拟时间和步长 t = 0 dt = 0.01 total_time = 5 # 总运行时间 fig, ax = plt.subplots() # 绑定鼠标移动事件 fig.canvas.mpl_connect('motion_notify_event', on_mouse_move) while t <= total_time: # 计算贝塞尔曲线上的点和切线方向 curve_pos = bezier_curve(control_points, t) curve_dir = bezier_tangent(control_points, t) # 更新小车位置和朝向 car_pos = curve_pos car_dir = curve_dir # 绘制贝塞尔曲线和小车 t_values = np.linspace(0, 1, 100) curve_points = np.array([bezier_curve(control_points, tv) for tv in t_values]) ax.plot(curve_points[:, 0], curve_points[:, 1], 'r-') ax.plot(control_points[:, 0], control_points[:, 1], 'bo-') # 绘制小车 car = Rectangle((car_pos[0] - car_width/2, car_pos[1] - car_length/2), car_width, car_length, angle=np.degrees(np.arctan2(car_dir[1], car_dir[0]))) ax.add_patch(car) ax.axis('equal') plt.show(block=False) plt.pause(0.01) ax.cla() t += dt ``` 在修改后的代码中,我添加了一个`on_mouse_move`函数来处理鼠标移动事件。当鼠标左键按住不放并且在图形区域内移动时,会更新被选中的控制点的坐标,然后重新绘制图形。 希望这次的回答能够满足你的需求。如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值