Projecting Point to Axis
For final version please visit
http://blog.yoz.sk/2010/11/4-000-000-rectangle-collisions-per-second/
/**
* Copyright jozefchutka ( http://wonderfl.net/user/jozefchutka )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ap5F
*/
/*
For final version please visit
http://blog.yoz.sk/2010/11/4-000-000-rectangle-collisions-per-second/
*/
package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.text.TextField;
[SWF(width="465", height="465", frameRate="30", backgroundColor="#FFFFFF")]
public class WonderflApp extends Sprite
{
private var shape1:Shape = new Shape();
private var rect1:Point = new Point(0, 0);
private var rect1Width:uint = 100;
private var rect1Height:uint = 50;
private var r1p1:Point;
private var r1p2:Point;
private var r1p3:Point;
private var r1p4:Point;
private var shape2:Shape = new Shape();
private var rect2:Point = new Point(0, 0);
private var rect2Width:uint = 80;
private var rect2Height:uint = 60;
private var r2p1:Point;
private var r2p2:Point;
private var r2p3:Point;
private var r2p4:Point;
public function WonderflApp():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
shape1.graphics.beginFill(0, 0);
shape1.graphics.drawRect(rect1.x, rect1.y, rect1Width, rect1Height);
shape1.x = 200;
shape1.y = 100;
shape1.rotation = 40;
addChild(shape1);
shape2.graphics.beginFill(0, 0);
shape2.graphics.drawRect(rect2.x, rect2.y, rect2Width, rect2Height);
shape2.rotation = 30;
addChild(shape2);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
graphics.clear();
// rectangle 1
shape1.rotation++;
r1p1 = shape1.localToGlobal(rect1);
r1p2 = shape1.localToGlobal(new Point(rect1.x + rect1Width, rect1.y));
r1p3 = shape1.localToGlobal(new Point(rect1.x + rect1Width, rect1.y + rect1Height));
r1p4 = shape1.localToGlobal(new Point(rect1.x, rect1.y + rect1Height));
// rectangle 2
shape2.x = mouseX;
shape2.y = mouseY;
r2p1 = shape2.localToGlobal(rect1);
r2p2 = shape2.localToGlobal(new Point(rect2.x + rect2Width, rect2.y));
r2p3 = shape2.localToGlobal(new Point(rect2.x + rect2Width, rect2.y + rect2Height));
r2p4 = shape2.localToGlobal(new Point(rect2.x, rect2.y + rect2Height));
// projections
drawProjections(0xff0000, r1p1, r1p2, r2p1, r2p2, r2p3, r2p4);
}
private function drawProjections(color:uint,
r1p1:Point, r1p2:Point,
r2p1:Point, r2p2:Point,
r2p3:Point, r2p4:Point):void
{
var b1:Point = new Point(r1p1.x, r1p1.y);
var b2:Point = new Point(r1p2.x, r1p2.y);
graphics.lineStyle(2, color);
graphics.moveTo(b1.x, b1.y);
graphics.lineTo(b2.x, b2.y);
graphics.lineStyle(0, color, 0.3);
drawProjectionLine(b1, b2, r2p1);
}
private function drawProjectionLine(b1:Point, b2:Point, p:Point):void
{
graphics.moveTo(p.x, p.y);
graphics.lineTo(
Math2D.projectX(b1.x, b1.y, b2.x, b2.y, p.x, p.y),
Math2D.projectY(b1.x, b1.y, b2.x, b2.y, p.x, p.y));
}
}
}
class Math2D
{
public function Math2D()
{
}
public static function calcA(x1:Number, y1:Number, x2:Number, y2:Number)
:Number
{
return (y1 - y2) / (x1 - x2);
}
public static function projectX(
boundary1X:Number, boundary1Y:Number,
boundary2X:Number, boundary2Y:Number,
pointX:Number, pointY:Number):Number
{
if(boundary1X == boundary2X)
return boundary1X;
if(boundary1Y == boundary2Y)
return pointX;
var a:Number = calcA(boundary1X, boundary1Y, boundary2X, boundary2Y);
return (pointY - boundary2Y + boundary2X * a + pointX / a) /
(a + 1 / a);
}
public static function projectY(
boundary1X:Number, boundary1Y:Number,
boundary2X:Number, boundary2Y:Number,
pointX:Number, pointY:Number):Number
{
if(boundary1X == boundary2X)
return pointY;
if(boundary1Y == boundary2Y)
return boundary1Y;
var a:Number = calcA(boundary1X, boundary1Y, boundary2X, boundary2Y);
var x:Number = projectX(boundary1X, boundary1Y,
boundary2X, boundary2Y, pointX, pointY)
return pointY + (pointX - x) / a;
}
}