/**
* Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/b27F
*/
package {
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
//note: triangle winding is important for this test
myTri = new xTri();
myTri.x0 = 110;
myTri.y0 = 60;
myTri.x1 = 280;
myTri.y1 = 280;
myTri.x2 = 90;
myTri.y2 = 290;
stage.addEventListener(Event.ENTER_FRAME, onEnter);
}//ctor
public var myTri:xTri;
public var temp:xPnt = new xPnt();
public function onEnter(e:Event):void
{
graphics.clear();
graphics.lineStyle(2, 0);
var a:xTri;
a = myTri;
graphics.moveTo(a.x0, a.y0);
graphics.lineTo(a.x1, a.y1);
graphics.lineTo(a.x2, a.y2);
graphics.lineTo(a.x0, a.y0);
var mx:Number;
var my:Number;
mx = stage.mouseX;
my = stage.mouseY;
a.getDist(mx, my, temp);
graphics.moveTo(temp.px, temp.py);
graphics.lineTo(mx, my);
graphics.drawRect(temp.px-4,temp.py-4,8,8);
graphics.drawCircle(mx,my,8);
}//onenter
}//classend
}
import flash.display.Graphics;
internal class xPnt
{
public var px:Number = 0;
public var py:Number = 0;
}//xpnt
internal class xTri
{
public var x0:Number = 0;
public var y0:Number = 0;
public var x1:Number = 0;
public var y1:Number = 0;
public var x2:Number = 0;
public var y2:Number = 0;
//returns squared distance to triangle
public function getDist(wx:Number, wy:Number, ret:xPnt):Number
{
var ax0:Number; var ay0:Number;
var bx0:Number; var by0:Number;
var ax1:Number; var ay1:Number;
var bx1:Number; var by1:Number;
var ax2:Number; var ay2:Number;
var bx2:Number; var by2:Number;
var dz0:Number; var dz1:Number; var dz2:Number;
var rx:Number; var ry:Number; var rz:Number;
var wd:Number;
var d:Number;
// ok so the triangle has multiple zones
// based on if we are closest to an edge, vertex or inside the triangle
// (also if we are right on a vertex or edge)
// by figuring out which side on each 3 sides of the triangle our point is
// we can figure out which zone the point is in
// e.g. if we are front of all 3 edges we are inside
// if we are only front of one of them then we are closest to a vertex
// if we are are front of two then we are closest to one of the edges
// also because we us this the winding is important
// if we are right on an edge or vertex then we got a special case
// here its handled by assuming that a point on the edge is front of it
// aka a point on a vertex is considered inside the triangle
ax0 = x1 - x0;
ay0 = y1 - y0;
bx0 = wx - x0;
by0 = wy - y0;
dz0 = (ax0 * by0) - (ay0 * bx0);
ax1 = x2 - x1;
ay1 = y2 - y1;
bx1 = wx - x1;
by1 = wy - y1;
dz1 = (ax1 * by1) - (ay1 * bx1);
ax2 = x0 - x2;
ay2 = y0 - y2;
bx2 = wx - x2;
by2 = wy - y2;
dz2 = (ax2 * by2) - (ay2 * bx2);
//+++ //inside
if (dz0 >= 0 && dz1 >= 0 && dz2 >=0)
{
d = 0;
if (ret) { ret.px = wx; ret.py = wy; }
}
else //-+- //vertex
if (dz0 < 0 && dz1 >= 0 && dz2 < 0)
{
d = bx0*bx0 + by0*by0;
if (ret) { ret.px = x0; ret.py = y0; }
}
else //--+ //vertex
if (dz0 < 0 && dz1 < 0 && dz2 >= 0)
{
d = bx1*bx1 + by1*by1;
if (ret) { ret.px = x1; ret.py = y1; }
}
else //+-- //vertex
if (dz0 >= 0 && dz1 < 0 && dz2 < 0)
{
d = bx2*bx2 + by2*by2;
if (ret) { ret.px = x2; ret.py = y2; }
}
else //-++ //edge
if (dz0 < 0 && dz1 >= 0 && dz2 >= 0)
{
wd = ((ax0 * bx0) + (ay0 * by0) ) / ((ax0 * ax0) + (ay0 * ay0));
if (wd < 0) { wd = 0;} if (wd > 1) { wd = 1; }
rx = x0 + (x1 - x0) * wd;
ry = y0 + (y1 - y0) * wd;
if (ret) { ret.px = rx; ret.py = ry; }
rx = wx-rx; ry = wy-ry;
d = rx*rx + ry*ry;
}
else //+-+ //edge
if (dz0 >= 0 && dz1 < 0 && dz2 >= 0)
{
wd = ((ax1 * bx1) + (ay1 * by1) ) / ((ax1 * ax1) + (ay1 * ay1));
if (wd < 0) { wd = 0;} if (wd > 1) { wd = 1; }
rx = x1 + (x2 - x1) * wd;
ry = y1 + (y2 - y1) * wd;
if (ret) { ret.px = rx; ret.py = ry; }
rx = wx-rx; ry = wy-ry;
d = rx*rx + ry*ry;
}
else //++- //edge
if (dz0 >= 0 && dz1 >= 0 && dz2 < 0)
{
wd = ((ax2 * bx2) + (ay2 * by2) ) / ((ax2 * ax2) + (ay2 * ay2));
if (wd < 0) { wd = 0;} if (wd > 1) { wd = 1; }
rx = x2 + (x0 - x2) * wd;
ry = y2 + (y0 - y2) * wd;
if (ret) { ret.px = rx; ret.py = ry; }
rx = wx-rx; ry = wy-ry;
d = rx*rx + ry*ry;
}//endif
return d;
}//isinside
}//xtris