RayMath class

raymath

While working on newest project I created a simple util class that simulates rays of spot light. It uses DisplayObject hitTestPoint() method to test for ray stream collisions so it does not go beyond the obstacles (corners etc.). Feel free to use RayMath class as you wish

RayMath application

RayMath class

package sk.yoz.math
{
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.geom.Point;
    
    public class RayMath extends Object
    {
        public function RayMath()
        {
            super();
        }
        
        public static function getRayPoints(lamp:DisplayObject, 
            boundary:DisplayObject, rayCount:uint = 50, rayRange:uint = 50)
            :Array
        {
            var lp:Point, gp:Point, fp:Point;
            var points:Array = [];
            var angle:Number;
            for(var i:uint = 0; i < rayCount; i++)
            {
                fp = null;
                for(var j:uint = 0; j < rayRange; j++)
                {
                    angle = Math.PI / rayCount * i * 2;
                    lp = new Point(Math.cos(angle) * j, Math.sin(angle) * j);
                    gp = lamp.localToGlobal(lp);
                    if(!boundary.hitTestPoint(gp.x, gp.y, true))
                        break;
                    fp = lp;
                }
                if(fp)
                    points.push(fp);
            }
            return points;
        }
        
        public static function boundaryDistance(points:Array):Number
        {
            var shortest:Number = Number.MAX_VALUE;
            var zeroPoint:Point = new Point(0, 0);
            var distance:Number;
            for each(var point:Point in points)
            {
                distance = Point.distance(point, zeroPoint);
                if(distance < shortest)
                    shortest = distance;
            }
            return shortest;
        }
        
        public static function drawRays(lamp:Sprite, points:Array):void
        {
            if(!points.length)
                return;
            lamp.graphics.moveTo(points[0].x, points[0].y);
            for each(var point:Point in points)
                lamp.graphics.lineTo(point.x, point.y);
            lamp.graphics.lineTo(points[0].x, points[0].y);
        }
    }
}

Demo application

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" 
    applicationComplete="init()" width="500" height="500" 
    backgroundGradientAlphas="1,1" backgroundColor="0xffffff">
<mx:Script>
<![CDATA[
    import sk.yoz.math.RayMath;
    
    private function init():void
    {
        var bg:Graphics = boundary.graphics;
        bg.beginFill(0x000000, 1);
        
        bg.moveTo(50, 50);
        bg.lineTo(width - 50, 130);
        bg.lineTo(width - 150, height - 50);
        bg.lineTo(100, height - 100);
        bg.lineTo(50, 50);
        
        bg.moveTo(100, 200);
        bg.lineTo(300, 200);
        bg.lineTo(250, 300);
        bg.lineTo(100, 200);
        
        bg.moveTo(300, 250);
        bg.lineTo(350, 250);
        bg.lineTo(350, 300);
        bg.lineTo(300, 250);
        
        lamp.startDrag(true);
        addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
    }
    
    private function mouseMoveHandler(event:MouseEvent):void
    {
        var lg:Graphics = lamp.graphics;
        lg.clear();
        lg.beginFill(0xffff00, 0.5);
        lg.lineStyle(1, 0xffff00, 0.8);
        var points:Array = RayMath.getRayPoints(lamp, boundary, 80, 100);
        RayMath.drawRays(lamp, points);
        
        lg.endFill();
        for each(var point:Point in points)
        {
            lg.moveTo(0, 0);
            lg.lineTo(point.x, point.y);
        }
    }
]]>
</mx:Script>
<mx:UIComponent id="boundary" />
<mx:UIComponent id="lamp" />
</mx:Application>

Leave a comment

Please be polite and on topic. Your e-mail will never be published.