In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Drawing Quadratic Bezier curve using Bitmap

Instructions:
-play around with the control points to change the curve
-tap or hold "UP " arrow key to increase the number of steps along the curve
-tap or hold "DOWN" arrow key to decrease the number of steps along the curve

This didn't take too long (thus it's really not the best way to go about doing it), but this code does show how to not only find the pts along the path of a quadratic Bezier curve, but how to draw along the path of a curve at a given point using a Vector based object as a brush, that has been converted to a Bitmap.

I am taking a digital media class right now at OCAD University, and we're using nothing but Adobe Illustrator at the moment, so I figured, although it uses cubic Bezier curves (which is just as easy to do as this), that I would write some sketch code to show how to draw along a path, and, in theory, how to make a vector manipulable bitmap brush.

You can contact me on FB if you have ny questions: https://www.facebook.com/arpace
Get Adobe Flash player
by NME 12 Mar 2016
package {
    import flash.filters.BlurFilter;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.geom.Matrix;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        public function FlashTest() {
            
          //setting up the data for the control points layer that will be added later
          var cp0:Pt = new Pt(10,200);
          var cp1:Pt = new Pt(200,25);
          var cp2:Pt = new Pt(400,300);
           
          //control points layer
          var cpl:Sprite = new Sprite();
          var cp0Box:CtrlPtBox = new CtrlPtBox();
               cp0Box.x = cp0.x;
               cp0Box.y = cp0.y;
               cp0Box.ptData = cp0;
          var cp1Box:CtrlPtBox = new CtrlPtBox();
               cp1Box.x = cp1.x;
               cp1Box.y = cp1.y;
               cp1Box.ptData = cp1;
          var cp2Box:CtrlPtBox = new CtrlPtBox();
               cp2Box.x = cp2.x;
               cp2Box.y = cp2.y;
               cp2Box.ptData = cp2;
           
          cpl.addChild(cp0Box);
          cpl.addChild(cp1Box);
          cpl.addChild(cp2Box);
            
            
          //number of steps to take along the path
          var n:uint = 100;
            
            
          var dotr:uint = 20;
          var blurAmount:uint = 8;
          //making the sprite that will be used as a brush
          var brushContainer:Sprite= new Sprite();
          var ldot:Shape = new Shape();
          var g:Graphics = ldot.graphics;
          g.lineStyle(1,0x666666,1);
          g.drawCircle(dotr+blurAmount,dotr+blurAmount,dotr);
          ldot.filters = [new BlurFilter(blurAmount,blurAmount,3)];
          //workaround to be sure we get the all the bitmap data including the blurred areas
          brushContainer.addChild(ldot);
          g = brushContainer.graphics;
          g.lineStyle(1,0x000000,0);
          g.drawRect(0,0,(blurAmount+dotr)*2,(blurAmount+dotr)*2);
          
          //turning the brush into bitmap data
          var brushBMD:BitmapData = new BitmapData(brushContainer.width,brushContainer.height,true,0);
          brushBMD.draw(brushContainer,new Matrix(1,0,0,1,0,0));
            
          //making a bitmap canvas the size of the stage
          var bmd:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false,0xffffff);//the colour needs to be 0 in order to be transparent
          var bmp:Bitmap = new Bitmap(bmd,'never',true);
            
            
          drawPts(bmp,findQuadBezPts_nsubdivisions(cp0,cp1,cp2,n),brushBMD);
          stage.addChild(bmp);
          
          //adding the control point layer
          stage.addChild(cpl);
           
          var isDragging:Boolean = false;
          var instanceOfDraggedObject:Object;
          
           
           //setting up the listeners using anonymous funtions for now to make things easier on me
           //this may be familiar to someone that knows Javascript
           cpl.addEventListener(MouseEvent.MOUSE_DOWN,
               function(me:MouseEvent):void{
                   isDragging=true;
                   instanceOfDraggedObject = me.target;
               }); 
           stage.addEventListener(MouseEvent.MOUSE_UP,
               function(me:MouseEvent):void{
                   isDragging=false;
               });
           
          
           stage.addEventListener(MouseEvent.MOUSE_MOVE,
               function(me:MouseEvent):void{
                   if(me.buttonDown && isDragging){
                           instanceOfDraggedObject.ptData.x = me.stageX;
                           instanceOfDraggedObject.ptData.y = me.stageY;//
                           
                           instanceOfDraggedObject.x = me.stageX;
                           instanceOfDraggedObject.y = me.stageY;
                           drawPts(bmp,findQuadBezPts_nsubdivisions(cp0,cp1,cp2,n),brushBMD);
                      
                   }
                   me.updateAfterEvent();
                   
               });
          
           var ctrlLayerIsVisible:Boolean = true;
           stage.addEventListener(KeyboardEvent.KEY_UP,
               function(ke:KeyboardEvent):void{
                   if(ke.keyCode == 88){
                      if(ctrlLayerIsVisible){
                          ctrlLayerIsVisible = false;
                          stage.removeChild(cpl);
                      }else {
                          ctrlLayerIsVisible = true;
                          stage.addChild(cpl);
               }}});
               stage.addEventListener(KeyboardEvent.KEY_DOWN,
               function(ke:KeyboardEvent):void{
                   if(ke.keyCode==40){
                       if(n>1){
                           n--;
                           drawPts(bmp,findQuadBezPts_nsubdivisions(cp0,cp1,cp2,n),brushBMD);
                       }
                   }else if(ke.keyCode==38){
                       if(n<0xffffff){
                           n++;
                           drawPts(bmp,findQuadBezPts_nsubdivisions(cp0,cp1,cp2,n),brushBMD);
                 }}});
            
        }
        
        public function drawPts(bmp:Bitmap,pts:Vector.<Pt>,sBMD:BitmapData):void{
            var bmd:BitmapData = new BitmapData(bmp.width,bmp.height,false,0xffffff);
            var lenPts:uint = pts.length;
            var offsetX:Number = sBMD.rect.width*0.5;
            var offsetY:Number = sBMD.height*0.5;
            var m:Matrix = new Matrix(1,0,
                                      0,1,  0,0);
            for (var i:uint = 0;i!=lenPts;++i){
                m.tx = pts[i].x - offsetX;
                m.ty = pts[i].y - offsetY;
                bmd.draw(sBMD,m);
            }
            bmp.bitmapData=bmd;
        }
        public function findQuadBezPts_nsubdivisions(p0:Pt,p1:Pt,p2:Pt,n:uint=100):Vector.<Pt>
        {
            //the length of the returning vector will be the number of subdivisions +2, in order to include
            //the starting and ending points
            
            if(n<1){
                n=1;
            }
                    
            var locus:Vector.<Pt> = new Vector.<Pt>;
            //first 1
            locus[0] = new Pt(p0.x,p0.y);
            
            
            //the stuff in the middle
            //varibles to store for the loop..
            var p1xNegP0x:Number = p1.x - p0.x;
            var p1yNegP0y:Number = p1.y - p0.y;
            //p2-p1 can be stored
            var p2xNegP1x:Number = p2.x - p1.x;
            var p2yNegP1y:Number = p2.y - p1.y;
           
            var m0:Number,m1:Number;  
            var i:uint = 0;
            var t:Number = 0;
            var inc:Number = 1/n;
            for (i=1; i<n;i+=1){
                t+=inc;
                locus[i] = new Pt();
                m0 = p0.x + p1xNegP0x*t;
                m1 = p1.x + p2xNegP1x*t;
                locus[i].x =  m0 + (m1-m0)*t;
                
                m0 = p0.y + p1yNegP0y*t;
                m1 = p1.y + p2yNegP1y*t;
                locus[i].y =  m0 + (m1-m0)*t;
                
            }
            
            
            //final 1
            locus[n] = new Pt(p2.x,p2.y);
            return locus;
            
        }
    }
}
import flash.display.Graphics;
internal class Pt{
   public var x:Number;
   public var y:Number;
   public function Pt(x:Number=0,y:Number=0){  
       this.x=x;
       this.y=y;  
   }
}

import flash.display.Sprite;
internal class CtrlPtBox extends Sprite{
   public var ptData:Pt;
    
    public function CtrlPtBox(w:uint = 10,h:uint=10,colour:uint=0x000000){
        
        this.buttonMode = true;
        drawBox(w,h,colour);
    }
    public function drawBox(w:uint=10,h:uint=10,colour:uint= 0x000000):void{
        var g:Graphics = this.graphics;
        g.beginFill(colour,1); //
        g.drawRect(-w/2,-h/2,w,h);
    }
    
}