2009/03/10 | 曲线的画法
类别(Flash与飞行程序设计) | 评论(1) | 阅读(1039) | 发表于 11:34

  飞行路径的设定,需要基本的画线功能,网上已经有一个Path类,够将画出的线条自动分段保存成数据,这样逐段的移动,就可以实现飞机沿“画定”的路线前进的功能。

  Path类中提供了直线(lineTo)和二次曲线(curveTo)以及画圆(circleTo)函数,现在的问题就是怎样提供一个画曲线的工具,让用户来创建曲线路径。

  之前我考虑的是自动计算,比如给出两个直线段,自动计算出能够连接两条线段的切线弧,但是用户的操作可以千差万别,给出的线段不一定符合需要,代码编写上难度也较高,因此这个想法就放弃了。

  画曲线的一种方式是三点确定一条曲线,这样的画法相对简单,但如要提高路径的模拟程度,就必然使用多段曲线,造成曲线摆放、调整时的困难。

  偶然间翻到02年的一本旧书《Flash编程创意与实现》,里面提到了二次曲线与三次曲线的问题,为曲线添加两个控制点看来是个不错的主意,至少画一次曲线,就可以得到“两段”相连的曲线。于是先简单模拟了一下,以两个控制点的中点为曲线的中继点,先画曲线到中继点,再从中继点画向终点,实现的效果如下:

var pen:Graphics = this.graphics;

addEventListener(Event.ENTER_FRAME,onDraw);
function onDraw(evt:Event)
{
 pen.clear();
 pen.lineStyle(1,0x000099,0.5);
 pen.moveTo(b.x,b.y);
 pen.lineTo(a.x,a.y);

 pen.lineStyle(3,0xff0099,0.5);
 pen.curveTo(b.x,b.y,(b.x + c.x)/2,(b.y+c.y)/2);
 pen.curveTo(c.x,c.y,d.x,d.y);

 pen.lineStyle(1,0x000099,0.5);
 pen.lineTo(c.x,c.y);
}

  上面的曲线实际上只是两段二次曲线的相连,与原作者的三次曲线有很大的差距,既然见到了更好的东西,就不想就此放弃,与是花了几个小时去理解并改写原代码,完成之后,得到下面的效果(添加了辅助中继点的显示),三次曲线实现的原理是利用递归运算,将已有的画线点进行拆分,直到误差符合要求为止,然后将所有点以曲线相连起来。

  与前面简单模拟的曲线相比,后面的三次曲线更加的平滑,当曲线仅向一个方向弯曲时,中继点会迅速的减少,而当出现S形时,在中部的拐弯处会集中大量的中继点。有了这样的曲线函数,我们就可以进入下一步的操作框架分析的阶段了。

0

评论Comments