/**
* Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/q0Ud
*/
package {
import flash.text.TextField;
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
deb = new TextField();
deb.mouseEnabled = false;
deb.width = 320;
deb.height = 240;
addChild(deb);
line1 = new xLine(50, 90, 90, 300);
line2 = new xLine(300, 200, 50, 200);
stage.addEventListener(Event.ENTER_FRAME, onEnter);
}//ctor
public var deb:TextField;
public var line1:xLine;
public var line2:xLine;
public function onEnter(e:Event):void
{
graphics.clear();
graphics.lineStyle(2, 0);
line2.x1 = stage.mouseX;
line2.y1 = stage.mouseY;
graphics.moveTo(line1.x0, line1.y0);
graphics.lineTo(line1.x1, line1.y1);
graphics.moveTo(line2.x0, line2.y0);
graphics.lineTo(line2.x1, line2.y1);
var dist0:Number;
var dist1:Number;
var dist2:Number;
var t:Number;
var t2:Number;
var u:Number;
var kx:Number;
var ky:Number;
var kx2:Number;
var ky2:Number;
var dx:Number;
var dy:Number;
var nx:Number;
var ny:Number;
var mag:Number;
dx = line1.x0 - line1.x1;
dy = line1.y0 - line1.y1;
mag = getDist(dx, dy);
if (mag == 0) { mag = 0.00000001;}
nx = -(dy/mag);
ny = dx/mag;
t = getInter(line1, line2);
// t = lineLineInter(line1.x0, line1.y0, line1.x1, line1.y1, line2.x0, line2.y0, line2.x1, line2.y1);
kx = line1.x0 + (line1.x1 - line1.x0) * t;
ky = line1.y0 + (line1.y1 - line1.y0) * t;
graphics.drawCircle(kx, ky, 12);
if (t == 999)
{
t = getClosePoint(line2.x1, line2.y1, line1);
kx = line1.x0 + (line1.x1 - line1.x0) * t;
ky = line1.y0 + (line1.y1 - line1.y0) * t;
dist0 = getDist(line2.x1 - kx, line2.y1 - ky);
graphics.drawCircle(kx, ky, 8);
t2 = getClosePoint(line2.x0, line2.y0, line1);
kx2 = line1.x0 + (line1.x1 - line1.x0) * t;
ky2 = line1.y0 + (line1.y1 - line1.y0) * t;
dist1 = getDist(line2.x0 - kx, line2.y0 - ky);
graphics.drawCircle(kx, ky, 6);
//todo -- optimisation -- use squared distance for this
if (dist1 < dist0)
{
kx = kx2;
ky = ky2;
}
u =linePlaneInter(line2, line1.x0, line1.y0, nx, ny);
kx2 = line2.x0 + (line2.x1 - line2.x0) * u;
ky2 = line2.y0 + (line2.y1 - line2.y0) * u;
graphics.drawCircle(kx2, ky2, 8);
deb.text = "no inter \n dist "
+ dist0 + "\n dist1 " + dist1+ "\n u " + u;
}
else { deb.text = " inter " + t;}
graphics.drawCircle(kx, ky, 16);
}//onenter
public function getDist(dx:Number, dy:Number):Number
{
return Math.sqrt(dx*dx + dy*dy);
}
public function getClosePoint(px:Number, py:Number, w:xLine):Number
{
var t:Number;
var jx:Number; var jy:Number;
var hx:Number; var hy:Number;
var ab:Number; var ak:Number;
jx = px - w.x0;
jy = py - w.y0;
hx = w.x1 - w.x0;
hy = w.y1 - w.y0;
ab = hx*hx + hy*hy;
ak = jx*hx + jy*hy;
t = ak / ab;
if (t < 0) { t = 0;}
if (t > 1) { t = 1;}
return t;
}//getclose
/*
public function lineLineInter(
v0x:Number, v0y:Number,
v1x:Number, v1y:Number,
v2x:Number, v2y:Number,
v3x:Number, v3y:Number ):Number
{
var ua:Number;
var ub:Number;
var bot:Number;
bot = ((v3y-v2y)*(v1x-v0x))-((v3x-v2x)*(v1y-v0y));
if (bot == 0) { return 999;}
ua = (((v3x-v2x)*(v0y-v2y))-((v3y-v2y)*(v0x-v2x))) / bot;
ub = (((v1x-v0x)*(v0y-v2y))-((v1y-v0y)*(v0x-v2x))) / bot;
if (ua > 1 || ua < 0 || ub > 1 || ub < 0) { return 999; }
return ua;
}//lineline
*/
public function getInter(ma:xLine, mb:xLine):Number
{
var ua:Number;
var ub:Number;
var bot:Number;
bot = ((mb.y1-mb.y0)*(ma.x1-ma.x0))-((mb.x1-mb.x0)*(ma.y1-ma.y0));
if (bot == 0) { return 999;}
ua = (((mb.x1-mb.x0)*(ma.y0-mb.y0))-((mb.y1-mb.y0)*(ma.x0-mb.x0))) / bot;
ub = (((ma.x1-ma.x0)*(ma.y0-mb.y0))-((ma.y1-ma.y0)*(ma.x0-mb.x0))) / bot;
if (ua > 1 || ua < 0 || ub > 1 || ub < 0) { return 999; }
return ua;
}//getinter
public static function linePlaneInter(v:xLine,
px:Number, py:Number, nx:Number, ny:Number):Number
{
var dx:Number; var dy:Number; var dz:Number;
var vx:Number; var vy:Number; var vz:Number;
var ndotv:Number;
vx = v.x1 - v.x0;
vy = v.y1 - v.y0;
dx = px - v.x0;
dy = py - v.y0;
ndotv = (vx * nx) + (vy * ny);
if (ndotv == 0) { return -99999; }
return ( ( ( nx * dx) + (ny * dy)) / ndotv );
}//lineplane
}//classend
}
internal class xLine
{
public var x0:Number = 0;
public var y0:Number = 0;
public var x1:Number = 0;
public var y1:Number = 0;
public function xLine(ax:Number=0, ay:Number=0, bx:Number=0, by:Number=0):void
{
x0 = ax;
y0 = ay;
x1 = bx;
y1 = by;
}//xline
}//xline