Gumowski / Mira

Actionscript:
  1. [SWF(width = 600, height = 600)]
  2. var a:Number = 0.02;
  3. var b:Number = .9998;
  4.  
  5. var xn1:Number = 5;
  6. var yn1:Number = 0;
  7. var xn:Number, yn:Number;
  8.  
  9. var scale:Number = 10;
  10. var iterations:Number = 20000;
  11.  
  12. function f(x:Number):Number{
  13.     var x2:Number = x * x;
  14.     return a * x + (2 * (1 - a) * x2) / (1 + x2);
  15. }
  16.  
  17. var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(600,600,false,0xEFEFEF)))).bitmapData;
  18.                                                                        
  19. addEventListener(Event.ENTER_FRAME, onLoop);
  20. function onLoop(evt:Event):void {
  21.    
  22.     canvas.fillRect(canvas.rect, 0xEFEFEF);
  23.     a = mouseY / 1000;
  24.     xn1 = mouseX / 30;
  25.     yn1 = 0;
  26.     for (var i:int = 0; i<iterations; i++){
  27.           xn = xn1;
  28.           yn = yn1;
  29.          
  30.           xn1 = b * yn + f(xn);
  31.           yn1 =  -xn + f(xn1);
  32.           canvas.setPixel( 280 + xn1 * scale, 300 + yn1 * scale, 0x000000);
  33.     }
  34. }

Notice the setup for this is very similar to yesterdays flames attractor post.

Back in october of last year I stumbled upon the excellent subblue website by Tom Beddard. I was REALLY impressed by a blog post about Gumowski / Mira patterns. If you haven't seen it you should go take a look.

I'd never heard of Gumowski / Mira patterns before and made a mental note to go and try to read about them and maybe find an equation to port to actionscript or processing. Anyway, a few days ago I decided to go ahead and look up the math and... this is the result.

I got equation over at mathworld...

For simplicity I intentionally made the actionscript code look as much like the mathworld equation as possible. Using f for my function name and using xn1, yn1 etc... There are a few speed optimizations that could be made but I wanted this snippet to be very readable.

Here are a few examples of what this code will generate:

Posted in Math, setPixel | Tagged , | Leave a comment

setPixel() Flames Attractor

Actionscript:
  1. [SWF(width = 600, height = 600)]
  2. var a:Number = 0.02;
  3.  
  4. var xn:Object = new Object();
  5.  
  6. var scale:Number = 20;
  7. var iterations:Number = 10000;
  8.  
  9. var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(600,600,false,0xEFEFEF)))).bitmapData;
  10.  
  11. addEventListener(Event.ENTER_FRAME, onLoop);
  12. function onLoop(evt:Event):void {
  13.    
  14.     canvas.fillRect(canvas.rect, 0xEFEFEF);
  15.     a = mouseX / 100;
  16.    
  17.     // equations from here: http://www.discretedynamics.net/Attractors/Flames.htm
  18.     // i used object syntax so that I could really reflect the math notation, changing these to
  19.     // 3 variables will significantly improve performance:
  20.     xn["n-1"] =  mouseX / 200;
  21.     xn["n"] =   mouseY / 200;
  22.     xn["n+1"] = 0;
  23.    
  24.     for (var i:int = 0; i<iterations; i++){
  25.          
  26.           xn["n+1"] = ((a * xn["n"]) / (1 + (xn["n-1"] * xn["n-1"]))) - ((xn["n-1"]) / (1 + (xn["n"] * xn["n"])));
  27.          
  28.           canvas.setPixel( 280 + xn["n-1"] * scale, 300 + xn["n"] * scale, 0x000000);
  29.          
  30.           xn["n-1"] = xn["n"];
  31.           xn["n"] = xn["n+1"];
  32.     }
  33. }

This is an attractor that vaguely resembles flames, I wrote this code so that it would be very similar to the math notation to help anyone who wonders how to go from notation to code. You could replace the Object syntax with 3 separate variables for increased performance.

See the equation here:
http://www.discretedynamics.net/Attractors/Flames.htm


This snippet will create something that looks like this and is reactive to the mouse location

Posted in setPixel | Tagged , | Leave a comment

Parallax Based on Y

Actionscript:
  1. [SWF(backgroundColor=0x000000, frameRate=30)]
  2.  
  3. var elements:Array = new Array();
  4. for (var i:int = 0; i<200; i++){
  5.     var c:MovieClip= MovieClip(addChild(new MovieClip()));
  6.     c.x = Math.random()*(stage.stageWidth + 100) - 50;
  7.     c.y = Math.random()*stage.stageHeight;
  8.     with(c.graphics) lineStyle(2, 0xFFFFFF,3), drawCircle(0,0,2 + c.y / 20);
  9.     c.startX = c.x;
  10.     elements.push(c);
  11. }
  12.  
  13. var offset:Number = 0;
  14. var t:Number = 0;
  15.  
  16. addEventListener(Event.ENTER_FRAME, onLoop);
  17. function onLoop(evt:Event):void {
  18.     t+=.1;
  19.     offset = 200 * Math.cos(t);
  20.     for (var i:int = 0; i<elements.length; i++){
  21.        elements[i].x = elements[i].startX + offset / ((stage.stageWidth - elements[i].y) / 80);
  22.     }
  23. }

I wrote this snippet originally to automatically add parallax motion to a bunch of quick drawings I did within the flash IDE. Each movieClip in the elements array is moved from left to right based on it's y position. Clips with a higher y value will oscillate more from left to right than clips with lower y values.

Here is the original drawing I used this on.

And here is what the above snippet will create.

Posted in motion | Tagged , | 2 Comments

Animate Graphics.lineTo()

Actionscript:
  1. // line thickness, line color, start point, end point, divisor, callback
  2. function animateLineTo( thick:Number, col:uint, sp:Point, ep:Point, div:Number=4, callback:Function=null):void {
  3.      var s:Shape  = Shape(addChild(new Shape()));
  4.      var ap:Point = sp.clone();
  5.      div = Math.max(2, div);
  6.      setTimeout(runLineAnimation, 1000/stage.frameRate, s.graphics , thick , col , sp , ep , ap, div, callback);
  7. }
  8.  
  9. function runLineAnimation(g:Graphics , thick:Number, col:uint, sp:Point, ep:Point, ap:Point, div:Number, callback:Function):void {
  10.      ap.x += (ep.x - ap.x) / div;
  11.      ap.y += (ep.y - ap.y) / div;
  12.       with(g){
  13.         clear();
  14.         lineStyle(thick, col);
  15.         moveTo(sp.x, sp.y);
  16.         lineTo(ap.x, ap.y);
  17.       }
  18.        if (Math.abs(ap.x - ep.x) <1 && Math.abs(ap.y- ep.y)  <1){
  19.            // done
  20.            if (callback!=null){
  21.                callback();  
  22.            }
  23.        }else{
  24.             setTimeout(runLineAnimation, 1000/stage.frameRate, g , thick , col , sp , ep , ap, div, callback);
  25.        }
  26. }
  27. //
  28. // test out the animateLineTo function:
  29. //
  30. var a:Point = new Point(100,100);
  31. var b:Point = new Point(150, 200);
  32. var c:Point = new Point(300, 190);
  33. var d:Point = new Point(280, 90)
  34.  
  35. animateLineTo(0, 0xFF0000, a, b, 4, line2);
  36.  
  37. function line2():void{
  38.     animateLineTo(0, 0xFF0000, b, c, 4, line3);
  39. }
  40.  
  41. function line3():void{
  42.     animateLineTo(0, 0xFF0000, c, d, 4, line4);
  43. }
  44.  
  45. function line4():void{
  46.     animateLineTo(0, 0xFF0000, d, a, 4);
  47. }

The above demos a function called animateLineTo() that will draw a line using zeno's paradox.

There are a couple weird/interesting tricks going on here. I'm using setTimeout() over and over rathaer than using setInterval(). This makes it so I don't need to store an interval id. I'm also using a delay of 1000/stage.frameRate, this attempts to cause the setTimeout() to run at the same frequency as an enter frame would. This is important because having a setTimeout()/setInterval() that is doing animation and attempting to run more frequently than the framerate can cause problems and is a waste of cpu power.

This snippet was spurned by a student question about how to animate a Graphics.lineTo() from point A to point B. Here is the original snippet, which is easier to read and more bare bones:

Actionscript:
  1. var p0:Point = new Point(100,100);
  2. var p1:Point = new Point(400,200);
  3. var dp:Point = new Point(p0.x,p0.y);
  4.  
  5. var s:Sprite = Sprite(addChild(new Sprite()));
  6.  
  7. addEventListener(Event.ENTER_FRAME, onLoop);
  8. function onLoop(evt:Event):void {
  9.     s.graphics.clear()
  10.     s.graphics.lineStyle(0,0x000000);
  11.     s.graphics.moveTo(p0.x, p0.y);
  12.     s.graphics.lineTo(dp.x, dp.y);
  13.     dp.x += (p1.x - dp.x) / 4;
  14.     dp.y += (p1.y - dp.y) / 4;
  15. }

Posted in motion | Tagged , | 1 Comment