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

Rectangle Intersection with Axis

For final version please visit 
http://blog.yoz.sk/2010/11/4-000-000-rectangle-collisions-per-second/
Get Adobe Flash player
by jozefchutka 16 Nov 2010
    Embed
/**
 * Copyright jozefchutka ( http://wonderfl.net/user/jozefchutka )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/impe
 */

/*
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.6);
            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);
            
            var collision:Boolean = Math2D.isProjectedAxisCollision(
                r1p1.x, r1p1.y, r1p2.x, r1p2.y,
                r2p1.x, r2p1.y, r2p2.x, r2p2.y, 
                r2p3.x, r2p3.y, r2p4.x, r2p4.y);
            shape2.alpha = collision ? 1 : 0.5;
        }
        
        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);
            drawProjectionLine(b1, b2, r2p2);
            drawProjectionLine(b1, b2, r2p3);
            drawProjectionLine(b1, b2, r2p4);
        }
        
        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;
        }
        
        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);
        }
        
        public static function isProjectedUnderBoundaries(
            boundary1X:Number, boundary1Y:Number,
            boundary2X:Number, boundary2Y:Number,
            pointX:Number, pointY:Number):Boolean
        {
            var x:Number = projectX(boundary1X, boundary1Y,
                boundary2X, boundary2Y, pointX, pointY);
            var y:Number = projectY(boundary1X, boundary1Y,
                boundary2X, boundary2Y, pointX, pointY);
            return isUnderBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, x, y);
        }
        
        public static function isProjectedOverBoundaries(
            boundary1X:Number, boundary1Y:Number,
            boundary2X:Number, boundary2Y:Number,
            pointX:Number, pointY:Number):Boolean
        {
            var x:Number = projectX(boundary1X, boundary1Y,
                boundary2X, boundary2Y, pointX, pointY);
            var y:Number = projectY(boundary1X, boundary1Y,
                boundary2X, boundary2Y, pointX, pointY);
            return isOverBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, x, y);
        }
        
        public static function isAxisCollision(
            boundary1X:Number, boundary1Y:Number,
            boundary2X:Number, boundary2Y:Number,
            projected1X:Number, projected1Y:Number,
            projected2X:Number, projected2Y:Number,
            projected3X:Number, projected3Y:Number,
            projected4X:Number, projected4Y:Number):Boolean
        {
            return hasOneUnderBoundaries(boundary1X, boundary1Y,
                    boundary2X, boundary2Y,
                    projected1X, projected1Y,
                    projected2X, projected2Y,
                    projected3X, projected3Y,
                    projected4X, projected4Y) &&
                hasOneOverBoundaries(boundary1X, boundary1Y,
                    boundary2X, boundary2Y,
                    projected1X, projected1Y,
                    projected2X, projected2Y,
                    projected3X, projected3Y,
                    projected4X, projected4Y);
        }
        
        public static function isProjectedAxisCollision(
            boundary1X:Number, boundary1Y:Number,
            boundary2X:Number, boundary2Y:Number,
            point1X:Number, point1Y:Number,
            point2X:Number, point2Y:Number,
            point3X:Number, point3Y:Number,
            point4X:Number, point4Y:Number):Boolean
        {
            return isAxisCollision(boundary1X, boundary1Y, 
                boundary2X, boundary2Y,
                projectX(boundary1X, boundary1Y, boundary2X, boundary2Y, 
                    point1X, point1Y),
                projectY(boundary1X, boundary1Y, boundary2X, boundary2Y, 
                    point1X, point1Y),
                projectX(boundary1X, boundary1Y, boundary2X, boundary2Y, 
                    point2X, point2Y),
                projectY(boundary1X, boundary1Y, boundary2X, boundary2Y, 
                    point2X, point2Y),
                projectX(boundary1X, boundary1Y, boundary2X, boundary2Y, 
                    point3X, point3Y),
                projectY(boundary1X, boundary1Y, boundary2X, boundary2Y, 
                    point3X, point3Y),
                projectX(boundary1X, boundary1Y, boundary2X, boundary2Y, 
                    point4X, point4Y),
                projectY(boundary1X, boundary1Y, boundary2X, boundary2Y, 
                    point4X, point4Y));
        }
        
        public static function hasOneUnderBoundaries(
            boundary1X:Number, boundary1Y:Number,
            boundary2X:Number, boundary2Y:Number,
            projected1X:Number, projected1Y:Number,
            projected2X:Number, projected2Y:Number,
            projected3X:Number, projected3Y:Number,
            projected4X:Number, projected4Y:Number):Boolean
        {
            if(isUnderBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, projected1X, projected1Y))
                return true;
            if(isUnderBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, projected2X, projected2Y))
                return true;
            if(isUnderBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, projected3X, projected3Y))
                return true;
            if(isUnderBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, projected4X, projected4Y))
                return true;
            return false;
        }
        
        public static function hasOneOverBoundaries(
            boundary1X:Number, boundary1Y:Number,
            boundary2X:Number, boundary2Y:Number,
            projected1X:Number, projected1Y:Number,
            projected2X:Number, projected2Y:Number,
            projected3X:Number, projected3Y:Number,
            projected4X:Number, projected4Y:Number):Boolean
        {
            if(isOverBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, projected1X, projected1Y))
                return true;
            if(isOverBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, projected2X, projected2Y))
                return true;
            if(isOverBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, projected3X, projected3Y))
                return true;
            if(isOverBoundaries(boundary1X, boundary1Y, 
                boundary2X, boundary2Y, projected4X, projected4Y))
                return true;
            return false;
        }
    }