blog

RayMath class at Jozef Chúťka's blog

December 16, 2009

No comments

DisplayObject Graphics hitTestPoint RayMath

RayMath class

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>

You may Leave a comment or Subscribe to Comments RSS or Trackback this entry.

Leave a comment

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