简介
本文是对ImagePy的矢量图形绘制工具进行深度解析。
矢量图形相对于位图来说,有其特有的操作,比如两个矢量进行求交集、求并集、求差等。
阅读本文之前,可以先参考之前的这篇文章,以对ImagePy的矢量图形有初步了解。
功能函数
将矢量图形转化为点集
该函数的作用是将矢量图形转换为点集,这里的点作为锚点,可以供后续编辑。
比如对于矩形这一矢量,在shp中定义了它的起始点和长宽,通过该函数,可以将该矩形转为9个点的点集,即将该矩形分成田字格。
(具体到语法上,使用了numpy的mgrid函数,其中的步长设为了复数的形式,具体可以参考这里)
1 | def mark(shp, types = 'all'): |
选择对象
该函数的功能是选择与鼠标点击位置距离在一定范围内且距离最近的那个矢量对象。
1 | def pick_obj(shp, x, y, lim, types='all'): |
选择锚点
该函数的功能是选择与鼠标所在位置小于某个距离的那个锚点。
如果锚点被选中,就会返回该锚点所在的矢量对象,同时表示该锚点的一个标识。比如对于椭圆上一个锚点,有“lt”左上、“rt”右上、“o”中心点等多种锚点。
1 | def pick_point(shp, x, y, lim, types='all'): |
拖动锚点
这个函数接收当前的矢量对象、它的某个锚点以及当前鼠标位置,然后通过该锚点的类型,来对该矢量对象的范围进行调整。
1 | def drag(shp, pt, x, y, types='all'): |
移动对象
该函数目的是对矢量对象进行移动。
1 | def offset(shp, dx, dy): |
BaseEditor鼠标动作
鼠标中键拖动
1 | def mouse_down(self, shp, x, y, btn, **key): |
alt+右键以删除一个shape
1 | def mouse_down(self, shp, x, y, btn, **key): |
shift+右键以合并shape
1 | def mouse_down(self, shp, x, y, btn, **key): |
右键根据当前区域大小缩放
1 | def mouse_down(self, shp, x, y, btn, **key): |
alt+ctrl以显示锚点
(注意该组合键是放在鼠标移动这个事件中,所以此时要鼠标移动一下,才会看到锚点)
1 | def mouse_move(self, shp, x, y, btn, **key): |
最开始时,画布中是没有锚点的,此时就会将矢量对象通过mark函数转为锚点的点集,然后在画布上显示出来(具体原理可以见上面的mark函数解析)。
当画布中有了锚点后,如果鼠标靠近了某个锚点,通过pick_point这个函数捕捉到该锚点,就会将鼠标的样式设置为“手形”。
alt+ctrl+鼠标左键拖动锚点
需要提前非常注意的一点是,当同时按住alt和ctrl后,就会在鼠标移动事件中将此时的status设为pick模式:
1 | self.status = 'pick' |
此时在鼠标按下事件中:
1 | def mouse_down(self, shp, x, y, btn, **key): |
如果是捕捉到了某锚点,那么self.pick_m和self.pick_obj都会有值。
此时如果移动鼠标,那么:
1 | def mouse_move(self, shp, x, y, btn, **key): |
就会触发drag这个函数来对锚点进行拖动。
alt+ctrl+鼠标左键拖动整个矢量对象
上面拖动锚点,是因为在鼠标按下时能够捕捉到锚点,而如果捕捉不到锚点(即与锚点离得较远),此时就会尝试选择整个对象,即:
1 | def mouse_down(self, shp, x, y, btn, **key): |
(注意到此时self.pick_m是None,即没有捕捉到锚点的前提下)
此时如果探测到了矢量对象,那么self.pick_m就会有值,但self.pick_obj没有值。
此时如果移动鼠标,那么:
1 | def mouse_move(self, shp, x, y, btn, **key): |
特定形状Editor的鼠标动作
调用BaseEditor
BaseEditor中有预置的鼠标动作,何时调用它。
1 | def inbase(key, btn): |
即同时按住Ctrl和alt,或点击了鼠标中键或右键,就先响应BaseEditor中的行为。
自定义动作
有几个特定的矢量图形绘制时都有如下动作,即:
(1)按住alt,求差集;
(2)按住shift,求并集;
(3)同时按住shift和alt,求交集。
1 | if key['alt'] or key['shift']: |