4点からなる交点の求め方

以前二つの線の交点を求めたことがありました。
そのときは、2つの線をy=ax+bにして連立二次方程式を解いていきました。
ところが、それだと二線が平行だったときや傾きが無かったときの条件分岐がぐちゃらぐちゃらして、どうもすっきりしないなぁっと思っていました。

   
   
4点からなる交点の求め方
http://imagingsolution.blog107.fc2.com/blog-entry-137.html
   
先日、上記のサイトをたまたま発見しました。
簡単に言えば、直線を面積比で割るという方法です。
なるほど。
実際に組んでみると、かなりスッキリした表現です。
   

  
[sourcecode language=”as3″]
package {
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
public class FlashTest extends Sprite {
private var dragpoint:Sprite;
private var redpoint:Sprite;
private var P1:Sprite;
private var P2:Sprite;
private var P3:Sprite;
private var P4:Sprite;
public function FlashTest() {
// write as3 code here..
redpoint=new Sprite();
addChild(redpoint);
var g:Graphics=redpoint.graphics;
g.beginFill(0xFF0000);
g.drawCircle(0,0,5);
g.endFill();
//
P1=setPoints(0);
P2=setPoints(1);
P3=setPoints(2);
P4=setPoints(3);
setLine();
//
clossPoint();
//
addEventListener(Event.ENTER_FRAME,ent);
}
private function clossPoint():void{
//ここがすごい!
var S1:Number=((P4.x-P2.x)*(P1.y-P2.y)-(P4.y-P2.y)*(P1.x-P2.x))*0.5;
var S2:Number=((P4.x-P2.x)*(P2.y-P3.y)-(P4.y-P2.y)*(P2.x-P3.x))*0.5;
redpoint.x=P1.x + (P3.x-P1.x)*(S1/(S1 + S2));
redpoint.y=P1.y + (P3.y-P1.y)*(S1/(S1 + S2));
}
private function ent(evt:Event):void{
setLine();
clossPoint();
}
private function setLine():void{
var g:Graphics=this.graphics;
g.clear();

g.lineStyle(2,0xCCCCCC);
g.moveTo(P1.x,P1.y);
g.lineTo(P3.x,P3.y);
g.moveTo(P2.x,P2.y);
g.lineTo(P4.x,P4.y);
}
private function setPoints(n:uint):Sprite{
var sp:Sprite=new Sprite();
var g:Graphics=sp.graphics;
g.beginFill(0xCCCCCC);
g.drawCircle(0,0,5);
g.endFill();
addChild(sp);
//
sp.buttonMode=true;
sp.addEventListener(MouseEvent.MOUSE_DOWN,pointPress);
//
var theta:Number=-1*Math.PI+0.5*Math.PI*n+Math.random()*0.5*Math.PI;
sp.x=0.5*stage.stageWidth+(100+100*Math.random())*Math.cos(theta);
sp.y=0.5*stage.stageHeight+(100+100*Math.random())*Math.sin(theta);
return sp;
}
private function pointPress(evt:Event):void{
dragpoint=evt.currentTarget as Sprite;
dragpoint.startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP,pointRelease);
}
private function pointRelease(evt:Event):void{
dragpoint.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP,pointRelease);
}
}
}
[/sourcecode]
   
   
外積など受験勉強したとき涙目になっていました。
ノートの上だと本当にうまくいくのかなぁっと不安に思っていました。
リアルタイムに見られて感無量です。
役に立つとわかったら、もう少しまじめに受験勉強したのかな。してないな。