Actionscript:
-
// graphics, vector of xy coords, closed boolean
-
function bezierSkin(g:Graphics, bez:Vector.<Number>, closed:Boolean = true):void {
-
var avg:Vector.<Number> = calcAvgs(bez);
-
var i:int, n:int;
-
var leng:int = bez.length;
-
-
if (closed){
-
g.moveTo(avg[0], avg[1]);
-
for (i = 2; i <leng; i+=2) {
-
n=i+1;
-
g.curveTo(bez[i], bez[n], avg[i], avg[n]);
-
}
-
g.curveTo(bez[0], bez[1], avg[0], avg[1]);
-
}else{
-
g.moveTo(bez[0], bez[1]);
-
g.lineTo(avg[0], avg[1]);
-
for (i = 2; i <leng-2; i+=2) {
-
n=i+1;
-
g.curveTo(bez[i], bez[n], avg[i], avg[n]);
-
}
-
g.lineTo(bez[ leng - 2], bez[ leng - 1]);
-
}
-
}
-
-
// create anchor points by averaging the control points
-
function calcAvgs(v:Vector.<Number>):Vector.<Number> {
-
var avg:Vector.<Number> = new Vector.<Number>();
-
var leng:int=v.length;
-
for (var i:int = 2; i<leng; i+=1) {
-
var prev:Number=i-2;
-
avg.push( (v[prev] + v[i]) / 2 );
-
}
-
// close
-
avg.push( (v[0] + v[ leng - 2]) / 2 );
-
avg.push( (v[1] + v[ leng - 1]) / 2 );
-
return avg;
-
}
-
-
// test out the functions:
-
-
graphics.lineStyle(0,0x000000);
-
-
// draw a very rounded rect
-
bezierSkin(graphics, Vector.<Number>([100,100,200,100,200,200,100,200]) );
-
-
// draw a random curve with 10 xy coords
-
var rnd:Vector.<Number> = new Vector.<Number>();
-
for (var i:int = 0; i<20; i++) rnd.push(Math.random()*100);
-
bezierSkin(graphics, rnd);
-
-
// erase everything and allow the used to draw a smooth curve with the mouse
-
stage.addEventListener(MouseEvent.MOUSE_DOWN, onLoop);
-
var index:int = 0;
-
var pnts:Vector.<Number> = new Vector.<Number>();
-
-
function onLoop(evt:MouseEvent):void {
-
pnts.push(mouseX);
-
pnts.push(mouseY);
-
-
graphics.clear();
-
graphics.lineStyle(0,0x000000);
-
-
// draw a smooth curved line
-
bezierSkin(graphics,pnts,false);
-
}
The above code uses averaging to generate anchor points for curveTo() calls. This is an easy way to always draw smooth curves.
This is an old one that I've seen floating around since the drawing api first came out... but I it's an important snippet, so I figured I'd post it.