Category Archives: BitmapData

Implicit 3D Plot

Actionscript:
  1. var matrix:Matrix3D = new Matrix3D();
  2. var verts:Vector.<Number> = new Vector.<Number>();
  3. var pVerts:Vector.<Number> = new Vector.<Number>();
  4. var uvts:Vector.<Number> = new Vector.<Number>();
  5. for (var i:Number = -2; i<2; i+=.04) {
  6.     for (var j:Number = -2; j<2; j+=.04) {
  7.         for (var k:Number = -2; k<2; k+=.04) {
  8.             // blobby, from here www.iiit.net/techreports/ImplicitTR.pdf
  9. var s:Number=i*i+j*j+k*k+Math.sin(4*i)-Math.cos(4*j)+Math.sin(4*k)-1;
  10.             if (s<0&&s>-.2) {
  11.                 verts.push(i * 60);
  12.                 verts.push(j * 60);
  13.                 verts.push(k * 60);
  14.                 pVerts.push(0),pVerts.push(0);
  15.                 uvts.push(0),uvts.push(0),uvts.push(0);
  16.             }
  17.         }
  18.     }
  19. }
  20. var brush:BitmapData=new BitmapData(3,2,true,0x41FFFFFF);
  21. var canvas:BitmapData=new BitmapData(400,400,false,0x000000);
  22. addChild(new Bitmap(canvas));
  23. var dx:Number=0;
  24. var dy:Number=0;
  25. addEventListener(Event.ENTER_FRAME, onLoop);
  26. function onLoop(evt:Event):void {
  27.     dx += (mouseX - dx)/4;
  28.     dy += (mouseY - dy)/4;
  29.     matrix.identity();
  30.     matrix.appendRotation(dy,Vector3D.X_AXIS);
  31.     matrix.appendRotation(dx,Vector3D.Y_AXIS);
  32.     matrix.appendTranslation(200, 200, 0);
  33.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  34.     canvas.lock();
  35.     canvas.fillRect(canvas.rect, 0x000000);
  36.     var p = new Point();
  37.     for (var i:int = 0; i<pVerts.length; i+=2) {
  38.         p.x = pVerts[i];
  39.         p.y = pVerts[i+1];
  40.         canvas.copyPixels(brush, brush.rect, p, null, null, true);
  41.     }
  42.     canvas.unlock();
  43. }

I was looking at some equations for implicit 3D surfaces in this pdf about raytracing... anyway, I realized I could just modify the Utils3D.projectVectors() code (that I wrote a little while ago) to easily render any of the implicit equations mentioned in the pdf. I also did some experimentation with fake lighting and distance rendering which I may post in the future.

(check out the swf on wonderfl.net)

Here are some stills of the above snippet:

Also posted in 3D, Math, Vector, graphics algorithms, pixel manipulation, strings | Tagged , | Leave a comment

static BitmapData References

Actionscript:
  1. package{
  2.    
  3.     import flash.display.*;
  4.     import flash.events.*;
  5.     import flash.geom.*;
  6.    
  7.     public class QuickCheckBox extends Sprite{
  8.        
  9.         private var _checked:Boolean;
  10.         private var _bitmap:Bitmap;
  11.         private var _canvas:BitmapData;
  12.        
  13.         private static var checked:BitmapData;
  14.         private static var unchecked:BitmapData;
  15.         private static var bg:Shape;
  16.         private static var ex:Shape;
  17.         private static var pnt:Point;
  18.        
  19.         // static init for BitmapData and drawing
  20.         {
  21.             trace("only render your graphics once");
  22.             pnt = new Point(0,0);
  23.             checked = new BitmapData(10,10, true, 0x00000000);
  24.             unchecked = new BitmapData(10, 10, true, 0x00000000);
  25.             bg = new Shape();
  26.             with(bg.graphics) lineStyle(0,0x000000), beginFill(0xEFEFEF), drawRect(0,0,9,9);
  27.             unchecked.draw(bg);
  28.             ex = new Shape();
  29.             with(ex.graphics) {
  30.                 lineStyle(2,0x333333), moveTo(3, 3),
  31.                 lineTo(7, 7), moveTo(7, 3), lineTo(3, 7);
  32.             }
  33.             checked.draw(bg);
  34.             checked.draw(ex);
  35.         }
  36.        
  37.         public function QuickCheckBox(value:Boolean = false):void{
  38.             _checked = value;
  39.             _canvas =  new BitmapData(10,10, true, 0x00000000);
  40.             _bitmap = new Bitmap(_canvas);
  41.             addChild(_bitmap);
  42.             buttonMode = true;
  43.             render();
  44.             addEventListener(MouseEvent.CLICK, onClick);
  45.         }
  46.        
  47.         public function render():void{
  48.              if (_checked){
  49.                  _canvas.copyPixels(QuickCheckBox.checked, _canvas.rect, pnt);
  50.              }else{
  51.                  _canvas.copyPixels(unchecked, _canvas.rect, pnt);
  52.             }
  53.         }
  54.        
  55.         private function onClick(evt:Event):void{
  56.             _checked = !_checked;
  57.             render();
  58.             this.dispatchEvent(new Event(Event.CHANGE, true));
  59.         }
  60.        
  61.         public function get checked():Boolean{
  62.             return _checked;
  63.         }
  64.        
  65.         public function set checked(val:Boolean):void{
  66.             _checked = val;
  67.             render();
  68.         }
  69.     }
  70. }

This checkbox class uses a static initializer. Static initializers can come in handy to initialize some static variables for all class instances to make use of. In this case I'm using the static initializer to create checked and unchecked BitmapData objects - all instances of QuickCheckBox use these two static BitmapData objects rather than create their own unique ones.

Here is some client code if you want to test this class out:

Actionscript:
  1. for (var i:int = 0; i<100; i++){
  2.  var checkBox:QuickCheckBox = new QuickCheckBox(true);
  3.  checkBox.x =100 +  i % 10 * 12;
  4.  checkBox.y = 100 + int(i / 10) * 12;
  5.  // uncheck a few checkboxes
  6.  if (checkBox.x == checkBox.y){
  7.      checkBox.checked = false;
  8.  }
  9.  addChild( checkBox);
  10.  // checkBox dispatches a change event
  11.  checkBox.addEventListener(Event.CHANGE, onChange);
  12. }
  13. function onChange(evt:Event):void{
  14.     trace(evt.currentTarget.checked);
  15. }
  16. /*outputs
  17. only render your graphics once
  18. */

This draws 100 checkboxes, - you'll also notice in the output window that the trace statement from QuickCheckBox only runs once.

Here are 100 instances of QuickCheckBox:

Also posted in OOP, UI | Tagged , | 4 Comments

Random Equation Attractor

Actionscript:
  1. [SWF(width = 800, height = 800)]
  2. var a:Number = 0.19;
  3. var b:Number = .9;
  4. var c:Number = 1.3
  5. var xn1:Number = 5;
  6. var yn1:Number = 0;
  7. var xn:Number, yn:Number;
  8.  
  9. var scale:Number =40;
  10. var iterations:Number = 20000;
  11.  
  12. function f(x:Number):Number{
  13.     // too lazy to simplify this at the moment
  14.     return((x + .1 + x * (a - c) * x) / (1.1 + a * (c*c + a*a)  * x * x )) * 1.3;
  15. }
  16.  
  17. var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(800,800,false,0xEFEFEF)))).bitmapData;
  18.                                                                        
  19. addEventListener(Event.ENTER_FRAME, onLoop);
  20. function onLoop(evt:Event):void {
  21.    
  22.     canvas.fillRect(canvas.rect, 0xEFEFEF);
  23.      
  24.     c +=  ((stage.stageWidth/2 - mouseX) / 8000 - c) / 2;
  25.    
  26.     xn1 = 0;
  27.     yn1 = 0;
  28.     for (var i:int = 0; i<iterations; i++){
  29.           xn = xn1;
  30.           yn = yn1;
  31.          
  32.           xn1 = -xn - a + c +  f(yn);
  33.           yn1 = -xn + c * f(xn * yn);
  34.           canvas.setPixel( 380 + xn1 * scale, 450 + yn1 * scale, 0x000000);
  35.     }
  36. }

I was randomly messing around with strange attractors a few weeks back and this is one of the better results.... I arbitrarily altered equations until I got a nice result. You can move your mouse left and right to alter some of the params. Here is what it looks like when your mouse is in the middle of the screen:

Also posted in misc, motion, pixel manipulation, setPixel | Tagged , | Leave a comment

Swirl Gradient

Actionscript:
  1. var canvas:BitmapData=new BitmapData(200,200,false,0x000000);
  2. addChild(new Bitmap(canvas));
  3. scaleX=scaleY=2;
  4. var pixNum:int=canvas.width*canvas.height;
  5.  
  6. var xp:Vector.<int> = new Vector.<int>();
  7. var yp:Vector.<int> = new Vector.<int>();
  8. var radius:Vector.<Number> = new Vector.<Number>();
  9. var theta:Vector.<Number> = new Vector.<Number>();
  10. for (var i:int = 0; i<pixNum; i++) {
  11.     xp.push(i % 200);
  12.     yp.push(int(i / 200));
  13.     var dx:Number=100-xp[i];
  14.     var dy:Number=100-yp[i];
  15.     theta.push(Math.atan2(dy, dx));
  16.     radius.push(Math.sqrt(dx * dx + dy * dy)/20);
  17. }
  18.  
  19. addEventListener(Event.ENTER_FRAME, onLoop);
  20. function onLoop(evt:Event):void {
  21.     canvas.lock();
  22.     var n:Number = mouseX / 100;
  23.     for (var i:int = 0; i<pixNum; i++) {
  24.         var swirl:Number = 1+Math.sin(6*Math.cos(radius[i]) -n*theta[i]);
  25.         canvas.setPixel(xp[i], yp[i],  Math.abs(255 - swirl * 255));
  26.     }
  27.     canvas.unlock();
  28. }

This snippet creates a swirl gradient. While this snippet is not highly optimized, it does implement a basic optimization technique ... I cache some repetitive calculations in Vectors and then use them on the main loop.

I got the function for a swirl gradient from mathworld...

Also posted in Math, pixel manipulation, setPixel | Tagged , | Leave a comment