forked from: 誰かが悩んでた問題
/**
* Copyright nutsu ( http://wonderfl.net/user/nutsu )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/icT0
*/
// forked from keno42's 誰かが悩んでた問題
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.utils.getTimer;
public class FlashTest extends Sprite {
// ドラッグ移動できる点の宣言
private var mpX0:MovablePoint = new MovablePoint(3, 0xFFFF0000, true);
private var mpX1:MovablePoint = new MovablePoint(3, 0xFFFF0000, true);
private var mpA:MovablePoint = new MovablePoint(3, 0xFFFF0000, true);
private var mpV0:MovablePoint = new MovablePoint(3, 0xFF00FF00, true);
private var mpV1:MovablePoint = new MovablePoint(3, 0xFF00FF00, true);
private var mpB:MovablePoint = new MovablePoint(3, 0xFF00FF00, true);
private var result:MovablePoint = new MovablePoint(3, 0xFF0000FF, false);
// コンストラクタ
public function FlashTest() {
// write as3 code here..
// 適当に初期条件
mpX0.x = 120;
mpX0.y = 180;
addChild(mpX0);
mpV0.x = 90;
mpV0.y = 210;
addChild(mpV0);
mpX1.x = 200;
mpX1.y = 280;
addChild(mpX1);
mpV1.x = 400;
mpV1.y = 250;
addChild(mpV1);
mpA.x = 50;
mpA.y = 300;
addChild(mpA);
mpB.x = 55;
mpB.y = 295;
addChild(mpB);
addChild(result);
// 画面描画
_refresh();
this.addEventListener(Event.ENTER_FRAME, _onEnter);
}
// 毎フレーム画面描画
private function _onEnter(e:Event):void{
_refresh();
}
// 画面描画メソッド
private function _refresh():void{
this.graphics.clear();
this.graphics.lineStyle(0, 0x0);
var t:Number = (getTimer() % 1000) / 1000;
var X0x:Number = (mpV0.x - mpX0.x) * t + mpX0.x;
var X0y:Number = (mpV0.y - mpX0.y) * t + mpX0.y;
var X1x:Number = (mpV1.x - mpX1.x) * t + mpX1.x;
var X1y:Number = (mpV1.y - mpX1.y) * t + mpX1.y;
var Bx:Number = mpB.x - mpA.x;
var By:Number = mpB.y - mpA.y;
var s:Number = (By * (X0x - mpA.x) - Bx * (X0y - mpA.y) ) / (-By * (X1x-X0x) + Bx * (X1y-X0y) );
// 線分描画
this.graphics.moveTo(X0x, X0y);
this.graphics.lineTo(X1x, X1y);
this.graphics.lineStyle(0, 0x0000FF);
_drawLine(new Point(mpA.x, mpA.y), new Point(mpB.x, mpB.y), false);
this.graphics.moveTo(mpX0.x, mpX0.y);
this.graphics.lineTo(mpV0.x, mpV0.y);
this.graphics.moveTo(mpX1.x, mpX1.y);
this.graphics.lineTo(mpV1.x, mpV1.y);
// 結果の表示位置を更新(本当はsが0-1の範囲になかったら線分とまじわらない)
cal( t, mpB.y - mpA.y, mpA.x - mpB.x, (mpB.x - mpA.x) * mpA.y - (mpB.y - mpA.y) * mpA.x,
mpV0.x - mpX0.x, mpV0.y - mpX0.y, mpX0.x, mpX0.y,
mpV1.x - mpX1.x, mpV1.y - mpX1.y, mpX1.x, mpX1.y );
//result.x = X0x + (X1x - X0x) * s;
//result.y = X0y + (X1y - X0y) * s;
}
private function cal( t:Number, a:Number, b:Number, c:Number, x1:Number, y1:Number, tx1:Number, ty1:Number, x2:Number, y2:Number, tx2:Number, ty2:Number ):void
{
//tの関数 (x1*t + tx1, y1*t + ty1 ), (x2*t + tx2, y2*t + ty2 ) と
//ax + by + c = 0 との交点
//全然整理しとらんです
result.x = ((b*t*t*x1+b*t*tx1)*y2+(-b*t*t*x2-b*t*tx2)*y1+(-b*t*ty1-c*t)*x2+(b*t*ty2+c*t)*x1+b*tx1*ty2-b*tx2*ty1-c*tx2+c*tx1)/(b*t*y2-b*t*y1+a*t*x2-a*t*x1+b*ty2-b*ty1+a*tx2-a*tx1);
result.y = -((a*t*t*x1+a*t*tx1+c*t)*y2+(-a*t*t*x2-a*t*tx2-c*t)*y1-a*t*ty1*x2+a*t*ty2*x1+(a*tx1+c)*ty2+(-a*tx2-c)*ty1)/(b*t*y2-b*t*y1+a*t*x2-a*t*x1+b*ty2-b*ty1+a*tx2-a*tx1);
}
private function _drawLine(a:Point, b:Point, isSenbun:Boolean):void{
// もろもろ計算用のPoint ぴったり重なったときのゼロ除算を避けるためにちょっとだけ加算
var tempPoint:Point = new Point(b.x + 0.0001,b.y + 0.0001);
tempPoint = tempPoint.subtract(a);
tempPoint.normalize(700); // ABの長さを700に伸ばしたベクトル
// 直線描画
this.graphics.moveTo(a.x+tempPoint.x, a.y+tempPoint.y);
this.graphics.lineTo(a.x-(isSenbun?0:tempPoint.x), a.y-(isSenbun?0:tempPoint.y));
}
}
}
import flash.display.*;
import flash.events.*;
// ドラッグで移動する点
class MovablePoint extends Sprite{
public function MovablePoint(radius:Number, color:uint, isMovable:Boolean){
this.graphics.lineStyle(1, color);
this.graphics.beginFill(color & 0xFFFFFF, 0.75);
this.graphics.drawCircle(0, 0, radius);
if( isMovable ){
this.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
this.buttonMode = true;
}
}
private function onDown(e:MouseEvent):void{
this.startDrag();
this.dispatchEvent(new Event("startRefresh"));
this.addEventListener(MouseEvent.MOUSE_UP, onUp);
this.stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
private function onUp(e:MouseEvent):void{
this.stopDrag();
this.dispatchEvent(new Event("stopRefresh"));
this.removeEventListener(MouseEvent.MOUSE_UP, onUp);
this.stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
}
}