forked from: ドラッグして描いた線の交差判定
マウスで引いた線を描画する基本
* マウスを押して動かしている間線を描いて
* マウスを離したら終了
*----------------------------------------
* 交点を検出して表示します。
* 交点でない場所でも、交点として表示されてしまうことがあるけど
* 交点はすべて検出できてる…よね。
*----------------------------------------
* ToDo 線を3D化
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/bp2X
*/
// forked from Kay's ドラッグして描いた線の交差判定
// forked from Kay's Basic お絵かき
/*
* マウスで引いた線を描画する基本
* マウスを押して動かしている間線を描いて
* マウスを離したら終了
*----------------------------------------
* 交点を検出して表示します。
* 交点でない場所でも、交点として表示されてしまうことがあるけど
* 交点はすべて検出できてる…よね。
*----------------------------------------
* 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;
// detが小さいときは無視してもいいんじゃないかなと
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;
}
}