In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

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

マウスで引いた線を描画する基本
* マウスを押して動かしている間線を描いて
* マウスを離したら終了
*----------------------------------------
* 交点を検出して表示します。
* 交点でない場所でも、交点として表示されてしまうことがあるけど
* 交点はすべて検出できてる…よね。
*----------------------------------------
* ↑uwiさんのforkを元に修正済み。ありがとうございました。
*----------------------------------------
* ToDo 線を3D化
Get Adobe Flash player
by Kay 05 Mar 2010
/**
 * Copyright Kay ( http://wonderfl.net/user/Kay )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1NKA
 */

// 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;
	}
}