forked from: ドラッグして描いた線の交差判定

by tepe forked from ドラッグして描いた線の交差判定 (diff: 1)
マウスで引いた線を描画する基本
マウスを押して動かしている間線を描いて
マウスを離したら終了
----------------------------------------
交点を検出して表示します。
交点でない場所でも、交点として表示されてしまうことがあるけど
交点はすべて検出できてる…よね。
----------------------------------------
↑uwiさんのforkを元に修正済み。ありがとうございました。
----------------------------------------
ToDo 線を3D化
♥0 | Line 103 | Modified 2011-02-11 10:19:51 | MIT License
play

ActionScript3 source code

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

// forked from Kay's ドラッグして描いた線の交差判定 
// forked from Kay's Basic お絵かき
/*
 * マウスで引いた線を描画する基本
 * マウスを押して動かしている間線を描いて
 * マウスを離したら終了
 *----------------------------------------
 * 交点を検出して表示します。
 * 交点でない場所でも、交点として表示されてしまうことがあるけど
 * 交点はすべて検出できてる…よね。
 *----------------------------------------
 * ↑uwiさんのforkを元に修正済み。ありがとうございました。
 *----------------------------------------
 * ToDo 線を3D化
 */

package {
    
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.geom.Point;
    
    [SWF(width=400, height=400, frameRate=24, backgroundColor=0)]
    public class FlashTest extends Sprite {
        
            public var dragFlg:Boolean = false;
        public var statusText:TextField;
        public var beginPoint:Point;
        public var lines:Vector.<Line> = new Vector.<Line>;
        public var canvas:Sprite = new Sprite();
        public var crossPoint:Point = new Point();
        
        public function FlashTest() {
                // 状態表示(基本動作には不要)
                statusText = new TextField();
                statusText.text = '';
                statusText.selectable = false;
                addChild(statusText);
                
                // 交点表示用カンバス
                addChild(canvas);
                
                // イベント検知
                stage.addEventListener(MouseEvent.MOUSE_UP,   xStopDrag);
                stage.addEventListener(MouseEvent.MOUSE_MOVE, xDrawLine);
                stage.addEventListener(MouseEvent.MOUSE_DOWN, xStartDrag);
        }
        
        // 描画開始
        public function xStartDrag(e:MouseEvent):void {
                statusText.text = 'start';    // 状態表示
                dragFlg = true;
                graphics.clear();
                graphics.lineStyle(3,0xcccccc);
                var nX:Number = mouseX;
                var nY:Number = mouseY;
                graphics.moveTo(nX, nY);
                // linesを初期化
                lines.splice(0, lines.length);
                // 描画開始点を記録
                beginPoint = new Point(nX, nY);
                // カンバスを消去
                canvas.graphics.clear();
        }
        
        // 描画処理
        // マウスが動いたことを検知し
        // かつマウスが押されている場合(dragFlg==true)だけドラッグと判断する
        public function xDrawLine(e:MouseEvent):void {
                if (dragFlg) {
                    statusText.text = 'drag';    // 状態表示
                    
                    xDrawAndRecord();
                }
        }
        
        // 描画終了
        public function xStopDrag(e:MouseEvent):void {
                statusText.text = 'stop';    // 状態表示
                dragFlg = false;
                xDrawAndRecord();
                var nL:Number = lines.length;
                statusText.text = nL.toString();    //lines;
        }
        
        // ラインを描画し、linesにLineを追加
        public function xDrawAndRecord():void {
                var nX:Number = mouseX;
                var nY:Number = mouseY;
                graphics.lineTo(nX,nY);
                
            // linesにlineを追加
                var line:Line = new Line(beginPoint.x, beginPoint.y, nX, nY); 
                lines.push(line);
                
                // linesとlineの交点を求める
            xCheckCross(line);

                // 描画終了点を記録
                beginPoint = new Point(nX, nY);
        }
        
        // linesとlineの交点を求める
        // 交点が見つかったら、交点を描画する
        public function xCheckCross(currentLine:Line):void {
                var total:Number = lines.length - 3;
                for ( var i:uint = 0; i < total; i++) {
                    var targetLine:Line = lines[i];
                    var cross:Point;
                    if (getCrossPoint(lines[i],currentLine)) {
                        canvas.graphics.lineStyle(2,0xffffff);
                        canvas.graphics.beginFill(0xff0000);
                        canvas.graphics.drawCircle(crossPoint.x, crossPoint.y, 4);
                        canvas.graphics.endFill();
                    }
                }
        }
        
        
        // 2本の直線の交点を計算
        public function getCrossPoint(lineA:Line, lineB:Line):Boolean {
                var flg:Boolean = false;
                // det == 0 は平行
                var det:Number = lineB.f*lineA.g - lineA.f*lineB.g;
                if (det != 0) {
                var dx:Number = lineB.p1.x - lineA.p1.x;
                var dy:Number = lineB.p1.y - lineA.p1.y;
                var t1:Number = (lineB.f*dy - lineB.g*dx)/det;
                var t2:Number = (lineA.f*dy - lineA.g*dx)/det;
                // t1, t2の値が0~1の範囲外の場合、交点は延長線上に存在する
                if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {
                    crossPoint.x = lineA.p1.x + lineA.f*t1;
                    crossPoint.y = lineA.p1.y + lineA.g*t1;
                    flg = true;
                }
                }
                return flg;
        }
    }
}

import flash.geom.Point;
class Line {
    public var p1:Point;
    public var p2:Point;
    public var f:Number;
    public var g:Number;
    public var color:uint;
    public function Line(x1:Number=0, y1:Number=0, x2:Number=0, y2:Number=0, c:uint=0):void {
        p1 = new Point(x1, y1);
        p2 = new Point(x2, y2);
        color = c;
        f = p2.x - p1.x;
        g = p2.y - p1.y;
    }
}