AS3.0画一段简单的贝塞尔曲线

一段曲线通常包含三个点:起点(x1,y1),控制点(x3,y3),终点(x2,y2),通过curveTo(controlX:Number, controlY:Number, anchorX:Number, anchorY:Number)即可画出曲线,curveTo参数中第一个参数是控制点的x坐标,第二个参数是控制点的y坐标,第三个参数是结束点的x坐标,第四个参数是结束点的y坐标。代码如下

package
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.TextField;
	
	/**
	 *@author hypo.chen
	 *@E-mail 645338868@qq.com
	 *@data 2015-9-11
	 */
	[SWF(width="1024",height="768",frameRate="60",backgroundColor="0x669966")]
	public class DrawBezierCurve extends Sprite
	{
		//已知三个顶点,即起点、终点和控制点
		private var _point1:Point;
		private var _point2:Point;
		private var _point3:Point;
		
		private var _text1:TextField;
		private var _text2:TextField;
		private var _text3:TextField;
		
		private var _lineShape:Shape;
		private var _cirCleShape:Shape;
		
		public function DrawBezierCurve()
		{
			init();
		}
		
		private function init():void
		{
			_point1 = new Point(200,500);
			_point2 = new Point(800,500);
			_point3 = new Point();
			//三个文本框标出三个点
			_text1 = new TextField();
			_text2 = new TextField();
			_text3 = new TextField();
			
			this.addChild(_text1);
			this.addChild(_text2);
			this.addChild(_text3);
			
			_text1.text = "(x1,y1)";
			_text2.text = "(x2,y2)";
			_text3.text = "(x3,y3)";
			
			_text1.x = _point1.x - 30;
			_text1.y = _point1.y + 10;
			_text2.x = _point2.x - 30;
			_text2.y = _point2.y + 10;
			
			_lineShape = new Shape();
			this.addChild(_lineShape);
			
			_cirCleShape = new Shape();
			this.addChild(_cirCleShape);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,onHandleMove);
			stage.addEventListener(MouseEvent.CLICK,onHandleClick);
			
			drawCurve(500,500,false);//鼠标进入舞台前初始化
			
		}
		private function onHandleClick(e:MouseEvent):void
		{
			drawCurve(mouseX,mouseY,true);
		}
		private function onHandleMove(e:MouseEvent):void
		{
			//鼠标移动来控制第三个点
			drawCurve(mouseX,mouseY,false);
		}
		private function drawCurve($x:Number,$y:Number,$isClick:Boolean):void
		{
			_lineShape.graphics.clear();
			_cirCleShape.graphics.clear();
			_lineShape.graphics.lineStyle(1,0x000000,0.5);//定义线的样式
			
			_point3.x = $x;
			_point3.y = $y;
			
			_text3.x = _point3.x - 30;
			_text3.y = _point3.y + 10;
			
			_cirCleShape.graphics.lineStyle(1,0xffffff,0.5);
			_cirCleShape.graphics.drawCircle(this._point1.x,this._point1.y,5);
			_cirCleShape.graphics.drawCircle(this._point2.x,this._point2.y,5);
			_cirCleShape.graphics.drawCircle(this._point3.x,this._point3.y,5);
			
			_lineShape.graphics.moveTo(this._point1.x,this._point1.y);
			_lineShape.graphics.lineTo($x,$y);
			_lineShape.graphics.moveTo(this._point2.x,this._point2.y);
			_lineShape.graphics.lineTo($x,$y);
			_lineShape.graphics.lineStyle(1,0xff0000,1);//定义线的样式
			_lineShape.graphics.moveTo(this._point1.x,this._point1.y);
			//curveTo(controlX:Number, controlY:Number, anchorX:Number, anchorY:Number)
			//curveTo参数中第一个点是控制点,也就是中间那个点,第二个点是结束点,也就是最后一个点
			//moveTo指的是起始点,也就是这里的第一个点,如果在调用 moveTo() 方法之前调用 curveTo() 方法,则当前绘画位置默认为 (0,0)。
			if(!$isClick)
			{
				_lineShape.graphics.curveTo($x,$y,this._point2.x,this._point2.y);
				return;
			}
			//如果想真正的经过鼠标点,还要做一下修正(即要把控制点人为抬高或降低一些):
			_lineShape.graphics.curveTo(($x*2 - (this._point1.x+this._point2.x)*0.5),($y*2 - (this._point1.y+this._point2.y)*0.5),this._point2.x,this._point2.y);
			
		}
		//一段曲线通常包含三个点:起点(x1,y1),控制点(x3,y3),终点(x2,y2);也许大家也看出来了:该曲线最终并不经过鼠标所在的点(x3,y3),在y轴方向上,曲线最大高度只有鼠标相对高度的一半,如果想真正的经过鼠标点,
		//还要做一下修正(即要把控制点人为抬高或降低一些):
		//修正公式为:新坐标 = 目标点坐标 * 2 - (起点坐标+终点坐标)/2
	}
}

程序中鼠标点击舞台,曲线就会通过控制点。效果图如下

 

 参考网址:http://www.cnblogs.com/yjmyzz/archive/2010/04/01/1702576.html

posted @ 2015-09-11 14:10  hypo.chen  阅读(1444)  评论(0编辑  收藏  举报