[原创]《C#高级GDI+实战:从零开发一个流程图》第09章:增长贝塞尔曲线,上、下、左、右毗连点

[复制链接]
发表于 2025-9-19 10:03:40 | 显示全部楼层 |阅读模式
一、前言

前面的课程我们添加了诸多形状,但连线还只有直线这一种样式,而且也只能毗连形状的中心点。我们本节课就来增长一种很常见的连线样式:贝塞尔曲线。同时也对形状增长多个差别的毗连点,不再只连中心了。
信赖看完的你,肯定会有所劳绩!
本文所在:https://www.cnblogs.com/lesliexin/p/19033113
二、先看效果

通过视频我们可以看到,我们本节课紧张实现3个效果:
1,支持添加贝塞尔曲线
2,全部形状都支持上、下、左、右四个毗连点
3,对贝塞尔曲线的控制点举行了优化,效果更好
下面我们就分别来讲授一下。
任意说一下,从本节开始我们的代码就和Gitee上同步了,读者可自行拉取编译。
Gitee所在:https://gitee.com/lesliexin/flowchartdemo
三、效果1:添加贝塞尔曲线

(一)贝塞尔曲线类

起首我们来看一下MSDN上对于贝塞尔曲线的分析:

可以看到共必要4个点:出发点、控制点1、控制点2、尽头。
我们的连线界说里有开始形状和竣事形状,可获取到出发点和尽头,那么还必要额外界说两个属性——控制点1和控制点2——吗?
答案是:不必要。我们的目的不是做成是PS中的钢笔那样可以可以自由调解控制点来改变连线的样式,我们的目的是提供一个同一规则样式的连线,以是我们只必要按照肯定的规则根据出发点和尽头盘算出这两个控制点即可。
我们先界说一个简朴的规则:控制点1:出发点右侧50像素;控制点2:尽头左侧50像素。
规则很简朴,也不太美满,我们先照此实现,下文会举行优化。
下面我们就基于连线基类派生出一个贝塞尔曲线类:

可以看到,实现起来还是很简朴的。
(二)画布增长对贝塞尔曲线的支持

我们现在的齐备都是在画布(FCCanvas)中实现,以是我们来看一下如安在画布中添加对贝塞尔曲线的支持。
我们先来看一下“直线连线”是在画布的那里利用的:

可以看到是在OnMouseDown变乱中判断选择了两个形状后便添加了一条新的直线连线,那么我们就要控制一下,可以根据必要添加直线还是贝塞尔曲线。
我们界说一个属性,来控制添加连线时添加的是什么范例连线:

这里我们界说为string范例,一是方便后续扩展,如果界说为bool、int、乃至是enum,扩展性都不太好,由于后续的连线大概是第三方自界说的,非string范例要么阅读性不好要么扩展性不好;二是方便后续动态反射,这个对于后续开放用户自界说形状是须要的。
然后,我们在OnMouseDown变乱中,根据此属性来判断添加哪种范例:

(三),应用画布

起首,我们添加一个下拉框控件,内容为直线和贝塞尔曲线:

在下拉框的改变选中项变乱中,我们根据选择的项差别,设置画布的连线范例:

到此,我们就实现了贝塞尔曲线的支持,是不是感觉不测的简朴?这就是抽象的利益。
注:从本节开始,课程代码就提交到了GITEE上了,各人可自行拉取编译。
四、效果2:上、下、左、右毗连点

我们之前的课程都是直接毗连的形状的中心点,效果是一言难尽,紧张是方便讲授用。随着我们的课程步入正轨,这点也必要同步办理,我们本节就来扩展一下,支持上、下、左、右四个毗连点。
注:近期阶段支持上、下、左、右四个毗连点已经充足用了,固然后期我们会开放此限定,完全的由派生类自行界说有多少个毗连点、各毗连点的坐标又是那里。
(一)形状基类扩展

由于这是全部形状的改动,以是我们要对形状基类举行扩展。
注:为了讲授课程必要,是重新下界说了个基类: ShapeBaseV2,各人自行实现时直接修改原类即可。下同,不再赘述。
1,毗连点罗列


我们界说了四个毗连点,从左开始顺时针依次是:左->上->右->下。
2,获取毗连点方法

我们同样界说一个带默认实现的虚方法。由于我们现在的形状都是基于一个“矩形”来绘制的,以是默认实现就是矩形的四个边的中点坐标:

我们界说为虚方法,是方便派生形状自行决定毗连点的坐标是那里,像平行四边形,左、右两个毗连点就是举行偏移才气在斜边上。
3,移除获取中心点方法

由于现在已经有连线点了,以是不再必要获取中心点的方法,我们直接移除即可。

(二)形状派生类修改

形状基类已经修改,以是我们的派生类也必要同步修改。
1,平行四边形

由于别的形状的四个边都是与矩形地区重合的,以是不必要修改。



哪怕是菱形,其四个顶点恰好是矩形地区的四个边的中心点,以是也不必要修改。

只有平行四边形必要重写获取毗连点坐标方法,由于左、右两个毗连点要举行偏移才气在斜边上:


(三)连线基类修改

上面的形状已经支持了差别的毗连点,那么连线也要做同步的修改,紧张是要记录开始形状的毗连点、和竣事形状的毗连点。

(四)连线派生修改

我们对连线的修改是获取开始点和竣事点坐标的地方,我们之前是调用形状的获取中心点方法,而现在要改成根据毗连点获取对应毗连点坐标。
1,直线


2,贝塞尔曲线


(五)画布增长毗连点支持

当形状和连线都修改好后,我们的画布也要同步添加对毗连点的支持。
由于这次是让连线支持毗连上、下、左、右差别的毗连点,以是我们的焦点便是记录下连线开始和竣事形状的毗连点信息然后在天生毗连时将毗连点信息赋于连线。
以是我们先界说两个属性:

然后在OnMouseDown中,添加连线时将这两个属性的值赋给连线:

(六)应用

我们下面就来编写步伐来看下差别毗连点的效果:
1,筹划器界面

我们增长两个下拉框,来分别设置开始和竣事的毗连点是上、下、左、右中的哪个:

注:这种方式看文首的演示视频就会发现用起来很繁琐,不直观。我们要一点点深入,在反面我们就会对其改造成鼠标点击开始形状的某连续接点,然后拖动着去竣事形状的某连续接点,松开鼠标完成连线利用,而且在拖动时会及时表现毗连的半透明虚线效果。
2,切换毗连点

我们在下拉框的选择改变变乱中,对画布的毗连点属性举行修改:
开始形状的毗连点:

竣事形状的毗连点:

就像上一末节一样,很简朴的改动,就支持了差别的毗连线,各人可主动拉取代码编译实验。
五、实现效果3:贝塞尔曲线控制点优化

我们实现了上下左右毗连点后会发现(看文首的演示视频可以明确):贝塞尔曲线效果只有在某些环境下效果很好,别的时间曲线的效果都很别扭。这是由于我们在第1末节界说贝塞尔曲线时,两个控制点是写死的,而现在我们支持了上下左右差别的毗连点,以是我们的贝塞尔曲线也得根据毗连点的差别而同步调解控制点的位置。
我们先看下原来控制点的盘算方式:

这种环境只得当:开始形状在竣事形状的左侧、开始形状的毗连点是‘右’、竣事形状的毗连点是‘左’。以是我们依此规律,根据毗连点的差别而盘算差别的坐标:

固然,盘算控制点的方法有很多,差别的控制点曲线的效果也不雷同,我们这里采取的是比力简朴的方式,效果不错。
我们只必要修改贝塞尔曲线的界说即可,别的的画布、步伐都不必要改动,就可以看到效果了。
随课代码为了每节课不干扰,以是必要重新修改画布、步伐等等。
六、结语

我们本节课实现了一个新的连线样式:贝塞尔曲线,同时还支持了上、下、左、右四个毗连点,到此终于有点正式流程图的样子了。
我们看本节的代码就会感受到,添加新功能不测的改动很少,这就是抽象的魅力。
着实到本节课为止,底子的东西就讲完了,我们反面的课程就是要在各个细节处下功夫了,向着正规的流程图去进步。反面的课程,实现思绪和逻辑大于技能代码,更多的是怎样去实现、去更好的实现想要的效果,而这些,对于任何框架和语言都有用。
下节课,我们就来办理本节课选择毗连点繁琐的题目,我们来实现鼠标拖动到毗连点来添加毗连。敬请等待。
感谢各人的观看,本人水平有限,文章不敷之处欢迎各人批评指正。
-[END]-

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表