交点4

by hashito
MainStage
♥0 | Line 149 | Modified 2010-08-22 11:28:28 | MIT License
play

ActionScript3 source code

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

// forked from hashito's 文字集まる修正
// MainStage
package {
    import flash.display.Sprite;
    [SWF(frameRate=60,width=456,height=456)]
    public class MainStage extends Sprite {
        public function MainStage(){
            addChild(new Main());
        }
    }
}

import flash.display.*;
import flash.filters.BlurFilter;
import flash.geom.Point;
import flash.geom.ColorTransform;
import flash.events.*;
import flash.utils.Timer;
import flash.text.TextField;
import flash.text.TextFormat;
import net.hires.debug.Stats;
// debug
class debug{public static var out:TextField=new TextField();}

/*t.hashito*/
class MF{
    public static function AFFORD (x:Number,aim:Number,a:Number):Boolean{return (x<=(a+aim))&&(x>=(a-aim));}
    public static function RAN (n:Number=1):Number{return (Math.random()*n);}
    public static function ISPM (n:Number):Number{if(n<0){return -1;}else if(n>0){return 1;}return 0;}
    public static function MAX (n:Number,max:Number):Number{return (n>max)?max:n;}
    public static function MIN (n:Number,min:Number):Number{return (n<min)?min:n;}
    public static function LIMIT (n:Number,max:Number,min:Number):Number{if(n>max){return max;}else if(n<min){return min;}else{return n};}
    public static function RAD_ANG(n:Number):Number{return n*180/Math.PI}
    public static function ANG_RAD(n:Number):Number{return n*Math.PI/180 }
    public static function LATCH(v:Boolean,s:Boolean,r:Boolean):Boolean{if(s)v=true;if(r)v=false;return v;}
    public static function ONE_SHOT_ON(v:Boolean,o:Boolean):Boolean{var r:Boolean = (v==(!o));o=v;return r;}
    public static function DOT2(x1:Number,y1:Number,x2:Number,y2:Number):Number{return x1 * x2 + y1 * y2; }//内積
    public static function SLOPE(x1:Number,y1:Number,x2:Number,y2:Number):Number{if((x1-x2)!=0)return (y1-y2)/(x1-x2);return 0; }//傾き
    public static function DISTANCE(x1:Number,y1:Number,x2:Number,y2:Number):Number{var a:Number=(x2-x1);var b:Number=(y2-y1);return Math.sqrt(a*a+b*b);}//距離
}

class Main extends Sprite{
    public const H:Number = 456,W:Number = 456;
    public var mx:Number = 0,my:Number = 0;
    public var ksp:Boolean   = false;
    public var la:Shape   = new Shape(),la1x:Number,la1y:Number,la2x:Number,la2y:Number;
    public var lb:Shape   = new Shape(),lb1x:Number,lb1y:Number,lb2x:Number,lb2y:Number;
    public var cross:Shape   = new Shape();
    public var t:Shape   = new Shape();
    public var select:int = 0;
    public const SELMAX:int = 4;
    
    // constructor
    public function Main() {addEventListener(Event.ADDED_TO_STAGE, init);}
    // init
    public function init(e:*):void{
        // debug
        debug.out.autoSize=flash.text.TextFieldAutoSize.LEFT;
        addChild(debug.out);
        
        la1x = MF.RAN(W);
        la1y = MF.RAN(H);
        la2x = MF.RAN(W);
        la2y = MF.RAN(H);
        lb1x = MF.RAN(W);
        lb1y = MF.RAN(H);
        lb2x = MF.RAN(W);
        lb2y = MF.RAN(H);
        //line init
        addChild(la);
        addChild(lb);
        
        // cross init
        addChild(cross);
        
        
        addEventListener(Event.ENTER_FRAME ,ef);
        stage.addEventListener(KeyboardEvent.KEY_DOWN ,key);
        
        var s:Stats = new Stats();
        addChild(s);
    }
    public function key(e:KeyboardEvent=null):void{
        if (e.keyCode == 32) {// space
            if(SELMAX <= ++select)
                select = 0;
        }
    }
    
    public function ef(e:Event=null):void{
        mx = mouseX;
        my = mouseY;
        
        if(select == 0){        la1x=mx;la1y=my;
        }else if(select == 1){    la2x=mx;la2y=my;
        }else if(select == 2){    lb1x=mx;lb1y=my;
        }else if(select == 3){    lb2x=mx;lb2y=my;
        }else{}
                
        la.graphics.clear();
        la.graphics.lineStyle(2,0xff0000);
        la.graphics.moveTo(la1x,la1y);
        la.graphics.lineTo(la2x,la2y); 
        
        lb.graphics.clear();
        lb.graphics.lineStyle(2,0xffff00);
        lb.graphics.moveTo(lb1x,lb1y);
        lb.graphics.lineTo(lb2x,lb2y);
        
        
        
        // http://atelier-peppe.jp/programTips/GEOMETRIC/KIKA_7.html
        // 参考にしました。。。
        var rx:Number,ry:Number,br:Boolean=false;
        var b1:Number,m1:Number;
        var b2:Number,m2:Number;
        var minX:Number,minY:Number,maxX:Number,maxY:Number;
        
        // ** まず、それぞれの線分を線として交点を求める
        // line1は垂直ではない(y軸に平行ではない)
        if(la1x != la2x){
            // 1の傾き
            m1 = (la2y - la1y) / (la2x - la1x);
            // 1の切片
            b1 = la2y - (m1 * la2x);
            
            // line2は垂直ではない(y軸に平行ではない)
            if(lb1x != la2x){
                // 2の傾き
                m2 = (lb2y - lb1y) / (lb2x - lb1x);
                // 2の切片
                b2 = lb2y - (m2 * lb2x);
                // もし線が平行の場合は、交点はない
                if(m2 == m1){
                    // 平行 ***
                    br =  false;
                }
                else{
                    // 直線の公式にのっとって、交点を算出
                    rx = (b1 - b2) / (-(m1 - m2));
                    ry = m1 * rx + b1;
                }
            }
            // line2は垂直
            else{
                // line2は垂直なので、x値は変わらない
                rx = lb1x;
                // 直線の公式に当てはめる
                ry = m1 * rx + b1;
            }
        }
        // line1は垂直(y軸に平行)
        else{
            // line2が垂直の場合、平行
            if(lb1x == lb2x){
                // 平行**
                br =  false;
            }
            else{
                // 2の傾き
                m2 = (lb2y - lb1y) / (lb2x - lb1x);
                // 2の切片
                b2 = lb2y - (m2 * lb2x);
                
                // line1は垂直なので、x値は変わらない
                rx = la1x;
                // 直線の公式に当てはめる
                ry = m2 * rx + b2;
            }
        }

        // **求めた交点が、それぞれの線分の領域に乗っているか
        minX = la1x < la2x ? la1x : la2x;
        minY = la1y < la2y ? la1y : la2y;
        maxX = la1x < la2x ? la2x : la1x;
        maxY = la1y < la2y ? la2y : la1y;

        if(maxX >= rx && minX <= rx 
        && maxY >= ry && minY <= ry
        ){
            minX = lb1x < lb2x ? lb1x : lb2x;
            minY = lb1y < lb2y ? lb1y : lb2y;
            maxX = lb1x < lb2x ? lb2x : lb1x;
            maxY = lb1y < lb2y ? lb2y : lb1y;
            
                           
            if(maxX >= rx && minX <= rx 
            && maxY >= ry && minY <= ry
            ){
                br = true;
            }
        }else{
            debug.out.text="out";
        
        }
        
        cross.x = rx;
        cross.y = ry;
        
        cross.graphics.beginFill(0xeeeeff);
        if(br)
            cross.graphics.beginFill(0x000000);
        cross.graphics.drawCircle(0,0,5);

        debug.out.x=la1x;
        debug.out.y=la1y;
        //debug.out.text=""+ MF.SLOPE(la1x,la1y,la2x,la2y);
        
        //debug.out.text="x="+t.bits[0].x+" y="+t.bits[0].y+" vx="+t.bits[0].vx+" vy="+t.bits[0].vy+" ax="+t.bits[0].ax+" ay="+t.bits[0].ay;
    }
}