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

Bezier Intersections

bezier intersection demo
drag dots.. red dots are intersections
more info: http://actionsnippet.com/?p=965
Get Adobe Flash player
by shapevent 06 Aug 2009
/**
 * Copyright shapevent ( http://wonderfl.net/user/shapevent )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/oTTm
 */

// forked from shapevent's flash on 2009-8-6
package {

        // bezier intersection demo
        // drag dots.. red dots are intersections
        // more info: http://actionsnippet.com/?p=965
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	
	dynamic public class BezierIntersections extends MovieClip {
		private var resolution:Number;
		private var pointNum:int;
		private var bezA:Array;
		private var a:Sprite;
		private var b:Sprite;
		private var c:Sprite;
		private var bezB:Array;
		private var d:Sprite;
		private var e:Sprite;
		private var f:Sprite;
		private var ip:Point;

		
		public function BezierIntersections(){
		   // init
			resolution = .03;
			pointNum = Math.ceil(1 / resolution);
			bezA = new Array();
			populateArray(bezA);
			a = dot(100, 200);
			b = dot(200, 100);
			c = dot(300, 200);
			bezB = new Array();
			populateArray(bezB);
			d = dot(300, 100, 0xCCCC00);
			e = dot(120, 130, 0xCCCC00);
			f = dot(200, 300, 0xCCCC00);
			addEventListener(Event.ENTER_FRAME, onLoop);
			
			
			
			
			
			ip = new Point();
			
			// draggable dot
			
			
			stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
			

		}
		// private methods

		private function onLoop(evt:Event):void {
			  with(graphics){
				  clear();
				  lineStyle(0, 0x000000);
				  // calc and draw bezier points
				  drawBezier(bezA, a, b, c);
				  drawBezier(bezB, d, e, f);
				  // calc collisions
				  var intersections:Array = calculateIntersection(bezA, bezB);
				   // draw collisions
				   beginFill(0xFF0000);
				   if (intersections.length> 0){
						for (var i:int = 0; i<intersections.length; i++){
							drawCircle(intersections[i].x, intersections[i].y, 3);
						}
				   }
				   endFill();
			 }
		}
		private function populateArray(a:Array):void {
			for (var i:int = 0; i<pointNum; i++){
				a.push(new Point());
			}
		}
		private function drawBezier(bez:Array, a:Sprite, b:Sprite, c:Sprite):void{
			 with(graphics){
				 bezier(bez, a.x, a.y, b.x, b.y, c.x, c.y);
				 var leng:Number = bez.length;
				 moveTo(bez[0].x, bez[0].y);
				 for (var i:int = 1; i<leng; i++){
					 lineTo(bez[i].x, bez[i].y);
				 }
			 }
		}
		private function bezier(bez:Array, x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number):void {
					var b:Number, a2:Number, ab2:Number, b2:Number;
					var pnt:Point;
					var inc:int = 0;
					for (var a:Number = 0; a <=1; a+=resolution) {
						b= 1 - a;
						a2 = a * a;
						ab2 = a * b * 2;
						b2 = b * b;
						pnt = bez[inc];
						pnt.x = a2 * x1 + ab2 * x2  + b2 * x3;
						pnt.y = a2 * y1 + ab2 * y2 + b2 * y3;
						inc++;
					}
		}
		private function calculateIntersection(bezA:Array, bezB:Array):Array {
			var intersections:Array = new Array();
			var ip:Point;
			var aLength:int = bezA.length;
			var bLength:int = bezB.length;
			var p1:Point, p2:Point, p3:Point, p4:Point;
			// compare all line segments and check for
			// intersections
			for (var i:int = 1; i<aLength; i++){
				p1 = bezA[i - 1];
				p2 = bezA[i];
				for (var j:int = 1; j<bLength; j++){
					p3 = bezB[j - 1];
					p4 = bezB[j];
					ip = intersection(p1, p2, p3, p4);
					if (ip){
						intersections.push(ip.clone());
					}
				}
			}
			return intersections;
		}
		private function intersection(p1:Point, p2:Point, p3:Point, p4:Point):Point {
			var nx:Number, ny:Number, dn:Number;
			var x4_x3:Number = p4.x - p3.x;
			var pre2:Number = p4.y - p3.y;
			var pre3:Number = p2.x - p1.x;
			var pre4:Number = p2.y - p1.y;
			var pre5:Number = p1.y - p3.y;
			var pre6:Number = p1.x - p3.x;
			nx = x4_x3 * pre5 - pre2 * pre6;
			ny = pre3 * pre5 - pre4 * pre6;
			dn = pre2 * pre3 - x4_x3 * pre4;
			if (dn == 0){
				return null
			}
			nx /= dn;
			ny /= dn;
			// has intersection
			if(nx>= 0 && nx <= 1 && ny>= 0 && ny <= 1){
				ny = p1.y + nx * pre4;
				nx = p1.x + nx * pre3;
				ip.x = nx;
				ip.y = ny;
			}else{
				 return null;
			}
			return ip
		}
		private function dot(xp:Number, yp:Number, col:uint = 0x507399, noDrag:Boolean = false):Sprite {
			var s:Sprite = Sprite(addChild(new Sprite));
			s.x = xp;
			s.y = yp;
			with(s.graphics) beginFill(col), drawCircle(0,0,5);
			if (!noDrag){
				s.buttonMode = true;
			   s.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
			}
			return s;
		}
		private function onDrag(evt:MouseEvent):void {
			evt.currentTarget.startDrag()
		}
		private function onUp(evt:MouseEvent):void{
			stopDrag();
		}
		

	}

}