In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Point in Rectangle Collision

fast calculation using FastCollisions.pointInRectangle()
Get Adobe Flash player
by jozefchutka 09 Mar 2012
/**
 * 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;
        }
    }