flash5连线教程之三---折线变曲线
前面我已经讲了怎样用flash5来连一根直线,接着又说了利用连直线程序来做折线图的例子,下面我讲一讲我是怎么把折线编程曲线的.在讲之前,请先看看下面两个效果的区别.
页面:
点这儿参观页面:
点这儿参观 看了效果之后,我先给大家说一说我的原理,我是以四个点(p1,p2,p3,p4),三条线(l1,l2,l3)为基本转化l2为曲线,将l2在x方向分为n份:第一,利用l1与l2的夹角的角平分线,向p3延时出一条直线(x方向是l2的x方向的1/n长),同理在l2与l3也向p2延时出一条直线;第二,连接两条新直线的新顶点为一条线,转化中间的四个点分别为原来的四点,继续进行判断延伸,直到两条直线的夹角小于某一值时停止.此时原来的折线已经是看上去很平滑的曲线了.
看了上面的原理不知道你懂了没有,没懂也没关系,下面看了程序也许你就懂了,不过这种算法也有一定的局限性,因为它只是根据四个点来判断曲线的走向,如果变化很剧烈的话,可能不够准确,我在这里希望能集思广益,希望大家都能把自己的想法来讲出来,我们共同研究,另外我在程序实现上也有一定的缺陷,希望大家能指正修改.
下面我给大家来讲解一下我的整个程序:
第一:就是我以前给大家讲的整个画直线的程序,在这里我就不再讲了,如果还有不懂的,请查找以前的帖子,我们把它放在主mc(quxian)的line层理的第一帧.
第二:我主要讲解一下下面的程序,就是怎样把已知的几个点用光滑的曲线连接起来.
1 建立Point 函数,注要是来存储坐标点,使程序更俱可读性,具体如下:
function Point(cx,cy)
{
this.x=cx;
this.y=cy;
}//功能就是把各个点的坐标存储在里面
2 建立主功能函数及其连接功能函数,主函数实现读取数据,连接函数实现连接曲线功能,具体程序如下:
function Smooth(cpoint0,cpoint1,cpoint2,cpoint3){
//将四个点存为内部变量:
this.point0 = cpoint0;
this.point1 = cpoint1;
this.point2 = cpoint2;
this.point3 = cpoint3;
}
Smooth.prototype.connect0 = function(cn)
{
//参数cn是将直线分为几部分,如果不是偶数,转化为偶数
this.n = cn;
if(this.n%2 == 0) this.n++;
//
this.dx = (this.point2.x - this.point1.x)/this.n;
// trace(this.dx);
//
//下面计算出三条直线之间的夹角,其中AttachAngle是自定义函数,计算两条线的夹角
this.angle1 = AttachAngle(this.point0, this.point1);
this.angle2 = AttachAngle(this.point1, this.point2);
this.angle3 = AttachAngle(this.point2, this.point3);
trace("angle1 = " + this.angle1);
trace("angle2 = " + this.angle2);
trace("angle3 = " + this.angle3);
trace("");
//
//计算出要画直线的斜率:
this.kk0=Math.tan((this.angle1+this.angle2)/2);
this.kk1=Math.tan((this.angle2+this.angle3)/2);
if(this.dx < 0) this.kk1 = -this.kk1;
trace("kk0 = " + this.kk0);
trace("kk1 = " + this.kk1);
//
//得到新画线的顶点,并存储在两个点对象里面
this.point11 = new Point(this.point1.x+this.dx,this.point1.y+this.dx*this.kk0);
this.point22 = new Point(this.point2.x-this.dx,this.point2.y-this.dx*this.kk1);
//
trace(Math.abs(this.kk0-this.kk1));
//
//将这两点连接起来,如果两个斜率只差小于0.01,怎程序退出
this.myline=new line(this.point1.x,this.point1.y,this.point2.x,this.point2.y);
if(Math.abs(this.kk0-this.kk1) <= 0.01) return 0;
//
//下面是连接起来两条要画的线
this.mylinen=new line(this.point1.x,this.point1.y,this.point11.x,this.point11.y);
this.mylinen=new line(this.point2.x,this.point2.y,this.point22.x,this.point22.y);
// trace(this.dl);
this.myline.delete_line(myline);
//
//转化顶点,p1->p0,p11->p1,p22->p2,p2->p3;
this.point0 = this.point1;
this.point1 = this.point11;
this.point3 = this.point2;
this.point2 = this.point22;
delete this.point11;
delete this.point22;
// this.n-=2;
//
this.connect0(this.n);//递归调用
};
3 是计算夹角的函数,上面已经用到:
function AttachAngle (cpoint1, cpoint2) {
this.dx = cpoint2.x - cpoint1.x;
this.dy = cpoint2.y - cpoint1.y;
this.angle = Math.atan2(this.dy,this.dx);
return this.angle;
}//程序很简单,就不用我解释了把
4 实现连线功能函数,为了使用简单,我们采用数组式输入,只需输入两个坐标轴的值就能把曲线连好,如果已经看懂上面的程序,那下面的程序也就不难了,我仅给出注释:
function Smooth_line(carray_x,carray_y)
{
this.dn=10;//设置要用的参数
this.n=carray_x.length;//设置循环次数
//
//for循环将两个数组分别存储为所包含的n个点
for(i=0;i
this["point"+i]=new Point(carray_x[i],carray_y[i]);
}
//
//下面两句是假定两个不存在的点,为了画第一条和最后一条曲线用
this.point00=new Point(2*this.point0.x-this.point1.x,2*this.point0.y-this.point1.y);
this.pointnn=new Point(2*this["point"+(this.n-1)].x-this["point"+(this.n-2)].x,2*this["point"+(this.n-1)].y-this["point"+(this.n-2)].y);
// trace(this.pointnn.x+"\t"+this.pointnn.y);
//
//连接第一条曲线
this.mysmooth=new Smooth(this.point00,this.point0,this.point1,this.point2);
this.mysmooth.connect0(this.dn);
//下面连接中间的所有曲线
for(i=0;i this.mysmooth=new Smooth(this["point"+i],this["point"+(i+1)],this["point"+(i+2)],this["point"+(i+3)]);
this.mysmooth.connect0(this.dn);
}
//最后连接最后一条曲线
this.mysmooth=new Smooth(this["point"+(this.n-3)],this["point"+(this.n-2)],this["point"+(this.n-1)],this.pointnn);
this.mysmooth.connect0(this.dn);
}
5 最后我们来实现函数的功能,给出几个坐标点,来画一条曲线:
myarray_x=[0,50,100,150,200,250,300,350];
myarray_y=[0,-50,-75,-25,-100,-20,0,80];
myline=new Smooth_line(myarray_x,myarray_y)
delete myline;//如果你要删除曲线,请自己添加函数删除
第三,我们来看一下效果:
页面:点这儿参观
源文件
到这里我就讲完了怎样讲一条折线来转化为一条曲线了,我的程序还有很大的缺陷,比如x轴必须是一直增加的,不能减小,要不然就不能画出理想的曲线来,我自己也有了解决的办法,但一直都没有来得及来修改,不知道大家还有没有好的方法,在这里希望多多讨论,我也希望能从大家身上多学到一些知识.