Flex动态绘制线段

最近公司一个项目中需要大量的动态绘制流程图,其中我做了绘制线段这一部分,用的是ActionScript语言,起初只是需要简单的将服务器端返回的线段坐标连接起来,但后来客户看了demo之后,感觉直角太不美观,无情的让我们要绘制带弧度的拐角,而且返回的数据还是原来那么多,这样就需要自己动态的去计算出绘制拐角所需要的点,这里说一下我的思路和方法,也希望小伙伴们提出更好的解决方案。

刚开始我的解决方案是根据给定的a,b,c点,计算得到绘制拐角弧度的圆心d,然后根据圆心,默认半径,并判断出弧的方向绘制弧,最后绘制出线段ap0,p2c,这样整个圆角线段就绘制出来了。如下图:

radian不过真正算起来的时候会非常麻烦,有时候,一个小问题往往会被想的复杂了,我突然想起来贝塞尔曲线的绘制。在wikipedia上down到一张图:

Bezier_2_big

根据贝塞尔二次曲线的公式,提供三个点(即图中的p0,b,p2)即可绘制出弧线,公式如下:

贝塞尔曲线

这样绘制弧度的问题解决了,但是计算p0和p2点的时候问题又来了,因为绘制流程图的时候,线段可能是水平向左/右,垂直向上/下四种情况。这样计算画弧度的点会非常麻烦,后来我在纸上笔画了半天,想到一个办法:

比如服务器端返回了4个点给我,那我就能知道,这条线画出来肯定有三个拐点(即n-1个拐点),然后通过遍历拐点,将每个拐点和其前一个点,以及后一个点进行比对(假设拐点为p1(即第一幅图中的b点),前一个点为a,后一个点为c,默认半径为30):

1.如果a.x=p1.x ,并且a.y<p1.y,那么p0点的坐标为(a.x ,p1.y-30); //垂直方向,向下

2.如果a.x=p1.x ,并且a.y>p1.y,那么p0点的坐标为(a.x,p1.y+30); //垂直方向,向上

3.如果a.y=p1.y,并且a.x<p1.x,那么po点的坐标为(p1.x-30,a.y); //水平方向,向右

4.如果a.y=p1.y,并且a.x>p1.x,那么po点的坐标为(p1.x+30,a.y); //水平方向,向左

这样思路就很清晰了。将拐点和后一个点c进行对比就可以算出p2。得到p0和p2后,用两个数组分别存放绘制线段所需要的点(如第一幅图中的线段ap0,p2c)和绘制弧度所需要的点(如第一幅图中的弧p0p2),这样就可以绘制出弧了。

箭头和动态绘制线段

同时,我还实现了绘制箭头和动态绘制线段这两个功能(可以点击顶部swf内部按钮查看效果),其中绘制箭头相对简单一点,在动态绘制线段的时候我采用如下步骤:

1.遍历上一步得到的存放绘制线段所需要点的数组,每次取两个点出来,根据这两个点判断绘制方向,每次绘制一个像素,每6毫秒绘制一次,便可达到动态的效果。

2.画完一个线后,到绘制弧度所需要点的数组中每次取三个点,根据贝塞尔二次曲线的公式,便可绘制出弧。

用文字描述想表达清楚太难了,代码放到GitHub上,总感觉我这样的做法不是最优的,希望大家提出改善意见。如果有别的更好的方法,欢迎留言,(*^__^*)。