forked from: forked from: CirclesLoveLines step 1

by onedayitwillmake forked from forked from: CirclesLoveLines step 1 (diff: 50)
CirclesLoveLines step 2
* @Revision 
* 		- Lets project a line segment from lineA to circlaA!
* 
* @author Mario Gonzalez
* @see http://onedayitwillmake.com/
* @note: This series of experiments is being created because.
♥0 | Line 119 | Modified 2009-05-13 22:48:45 | MIT License
play

ActionScript3 source code

/**
 * Copyright onedayitwillmake ( http://wonderfl.net/user/onedayitwillmake )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/l4Pb
 */

/**
 * CirclesLoveLines step 2
 * @Revision 
 * 		- Lets project a line segment from lineA to circlaA!
 * 
 * @author Mario Gonzalez
 * @see http://onedayitwillmake.com/
 * @note: This series of experiments is being created because.
 */
package
{ 
		
    import flash.display.Sprite;
	
	[SWF(frameRate="60", width="465", height="465", backgroundColor="#00ffcc")]
	
    public class CircleLineSegmentTest extends Sprite
    {
    	public function CircleLineSegmentTest():void
    	{
    		var A:Vector2D = new Vector2D(Math.random() * stage.stageWidth, Math.random() * stage.stageHeight);
    		var B:Vector2D = new Vector2D(Math.random() * stage.stageWidth, Math.random() * stage.stageHeight);
    		var V:Vector2D = B.minus(A);
    		
    		var X:Vector2D = new Vector2D(Math.random() * stage.stageWidth, Math.random() * stage.stageHeight);
    		var W:Vector2D = X.minus(A);
    		
    		var lineA:Line = new Line(A, B, 0xff0000);
    			addChild(lineA);
   
    		var lineB:Line = new Line(X, A.minus(A)); 
    			addChild(lineB);
    			
    		var circleA:Circle = new Circle(closestPointLineSegment(X, A, B), 8);
    			addChild(circleA);
    	}
    	/**
    	 * Find the closest point in a linesegment given point X  
    	 * @param X	Point to test against. 
    	 * @param A LineSegment point A
    	 * @param B LineSegment point B
    	 */    	
    	public static function closestPointLineSegment(X:Vector2D, A:Vector2D, B:Vector2D):Vector2D
    	{
		    var v:Vector2D = B.minus( A );
		    var w:Vector2D = X.minus( A );
		    var wDotv:Number = w.dot( v );
		    var t:Number = w.dot( v ) / v.dot( v );
		    t = clamp( 0, 1, t );
		    return A.plus( v.times( t ) );
    	}
    	
    	public static function clamp(min:Number, max:Number, val:Number):Number
    	{
    		 return Math.max(min, Math.min(max, val))
    	}
    }
}

import flash.geom.Point;
import flash.display.Shape;
import flash.display.Sprite;

internal class Vector2D
{
	public var x:Number, y:Number
	public function Vector2D(x1:Number, y1:Number):void
	{
		x = x1;
		y = y1;
	}
	
	public function minus(from:Vector2D):Vector2D
	{
		return new Vector2D(x - from.x, y - from.y);
	}
	
	public function plus(from:Vector2D):Vector2D
	{
		return new Vector2D(x + from.x, y + from.y);
	}
	
	public function times(z:Number):Vector2D
	{
		return new Vector2D(x * z, y * z);
	}
	
	//proj(w,v) = dot(w,v) / dot(v,v)
	public function project(from:Vector2D):Number
	{
		return dot(from) / from.dot(from);
	}
	
	// w.x * v.x + w.y * v.y
	public function dot(from:Vector2D):Number
	{
		return x * from.x + y * from.y;
	}
}

internal class Line extends Shape
{
	public var A:Vector2D, B:Vector2D; //A |----| B
	
	//Draw
	public var _color		:uint = 0x666666;
	public var __isDirty	:Boolean = false;
	public function Line(a:Vector2D, b:Vector2D, color:uint = 0x666666):void
	{
		A = a;
		B = b;
		_color = color;
		_isDirty = true;
	}
	
	public function draw():void
	{
		resetGraphics();
		graphics.moveTo(A.x, A.y);
		graphics.lineTo(B.x, B.y);
	}
	
	public function resetGraphics():void
	{
		graphics.clear();
		graphics.lineStyle(2, _color, 0.75);
	}
	
	public function get _isDirty():Boolean { return __isDirty };
	public function set _isDirty(value:Boolean):void
	{
		__isDirty = value;
		draw();
	}
}

internal class Circle extends Sprite
{
	public var _center	:Vector2D;
	public var _radius	:int;
	
	public function Circle(center:Vector2D, radius:int):void
	{
		_center = center;
		_radius = radius;
		
		x = _center.x;
		y = _center.y;
		
		//Draw
		graphics.beginFill(0xffffff, 1)
			graphics.drawCircle(0, 0, 2);
			graphics.drawCircle(0, 0, 6);
			graphics.drawCircle(0, 0, 7);
		graphics.endFill();
	}
	
	public function resetGraphics():void
	{
		graphics.clear();
		graphics.lineStyle(1, 0x666666, 1);
	}
}

Forked