模拟贝塞尔曲线过鼠标的效果

      Flash学习笔记 2008-11-8 23:40

  以鼠标为控制点,在两点间画一个曲线,相对来说比较容易,只要curveTo 就可以了,那么如果要让这个曲线过鼠标该怎么办呢?

  我想了一个办法,就是将曲线的起止点之间的距离缩小(比如缩小两倍),并“移动”到鼠标的两侧,让鼠标和这两个新位置点位于同一条直线上,然后以鼠标两侧的点为控制点,以曲线的起止点和鼠标位置为新的曲线起止点,依次连接起来,就可以得到过鼠标的贝塞尔曲线了。代码如下:

stage.frameRate = 30;
var line:Sprite = new Sprite();
addChild(line);

var startDot:Point = new Point(450,100);
var endDot:Point = new Point(150,300);

var curveRate = 2;  // 这个值越大,曲线在鼠标附近的弯曲度就越大,感觉上取2或3比较的合适。

var distPt:Point = new Point( (startDot.x  - endDot.x)/curveRate,(startDot.y  - endDot.y)/curveRate);

this.addEventListener(Event.ENTER_FRAME, drawLine);
function drawLine(e:Event):void {
 var pen:Graphics = line.graphics;
 //曲线
 pen.clear(); 
 pen.lineStyle(1); 
 var controlDot1:Point  = new Point(mouseX + distPt.x/2,mouseY + distPt.y/2); 
 pen.moveTo(startDot.x,startDot.y);
 pen.curveTo(controlDot1.x,controlDot1.y,mouseX,mouseY);
 var controlDot2:Point  = new Point(mouseX - distPt.x/2,mouseY - distPt.y/2);
 pen.curveTo(controlDot2.x,controlDot2.y,endDot.x,endDot.y);
 //控制线
 pen.lineStyle(1,0xff0000,0.3);
 pen.moveTo(startDot.x,startDot.y);
 pen.lineTo(controlDot1.x,controlDot1.y);
 pen.lineTo(controlDot2.x,controlDot2.y);
 pen.lineTo(endDot.x,endDot.y); 
}

//2008-11-15 补充下段文字:

古人说的好“吾尝终日而思,不如须臾之所学”,翻了一下 fl 基理大师译的 foundation ,里面提供了一个简单的算法,直接用一个控制点来实现曲线的绘制。

公式如下:

var ctlPtX = mouseX * 2 - (startDot.x + endDot.x) / 2;
var ctlPtY = mouseY * 2 - (startDot.y + endDot.y) / 2;

想了一下,相当于将我的两个控制点的做法,与曲线的起止点连起来延长得到交点,就是唯一的控制点,参数取2。

代码修改一下,复制放到场景中可以看到最终效果。

stage.frameRate = 30;
var line:Sprite = new Sprite();
addChild(line);

var startDot:Point = new Point(450,100);
var endDot:Point = new Point(150,300);

this.addEventListener(Event.ENTER_FRAME, drawLine);
function drawLine(e:Event):void {
 var pen:Graphics = line.graphics;
 pen.clear();
 pen.lineStyle(1);
 //曲线 
 var ctlPtX = mouseX * 2 - (startDot.x + endDot.x) / 2;
 var ctlPtY = mouseY * 2 - (startDot.y + endDot.y) / 2;

 pen.moveTo( startDot.x,startDot.y );
 pen.curveTo( ctlPtX,ctlPtY,endDot.x,endDot.y);

 //控制线
 pen.lineStyle(1,0xff0000,0.3);
 pen.lineTo(ctlPtX,ctlPtY);
 pen.lineTo( startDot.x,startDot.y );
}

标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}