raymarching minimum distance - part 0

by arithma
...
@author arithma
♥0 | Line 85 | Modified 2012-04-04 16:39:58 | MIT License
play

ActionScript3 source code

/**
 * Copyright arithma ( http://wonderfl.net/user/arithma )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/m7em
 */

package {
    import flash.geom.Rectangle;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.utils.getTimer;
    
    /**
     * ...
     * @author arithma
     */
    public class Renderer extends Sprite {
        
        private var bmp:BitmapData;
        private var angle:Number = 0;
        private var Z:Number = 0;
        
        public function Renderer() {
            //draw();
            bmp = new BitmapData(stage.stageWidth / 2, stage.stageHeight / 2);
            var holder:Bitmap = new Bitmap(bmp);
            holder.width = stage.stageWidth;
            holder.height = stage.stageHeight;
            addChild(holder);
            addEventListener(Event.ENTER_FRAME, frame);
        }
        
        public function frame(e:Event):void {
            angle = Math.PI/8 * Math.sin(getTimer()/1000);
            Z = 1 + .3 * Math.sin(getTimer()/523);
            draw();
        }
        
        public function draw():void {
            var aspect:Number = bmp.height / bmp.width;
            bmp.fillRect(new Rectangle(bmp.width, bmp.height), 0x0);
            bmp.lock();
            for (var i:int = 0; i < stage.stageWidth; i++) {
                for (var j:int = 0; j < stage.stageHeight; j++) {
                    var ray:number3 = new number3();
                    ray.z = Z;
                    ray.x = i / bmp.width * 2 - 1;
                    ray.y = (j / bmp.height * 2 - 1) * aspect;
                    
                    //var rz:Number = ray.z * Math.cos(angle) + ray.y * Math.sin(angle);
                    //var ry:Number = ray.z * Math.sin(angle) - ray.y * Math.cos(angle);
                    
                    //ray.y = ry
                    //ray.z = rz;
                    
                    var pt:number3 = ray.clone();
                    pt.z = 0;
                    
                    var norm:Number = Math.sqrt(ray.x * ray.x + ray.y * ray.y + ray.z * ray.z);
                    ray.x /= norm;
                    ray.y /= norm;
                    ray.z /= norm;
                    
                    var d:Number = 10000;
                    var t:Number;
                    
                    var color:uint = 0;
                    
                    while (d > .01 && (t = distance(pt)) < d) {
                        d = t;
                        var increment:number3 = ray.clone();
                        increment.scale(t);
                        pt.add(increment);
                        color++;
                    }
                    
                    if (t > d)
                        continue;
                    
                    var dist:Number = Math.sqrt(pt.x * pt.x + pt.y * pt.y + pt.z * pt.z);
                        
                    //if (d < 1000) {
                        bmp.setPixel(i, j, 1/dist*1000);
                    //}
                }
            }
            bmp.unlock();
        }
        
        private function distance(pt:number3):Number {
            return Math.abs(Math.sin(pt.x) + Math.sin(pt.y));
        }
    }
}

class number3 {
    public var x:Number;
    public var y:Number;
    public var z:Number;
    
    public function add(n:number3):void {
        x += n.x;
        y += n.y;
        z += n.z;
    }
    
    public function scale(n:Number):void {
        x *= n;
        y *= n;
        z *= n;
    }
    
    public function clone():number3 {
        var result:number3 = new number3();
        result.x = x;
        result.y = y;
        result.z = z;
        
        return result;
    }
}