Point in Rectangle Collision
fast calculation using FastCollisions.pointInRectangle()
/**
* Copyright jozefchutka ( http://wonderfl.net/user/jozefchutka )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/l597
*/
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;
public class PointCollisionApp extends Sprite
{
private var shape:Shape = new Shape;
public function PointCollisionApp()
{
super();
shape.graphics.beginFill(0x00ff00, .5);
shape.graphics.drawRect(0, 0, 200, 100)
shape.x = 300;
shape.y = 200;
shape.rotation = 30;
addChild(shape);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
shape.rotation++;
var lt:Point = shape.localToGlobal(new Point(0, 0));
var rt:Point = shape.localToGlobal(new Point(200, 0));
var rb:Point = shape.localToGlobal(new Point(200, 100));
var lb:Point = shape.localToGlobal(new Point(0, 100));
var p:Point = new Point(stage.mouseX, stage.mouseY);
var x1:Number = projectX(lt.x, lt.y, rt.x, rt.y, p.x, p.y);
var y1:Number = projectY(lt.x, lt.y, rt.x, rt.y, p.x, p.y);
var u1:Boolean = isUnderBoundaries(lt.x, lt.y, rt.x, rt.y, x1, y1);
var o1:Boolean = isOverBoundaries(lt.x, lt.y, rt.x, rt.y, x1, y1);
var x2:Number = projectX(rt.x, rt.y, rb.x, rb.y, p.x, p.y);
var y2:Number = projectY(rt.x, rt.y, rb.x, rb.y, p.x, p.y);
var u2:Boolean = isUnderBoundaries(rt.x, rt.y, rb.x, rb.y, x2, y2);
var o2:Boolean = isOverBoundaries(rt.x, rt.y, rb.x, rb.y, x2, y2);
graphics.clear();
graphics.beginFill(0xff0000);
graphics.drawCircle(lt.x, lt.y, 3);
graphics.drawCircle(rt.x, rt.y, 3);
graphics.drawCircle(rb.x, rb.y, 3);
graphics.drawCircle(lb.x, lb.y, 3);
graphics.beginFill(0x0);
graphics.drawCircle(x1, y1, 3);
graphics.drawCircle(x2, y2, 3);
var res:Boolean = FastCollisions.pointInRectangle(p.x, p.y, lt.x, lt.y, rt.x, rt.y, rb.x, rb.y, lb.x, lb.y);
var res2:Boolean = u1 && o1 && u2 && o2;
shape.alpha = res2 ? 1 : .5;
trace(res, res2);
if(res != res2)
throw new Error("error");
}
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;
}
public static function calcA(x1:Number, y1:Number, x2:Number, y2:Number)
:Number
{
return (y1 - y2) / (x1 - x2);
}
public static function isUnderBoundaries(
boundary1X:Number, boundary1Y:Number,
boundary2X:Number, boundary2Y:Number,
projectedX:Number, projectedY:Number):Boolean
{
if(boundary1X == boundary2X)
return projectedY <=
(boundary1Y > boundary2Y ? boundary1Y : boundary2Y);
return projectedX <=
(boundary1X > boundary2X ? boundary1X : boundary2X);
}
public static function isOverBoundaries(
boundary1X:Number, boundary1Y:Number,
boundary2X:Number, boundary2Y:Number,
projectedX:Number, projectedY:Number):Boolean
{
if(boundary1X == boundary2X)
return projectedY >=
(boundary1Y < boundary2Y ? boundary1Y : boundary2Y);
return projectedX >=
(boundary1X < boundary2X ? boundary1X : boundary2X);
}
}
}
class FastCollisions
{
public static function pointInRectangle(px:Number, py:Number,
r1x:Number, r1y:Number, r2x:Number, r2y:Number,
r3x:Number, r3y:Number, r4x:Number, r4y:Number):Boolean
{
var a:Number, x:Number, y:Number;
if(r1x == r2x)
{
x = r1x, y = py;
if(y > (r1y > r2y ? r1y : r2y)) return false;
if(y < (r1y < r2y ? r1y : r2y)) return false;
}
else if(r1y == r2y)
{
x = px, y = r1y;
}
else
{
a = (r1y - r2y) / (r1x - r2x);
x = (py - r2y + r2x * a + px / a) / (a + 1 / a);
y = py + (px - x) / a;
}
if(x > (r1x > r2x ? r1x : r2x)) return false;
if(x < (r1x < r2x ? r1x : r2x)) return false;
if(r2x == r3x)
{
x = r2x, y = py;
if(y > (r2y > r3y ? r2y : r3y)) return false;
if(y < (r2y < r3y ? r2y : r3y)) return false;
}
else if(r2y == r3y)
{
x = px, y = r2y;
}
else
{
a = (r2y - r3y) / (r2x - r3x);
x = (py - r3y + r3x * a + px / a) / (a + 1 / a);
y = py + (px - x) / a;
}
if(x > (r2x > r3x ? r2x : r3x)) return false;
if(x < (r2x < r3x ? r2x : r3x)) return false;
return true;
}
}