Beautifl - Flash Gallery

Thumbnail : Vector Perpendicular Projection
Vector Perpendicular Projection
tsu_droid 2014-07-01 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

package {
    import flash.display.Sprite;
    
    public class FlashTest extends Sprite {
        
        private var A:DP;
        private var B:DP;
        private var C:DP;
        
        private var tV:T;
        private var tU:T;
        private var tPV:T;
        private var tPer:T;
        
        private var V:Vec;
        private var U:Vec;
        
        private var pV:Vec;
        private var per:Vec;
        
        public function FlashTest() {
            // write as3 code here..
            
            A = new DP( update, "A", 0xB4C2D3, this, 50, 300 );
            B = new DP( update, "B", 0x79CD1D, this, 300, 250 );
            C = new DP( update, "C", 0xE18B17, this, 100, 130 );
            
            tV = new T("V", 0,0, 0x79CD1D, true );                addChild( tV );
            tU = new T("U", 0,0, 0xE18B17, true );                addChild( tU );
            tPV = new T("Proj v.u", 0,0, 0xD623D6 );        addChild( tPV );
            tPer = new T("Perpendicular", 0,0, 0x1D95DC );        addChild( tPer );
            
            update(null);
        }
        
        private function update( P:DP ):void
        {
            graphics.clear();
            
            // Calc vectors
            
            V = Vec.PP2V( A.point, B.point );
            V.lenght -= 12;
            
            U = Vec.PP2V( A.point, C.point );
            U.lenght -= 12;
            
            pV = V.projection( U );
            per = U.clone().subtract( pV );
            
            //Draw vectors
            V.render( graphics, A.point, 0x79CD1D, 4 );
            U.render( graphics, A.point, 0xE18B17, 4 );
            pV.render( graphics, A.point, 0xD623D6, 2 );
            per.render( graphics, pV.point.add( A.point ), 0x1D95DC, 2 );
            
            
            // Update labels
            V.lenght /= 2; tV.x = A.x + V.x; tV.y = A.y + V.y;
            U.lenght /= 2; tU.x = A.x + U.x; tU.y = A.y + U.y;
            per.lenght /= 2; 
            tPer.x = A.x + per.x + pV.x; 
            tPer.y = A.y + per.y + pV.y;
            
            pV.lenght /= 2; tPV.x = A.x + pV.x; tPV.y = A.y + pV.y;
            
            
        }
    }
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;



class DP extends Sprite
{
    public function get point():Point{ return new Point(x,y) };
    private var onChange:Function;
    private var color:uint;
    
    public function DP( 
        onChange:Function = null, 
        label:String = "P", 
        color:uint = 0xF3CE5C,
        parent:Sprite = null, 
        x:Number = 0, 
        y:Number = 0)
    {
        buttonMode = useHandCursor = true;
        
        this.x = x;
        this.y = y;
        if ( parent ) parent.addChild( this );
        
        alpha = 0.8;
        this.color = color;
        this.onChange = onChange;
        draw( 9 );
        
        addChild( new T(label) );
        
        addEventListener(MouseEvent.MOUSE_DOWN, onMD);
    }
    
    private function onMU(e:MouseEvent):void 
    {
        draw( 9 );
        alpha = 0.8;
        stopDrag();
        if ( onChange != null ) onChange( this );
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMM);
        stage.removeEventListener(MouseEvent.MOUSE_UP, onMU);
    }
    
    
    private function onMD(e:MouseEvent):void 
    {
        draw( 14 , true );
        alpha = 1;
        startDrag(true);
        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMM);
        stage.addEventListener(MouseEvent.MOUSE_UP, onMU);
    }
    
    private function onMM(e:MouseEvent):void 
    {
        if ( onChange != null ) onChange( this );
    }
    private function draw( r:Number, b:Boolean = false ):void
    {
        graphics.clear();
        if ( b ) graphics.lineStyle(3, 0x666666);
        graphics.beginFill(color);
        graphics.drawCircle(0, 0, r);
        graphics.endFill();
    }
    
}

class T extends TextField
{
    /** @author http://wonderfl.net/user/Vladik */
    public function T(txt:String = "Text", x:Number = 0, y:Number = 0,c:uint = 0x0,b:Boolean = false)
    {
        var tf:TextFormat = new TextFormat("_sans", 12, c, b);
        this.setTextFormat(tf);
        this.defaultTextFormat = tf;
        this.autoSize = 'left';
        this.text = txt;
        this.textColor = c;
        this.selectable = this.wordWrap = this.multiline = this.mouseEnabled = false;
        
        this.x = x - this.width / 2;
        this.y = y - this.height / 2;
    }
}

class Vec
{
    // Convert a line between two point into a vector
    static public function PP2V(a:Point, b:Point):Vec{return new Vec(b.x - a.x, b.y - a.y);}
    // Convert line 2 point
    static public function P2V(p:Point):Vec{return new Vec(p.x,p.y);}
    
    // Angle between two vectors in radians
    static public function RadiansBetween( A:Vec, B:Vec):Number
    {
        
        return Math.acos( A.clone().normalise().dot( B.clone().normalise() ) );
        
        //return Math.acos( A.dot(B) / ( A.lenght + B.lenght );
    }
    
    public function normalise():Vec
    {
        lenght = 1;
        return this;
    }
    
    //http://jccc-mpg.wikidot.com/vector-projection
    public function projection( u:Vec ):Vec
    {
        var l:Number = lenght;
        return clone().scale( u.dot( this ) / (l * l) );
    }
    
    /** @author http://wonderfl.net/user/Vladik */
    public var x:Number, y:Number;
    public function Vec(x:Number = 0, y:Number = 0){this.x = x;this.y = y;}
    public function get lenght():Number{return Math.sqrt(x * x + y * y);}
    public function set lenght(value:Number):void{lenght == 0 ? scale(0) : scale(value / lenght);}
    public function set degrees(value:Number):void{radians = value * Math.PI / 180;}
    public function get degrees():Number{return radians * 180 / Math.PI;}
    public function set radians(value:Number):void{var f:Number = lenght;x = Math.cos(value) * f;y = Math.sin(value) * f;}
    public function scale(n:Number):Vec { x *= n; y *= n; return this; }
    public function clone():Vec{return new Vec(x, y);}
    public function get radians():Number { return Math.atan2(y, x); }
    public function dot( v:Vec ):Number { return x * v.x + y * v.y; }
    public function get point():Point { return new Point(x, y); }
    
    public function distToPoint( p:Point ):Number
    {
        return p.length * Math.sin( Vec.RadiansBetween( this, Vec.P2V(p) ) );
    }
    
    public function toString():String{return "["+x.toFixed(2)+","+y.toFixed(2)+"]";}

    
    public function render( g:Graphics, o:Point = null, color:uint = 0xFF0000, thikness:uint = 3 ):void
    {
        g.beginFill( color );
        g.lineStyle( thikness, color);
        g.moveTo( o.x, o.y);
        
        var B:Point = new Point(o.x + x, o.y + y);
        
        g.lineTo( B.x, B.y);
        
        var v:Vec = Vec.PP2V( o, B );
        v.lenght = 7;
        
        v.degrees -= 45 + 180;
        g.lineTo( B.x + v.x, B.y + v.y );
        
        v.degrees += 90;
        g.lineTo( B.x + v.x, B.y + v.y );
        
        g.lineTo( B.x, B.y );
        
        g.endFill();
    }
    
    public function add( V:Vec ):Vec
    {
        this.x += V.x;
        this.y += V.y;
        return this;
    }
    public function subtract(V:Vec):Vec
    {
        this.x -= V.x;
        this.y -= V.y;
        return this;
    }
}