Linear interpolation

by WLAD forked from Fake Linear interpolation - Vector2D Method (diff: 204)
Drag the sky blue Points

-------------------------------------------------------------------

public static function interpolate(pt1:Point, pt2:Point, f:Number):Point
{
     var x:Number = (1 - f) * pt1.x + f * pt2.x;
     var y:Number = (1 - f) * pt1.y + f * pt2.y;
     return new Point(x, y);
}
♥0 | Line 241 | Modified 2014-08-19 07:34:56 | MIT License
play

ActionScript3 source code

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

// forked from Vladik's Fake Linear interpolation - Vector2D Method
package {
    import flash.display.Sprite;
    import flash.display.Graphics;
    import flash.geom.Point;
    import com.bit101.components.PushButton;
    import com.bit101.components.Style;
    
    
    public class FlashTest extends Sprite {
        
        
        private var a:DragablePoint;
        private var b:DragablePoint;
        
        private var points:Array = [
            new Point(0, 0.1),
            new Point(0.1, 0.5),
            new Point(0.2, 0.2),
            new Point(0.3, 1),
            new Point(0.5, 0),
            new Point(0.6, 1),
            new Point(0.7, 0.5),
            new Point(1, 0.9)
            
        ];
        
        private var g:Graphics;
        
        private var g2:Graphics;
        
        public function FlashTest() {
            // write as3 code here..
            
            graphics.beginFill(0);
            graphics.drawRect(0,0,500,500);
            graphics.endFill();
            
            var s:Sprite = new Sprite();
            addChild( s );
            g = s.graphics;
            s = new Sprite();
            addChild( s );
            g2 = s.graphics;
            
            
            a = new DragablePoint(onMove);
            a.DP_Normal.bg = a.DP_Normal.border = 0x7DD5FF;
                   
            addChild(a);
            
            a.x = 100;
            a.y = 200;
            
            b = new DragablePoint(onMove);
            b.DP_Normal.bg = b.DP_Normal.border = 0x7DD5FF;
            addChild(b);
            
            b.x = 400;
            b.y = 300;
            
            var btn:PushButton = new PushButton(this, 250, 10, "Randomize", function(e:*=null):void
            {        var c:int = 0; while(c<8) points[++c] = new Point( c/8, Math.random() ); onMove();    });
            btn.scaleX = btn.scaleY = 2;
            
            onMove();
            
            addEventListener("enterFrame", update);
        }
        
        private function update(e:*=null):void
        {
            g2.clear();
            
            var gap:int = 10;
            
            // Line start value
            var ls:int = 30;
            // Line end value
            var le:int = 150;
            
            // ************************* PINK
            g2.lineStyle( 6, 0xFF00FF );
            g2.moveTo( ls, gap );
            g2.lineTo( le, gap );
            var mx:Number = mouseX < ls ? ls : ( mouseX > le ? le : mouseX );
            g2.drawCircle( mx , gap, 5 );
            g2.lineStyle( 2, 0xCCCCCC, 0.2 );
            g2.moveTo( mx, 0 );
            g2.lineTo( mx, 500 );
            
            // ************************* SKIN COLOR
            g2.lineStyle( 6, 0xEBD592);
            g2.moveTo( gap, ls );
            g2.lineTo( gap, le);
            var my:Number = mouseY < ls ? ls : ( mouseY > le ? le : mouseY );
            g2.drawCircle( gap , my, 5 );
            g2.lineStyle( 2, 0xCCCCCC, 0.2 );
            g2.moveTo( 0, my );
            g2.lineTo( 500, my );
            
            var vx:Number = ( mx - ls ) / ( le-ls );
            var vy:Number = ( my - ls ) / ( le-ls ); 
            
            // ************************* ALPHA ( draw lines the standart way )
            
            g2.lineStyle( 3, 0xFFFFFF, 0.2 );
            
            var px:Number, py:Number;
            
            for( var i:int = 0; i < points.length; i++ )
            {
                px = ls + ( le - ls ) * points[i].x;
                py = ls + ( le - ls ) * points[i].y;
                
                if( i == 0 ) g2.moveTo( px, py );
                else g2.lineTo( px, py );
            }
            
            
            // ************************* YELLOW
            g2.lineStyle( 6, 0xFFFF00 );
            g2.drawCircle( mx, my, 5 );
            
            // ************************* ORANGE 
            
            var p:Point = cubicCoord( tl, tr, bl, vx, vy );
           
            g2.lineStyle( 6, 0xFF7D00);
            g2.drawCircle( p.x, p.y, 5 );
        }
        
        ///////////////////////////////////////////////////////////////////////////////////////
        
        public function cubicCoord( tl:Point, tr:Point, bl:Point, vx:Number, vy:Number ):Point
        {
            var px:Point = interpolate( tl, tr, vx );
            px.x -= tl.x;
            px.y -= tl.y;
            
            var py:Point = interpolate( tl, bl, vy );
            py.x -= tl.x;
            py.y -= tl.y;
            
            var p:Point = tl.clone();
            p.x += px.x + py.x;
            p.y += px.y + py.y;
            
            return p;
         }
        
        public function interpolate(pt1:Point, pt2:Point, f:Number):Point
        {
             // Work's inverse to flash.geom.Point.interpolate()..
             //var x:Number = f * pt1.x + (1 - f) * pt2.x;
             
             var x:Number = (1 - f) * pt1.x + f * pt2.x;
             var y:Number = (1 - f) * pt1.y + f * pt2.y;
             return new Point(x, y);
        }
        
        ///////////////////////////////////////////////////////////////////////////////////////
        
        
        
        
        private var tl:Point, tr:Point, br:Point, bl:Point;
        
        private function onMove():void
        {
            // x-dist & y-dist between two points a & b
            var line:Point = new Point( b.x - a.x, b.y - a.y );
            
            // Top left
            tl = a.p;
            tl.x += line.y/2;
            tl.y -= line.x/2;
            
            // Bottom right
            br = tl.clone();
            br.x += line.x - line.y;
            br.y += line.y + line.x;
            
            // Bottom left
            bl = tl.clone();
            bl.x -= line.y;
            bl.y += line.x;
            
            // Top Right
            tr = tl.clone();
            tr.x += line.x;
            tr.y += line.y;
            
            g.clear();
            
            
            // ************************* GREEN 
            
            g.lineStyle( 3, 0x00FF00 );
            
            g.moveTo( tl.x, tl.y );
            g.lineTo( tr.x, tr.y );
            g.lineTo( br.x, br.y );
            g.lineTo( bl.x, bl.y );
            g.lineTo( tl.x, tl.y );
            
            // ************************* RED 
            
            g.lineStyle( 3, 0xFF0000 );
            g.drawCircle( tl.x, tl.y, 3 );
            g.drawCircle( bl.x, bl.y, 3 );
            g.drawCircle( tr.x, tr.y, 3 );
            g.drawCircle( br.x, br.y, 3 );
            
            
            
            // ************************* WHITE
            
            g.lineStyle( 3, 0xFFFFFF );
            
            for( var i:int = 0; i < points.length; i++ )
            {
                var p:Point = cubicCoord( tl, tr, bl, points[i].x, points[i].y );
                if( i == 0 ) g.moveTo( p.x, p.y );
                else g.lineTo( p.x, p.y );
            }
            
        }
        
    }
}

// HELPER CALSSES

/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////








	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
        import flash.geom.Point;

	/**
	 * ...
	 * @author vladik.voina@gmail.com
	 */
	class DragablePoint extends Sprite 
	{
		private var isStatic:Boolean;
		private var onMove:Function;
		


                public var DP_Normal:Object = 
		{ 
			
			border: 0x00FF00, 
			bg: 0x00FF00, 
			bs: 12, 
			radius: 9, 
			lineAlpha: 0.2
		};
		public var DP_Static:Object = 
		{ 
			border: 0xFF0000, 
			bg: 0x00FFFF, 
			bs: 0, 
			radius: 6, 
			alpha: 0.5
		};
		public var DP_Down:Object = 
		{ 
			border: 0xFF0000, 
			bg: 0xFF0000, 
			bs: 12, 
			radius: 9, 
			lineAlpha: 0.2
		};
		

		public function DragablePoint( onMove:Function = null , isStatic:Boolean = false ) 
		{
			this.onMove = onMove;
			this.isStatic = isStatic;
			useHandCursor = buttonMode = true;
			addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			draw( isStatic ? DP_Static : DP_Normal );
			addEventListener(MouseEvent.MOUSE_DOWN, onMD);
		}
		
		private function onMD(e:MouseEvent):void 
		{
			draw( DP_Down );
			
			stage.addEventListener(MouseEvent.MOUSE_UP, onMU);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, update);
		}
		
		public var dragBounds:Rectangle = null;
		
		private function update(e:MouseEvent):void 
		{
			if( !isStatic ) this.x = parent.mouseX;
			this.y = parent.mouseY;
			
			if ( dragBounds )
			{
				if ( !isStatic) 
				{
					if ( this.x - radius < dragBounds.x )
						this.x = dragBounds.x + radius;
					if ( this.x + radius > dragBounds.right )
						this.x = dragBounds.right - radius;				
				}
				
				if ( this.y - radius < dragBounds.y )
					this.y = dragBounds.y + radius;
				
				if ( this.y + radius > dragBounds.bottom )
					this.y = dragBounds.bottom - radius;
			}
			
			if ( onMove != null ) 
			{
				if ( onMove.length == 1 ) onMove( e );
				else onMove();
			}
		}
		
		private function onMU(e:MouseEvent):void 
		{
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMU);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, update);
			
			draw( isStatic ? DP_Static : DP_Normal );
		}
		
		private var radius:Number = 0;
		
		public function draw( style:Object ):void
		{
			var lineAlpha:Number  = style.hasOwnProperty("lineAlpha") ? style.lineAlpha : 1;
			
			graphics.clear();
			graphics.lineStyle( style.bs, style.border, lineAlpha );
			graphics.beginFill( style.bg );
			graphics.drawCircle( 0, 0, style.radius );
			graphics.endFill();
			
			if ( style.hasOwnProperty("alpha") ) alpha = style.alpha;
			else alpha = 1;
			
			radius = style.radius + style.bs / 2;
		}

                public function get p():Point { return new Point( x, y ); }
	}