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

Kaleidoscope -- How can I get rid of the subpixel gap with tiled symmetry?

How can I refactor KaleidoImage's render() (line 63) to
1. be more efficient
2. get rid of the subpixel gap

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

// How can I refactor KaleidoImage's render() (line 63) to
//   1. be more efficient
//   2. get rid of the subpixel gap


package {
    import flash.display.Sprite;
    import flash.events.Event;
    
    public class Kaleidoscope extends Sprite {
        
            private var c:CameraBitmap;
            private var k:KaleidoImage;
            private var w:int = 160;
            
        public function Kaleidoscope() {
                c = new CameraBitmap(w,w*8/7);
                c.addEventListener(Event.RENDER, render);
                
                k = new KaleidoImage(465,465,w);
            addChild(k);
        }
        
        private function render(e:Event):void {
                k.render(c.bitmapData);
        }
    }
}





    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.geom.Matrix;

    class KaleidoImage extends Bitmap
    {
        private var _matrices:Vector.<Matrix> = new Vector.<Matrix>;
        private var _triangleWidth:int;
        private var _triangleHeight:int;
        
        public function KaleidoImage(width:int, height:int, triangleWidth:int)
        {
            _triangleWidth = triangleWidth;
            _triangleHeight = _triangleWidth*7/8;
            super(new BitmapData(width,height,false,0x000000));
            init();
        }
        
        private function init():void {
            // Translation matrices
            _matrices[0] = new Matrix();
            _matrices[0].translate(-_triangleWidth/2,0);
            for(var i:int=1; i<6; i++){
                _matrices[i] = _matrices[0].clone();
                if (i%2) _matrices[i].scale(-1,1); // mirror every other
                _matrices[i].rotate(2 * Math.PI * (-60*i / 360));                
            }
        }
        
        public function render(image:BitmapData):void {
            // Hexagon to chop into rectangle
            var hexTile:Shape = new Shape();
            hexTile.graphics.lineStyle();
            
            hexTile.graphics.beginBitmapFill(image,_matrices[0],true,true);
            hexTile.graphics.moveTo(0,0);
            hexTile.graphics.lineTo(_triangleWidth/2,_triangleHeight);
            hexTile.graphics.lineTo(-_triangleWidth/2,_triangleHeight);
            hexTile.graphics.endFill();

            hexTile.graphics.beginBitmapFill(image,_matrices[1],true,true);
            hexTile.graphics.moveTo(0,0);
            hexTile.graphics.lineTo(_triangleWidth,0);
            hexTile.graphics.lineTo(_triangleWidth/2,_triangleHeight);
            hexTile.graphics.endFill();

            hexTile.graphics.beginBitmapFill(image,_matrices[2],true,true);
            hexTile.graphics.moveTo(0,0);
            hexTile.graphics.lineTo(_triangleWidth/2,-_triangleHeight);
            hexTile.graphics.lineTo(_triangleWidth,0);
            hexTile.graphics.endFill();

            hexTile.graphics.beginBitmapFill(image,_matrices[3],true,true);
            hexTile.graphics.moveTo(0,0);
            hexTile.graphics.lineTo(-_triangleWidth/2,-_triangleHeight);
            hexTile.graphics.lineTo(_triangleWidth/2,-_triangleHeight);
            hexTile.graphics.endFill();

            hexTile.graphics.beginBitmapFill(image,_matrices[4],true,true);
            hexTile.graphics.moveTo(0,0);
            hexTile.graphics.lineTo(-_triangleWidth,0);
            hexTile.graphics.lineTo(-_triangleWidth/2,-_triangleHeight);
            hexTile.graphics.endFill();

            hexTile.graphics.beginBitmapFill(image,_matrices[5],true,true);
            hexTile.graphics.moveTo(0,0);
            hexTile.graphics.lineTo(-_triangleWidth/2,_triangleHeight);
            hexTile.graphics.lineTo(-_triangleWidth,0);
            hexTile.graphics.endFill();

            // Rectangle to tesellate
            var tileBmp:BitmapData = new BitmapData(_triangleWidth*3,_triangleHeight*2,true);
            tileBmp.draw(hexTile, new Matrix(1,0,0,1,0,_triangleHeight));
            tileBmp.draw(hexTile, new Matrix(1,0,0,1,_triangleWidth*3/2,0));
            tileBmp.draw(hexTile, new Matrix(1,0,0,1,_triangleWidth*3/2,_triangleHeight*2));
            tileBmp.draw(hexTile, new Matrix(1,0,0,1,_triangleWidth*3,_triangleHeight));
            
            var tiled:Sprite = new Sprite();
            
            tiled.graphics.beginBitmapFill(tileBmp, new Matrix(1,0,0,1, width/2, height/2-_triangleHeight*3/2)); // Center tile 0
            tiled.graphics.moveTo(0,0);
            tiled.graphics.lineTo(width,0);
            tiled.graphics.lineTo(width,height);
            tiled.graphics.lineTo(0,height);
            tiled.graphics.endFill();
            
            bitmapData.draw(tiled);
        }
    }








// CameraBitmap Class v1.0
//
// released under MIT License (X11)
// http://www.opensource.org/licenses/mit-license.php
//
// Author: Mario Klingemann
// http://www.quasimondo.com

/*
Copyright (c) 2009 Mario Klingemann

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

//package com.quasimondo.bitmapdata 
//{
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.TimerEvent;
    import flash.filters.ColorMatrixFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.media.Camera;
    import flash.media.Video;
    import flash.utils.Timer;
    import flash.utils.setTimeout;

    class CameraBitmap extends EventDispatcher 
    {
        
        [Event(name="Event.RENDER", type="flash.events.Event")]
        
        private const CAMERA_DELAY:int = 100;
        private const origin:Point = new Point();
        
        public var bitmapData:BitmapData;
        
        private var _width:int;
        private var _height:int;
        
        private var _cam:Camera;
        private var _video:Video;
        
        private var _refreshRate:int;
        private var _timer:Timer;
        private var _drawMatrix:Matrix;
        private var _smooth:Boolean;
        private var _flip:Boolean;
        private var _colorTransform:ColorTransform;
        private var _colorMatrix:Array;
        private var _colorMatrixFilter:ColorMatrixFilter = new ColorMatrixFilter();
        
        public function CameraBitmap( width:int, height:int, refreshRate:int = 15, flip:Boolean = false, cameraWidth:int = -1, cameraHeight:int = -1 )
        {
            _width  = width;
            _height = height;
            
            bitmapData = new BitmapData( width, height, false, 0 );
            
            _cam = Camera.getCamera();
            if ( cameraWidth == -1 || cameraHeight == -1 )
            {
                _cam.setMode( width, height, refreshRate, true );
            } else {
                _cam.setMode( cameraWidth, cameraHeight, refreshRate, true );
            }
            _refreshRate = refreshRate;
            _flip = flip;
            
            setTimeout( cameraInit, CAMERA_DELAY );
        }
        
        public function set active( value:Boolean ):void
        {
            if ( value ) _timer.start(); else _timer.stop();
        }

        public function close():void
        {
            active = false;
            _video.attachCamera(null);
            _video = null;
            _cam = null;
        }
        public function set refreshRate( value:int ):void
        {
            _refreshRate = value;
            _timer.delay = 1000 / _refreshRate;
        }
        
        public function set cameraColorTransform( value:ColorTransform ):void
        {
            _colorTransform = value;
        }
        
        public function set colorMatrix( value:Array ):void
        {
            _colorMatrixFilter.matrix = _colorMatrix = value;
        }
        
        private function cameraInit():void
        {
            _video = new Video( _cam.width, _cam.height );
            _video.attachCamera( _cam );
            
            if(_flip) {
                _drawMatrix = new Matrix( -_width / _cam.width, 0, 0, _height / _cam.height, _width, 0 );
            } else {
                _drawMatrix = new Matrix( _width / _cam.width, 0, 0, _height / _cam.height, 0, 0 );
            }
            
            _smooth = _drawMatrix.a != 1 || _drawMatrix.d != 1;
            
            _timer = new Timer( 1000 / _refreshRate );
            _timer.addEventListener( TimerEvent.TIMER, draw );
            _timer.start(); 
        }
        
        private function draw( event:TimerEvent = null ):void
        {
            bitmapData.lock();
            bitmapData.draw ( _video, _drawMatrix, _colorTransform, "normal", null, _smooth );
            if ( _colorMatrix != null )
            {
                bitmapData.applyFilter( bitmapData, bitmapData.rect, origin, _colorMatrixFilter );
            }
            bitmapData.unlock();
            dispatchEvent( new Event( Event.RENDER ) );
        }
    }
//}