Monthly Archives: February 2009

Tausworthe Random Numbers (seeded)

Actionscript:
  1. // best thing about this are the random seeds
  2. var s1:Number= 0xFFFFFF;
  3. var s2:Number = 0xCCCCCC;
  4. var s3:Number= 0xFF00FF;
  5.  
  6. // saw this algorithm on this somewhat annoying thread:
  7. // http://www.reddit.com/r/programming/comments/7yjlc/why_you_should_never_use_rand_plus_alternative/
  8. // additional googling brought me to this: http://wakaba.c3.cx/soc/kareha.pl/1100499906/
  9. // and finally to this ( didn't understand most of this one) www.ams.org/mcom/1996-65-213/S0025-5718-96-00696-5/S0025-5718-96-00696-5.pdf
  10.  
  11. function rand():Number {
  12.     s1=((s1&4294967294)<<12)^(((s1<<13)^s1)>>19);
  13.     s2=((s2&4294967288)<<4)^(((s2<<2)^s2)>>25);
  14.     s3=((s3&4294967280)<<17)^(((s3<<3)^s3)>>11);
  15.     var r:Number = (s1^s2^s3) * 2.3283064365e-10;
  16.     r = (r<0) ? r+=1 : r;
  17.     return r;
  18. }
  19.  
  20. // see a visual comparison between this and actionscript's Math.random()
  21.  
  22. var canvas:BitmapData = new BitmapData(400,400,false, 0xCCCCCC);
  23. addChild(new Bitmap(canvas));
  24.  
  25. var posX:Number;
  26. var posY:Number;
  27.  
  28. addEventListener(Event.ENTER_FRAME, onLoop);
  29.  
  30. function onLoop(evt:Event):void {
  31.  
  32.     for (var i:int = 0; i<100; i++){
  33.         posX = rand() * 180
  34.         posY = rand() * 180
  35.         canvas.setPixel( 100 + posX, 10 + posY, 0x000000);
  36.     }
  37.    
  38.     for (i = 0; i<100; i++){
  39.         posX = Math.random() * 180
  40.         posY = Math.random() * 180
  41.         canvas.setPixel( 100 + posX, 210 + posY, 0x000000);
  42.     }
  43. }

The above snippet demo's an alternative random number generator that uses the Tausworthe method.


Top square is Tausworthe and bottom is Math.random()

I don't actually know much about this, or fully understand how it works. I just saw it on a random reddit thread, googled about it for a few minutes and then ported it to actionscript.

There's lots of talk about what the BEST random number generator is.... which one is the fastest, which one is the most random. etc... I don't really know much about that, especially since I'm just playing around with code and I don't need a RNG for some scientific experiment. For me, what's nice about this approach is the three random seeds. For some reason, Math.random() doesn't have a place where you can enter a seed for random numbers. Random seeds are very useful when you want to do something random but want to be able to replicate the random results at a later time. For instance:

Actionscript:
  1. var s1:Number= 0xFFFFFF;
  2. var s2:Number = 0xCCCCCC;
  3. var s3:Number= 0xFF00FF;
  4.  
  5. trace("first three values:");
  6. trace(rand());
  7. trace(rand())
  8. trace(rand())
  9.  
  10. s1 = 0xFF;
  11. s2 = 0xEFEFEF;
  12. s3 = 19008;
  13.  
  14. trace("\nfirst three values with different seeds:");
  15. trace(rand());
  16. trace(rand())
  17. trace(rand())
  18.  
  19. s1 = 0xFFFFFF;
  20. s2  = 0xCCCCCC;
  21. s3 = 0xFF00FF;
  22.  
  23. trace("\noriginal three values:");
  24. trace(rand());
  25. trace(rand())
  26. trace(rand())
  27.  
  28. function rand():Number {
  29.     s1=((s1&4294967294)<<12)^(((s1<<13)^s1)>>19);
  30.     s2=((s2&4294967288)<<4)^(((s2<<2)^s2)>>25);
  31.     s3=((s3&4294967280)<<17)^(((s3<<3)^s3)>>11);
  32.     var r:Number = (s1^s2^s3) * 2.3283064365e-10;
  33.     r = (r<0) ? r+=1 : r;
  34.     return r;
  35. }
  36.  
  37. /*
  38. outputs:
  39. first three values:
  40. 0.051455706589931385
  41. 0.050584114155822715
  42. 0.417276361484596
  43.  
  44. first three values with different seeds:
  45. 0.6032885762463134
  46. 0.9319786790304015
  47. 0.8631882804934321
  48.  
  49. original three values:
  50. 0.051455706589931385
  51. 0.050584114155822715
  52. 0.417276361484596
  53. */

I stumbled upon a bunch of other random number algorithms, maybe I'll throw them in a class in the next couple days.

Posted in Number, misc | Tagged , | 1 Comment

Dial UI, Record Scratch etc…

Actionscript:
  1. var angOffset:Number = 0;
  2. var percent:Number  = 0;
  3.  
  4. var dial:Sprite = Sprite(addChild(new Sprite()));
  5. with(dial.graphics) lineStyle(1, 0x000000), beginFill(0xCCCCCC), drawCircle(0,0,100), lineTo(0,0);
  6. dial.x = stage.stageWidth / 2;
  7. dial.y = stage.stageHeight / 2;
  8.  
  9. dial.addEventListener(MouseEvent.MOUSE_DOWN, onDialDown);
  10. stage.addEventListener(MouseEvent.MOUSE_UP, onStageUp);
  11. function onDialDown(evt:MouseEvent):void {
  12.     calcOffset();
  13.     dial.addEventListener(Event.ENTER_FRAME, onRotateDial);
  14. }
  15.  
  16. function calcOffset():void {
  17.     angOffset = Math.atan2(mouseY - dial.y, mouseX - dial.x) / Math.PI * 180 - dial.rotation;
  18. }
  19.  
  20. function onRotateDial(evt:Event):void {
  21.     dial.rotation =  Math.atan2(mouseY - dial.y, mouseX - dial.x) / Math.PI * 180 - angOffset;
  22.     percent = dial.rotation;
  23.     if (percent <0){
  24.         percent += 360;
  25.     }
  26.     percent /= 360;
  27.     // range 0 - 1
  28.     trace(percent);
  29. }
  30.  
  31. function onStageUp(evt:Event):void {
  32.     dial.removeEventListener(Event.ENTER_FRAME, onRotateDial);
  33. }

The above shows the meat of what you need to create some kind of dial UI... this would also work well if you need to create an interactive turntable (record scratching etc...).

Everytime I needed to create dials for UI, the client wanted left -> right mouse motion rather than a circular... like what you see in Reason. Someone recently asked me how to do a circular motion style dial and this is the technique I came up with.

Posted in UI | Tagged , | Leave a comment

lineTo() w/ drawCircle()

Actionscript:
  1. var dial:Sprite = Sprite(addChild(new Sprite()));
  2. with(dial.graphics) lineStyle(1, 0x000000), beginFill(0xCCCCCC), drawCircle(0,0,100), lineTo(0,0);
  3. dial.x = stage.stageWidth / 2;
  4. dial.y = stage.stageHeight / 2;

This snippet shows how you can combine drawCircle() and lineTo() to quickly draw a clock/dial primitive shape. I'll use this in tomorrows snippet...

Posted in Graphics | Tagged , | Leave a comment

(HSV HSB) to RGB

Actionscript:
  1. [SWF(width=720,height=360,backgroundColor=0x000000,frameRate=30)]
  2.  
  3. // ported from here:
  4. //http://www.cs.rit.edu/~ncs/color/t_convert.html
  5.  
  6. function hsv(h:Number, s:Number, v:Number):Array{
  7.     var r:Number, g:Number, b:Number;
  8.     var i:int;
  9.     var f:Number, p:Number, q:Number, t:Number;
  10.      
  11.     if (s == 0){
  12.         r = g = b = v;
  13.         return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  14.     }
  15.    
  16.     h /= 60;
  17.     i  = Math.floor(h);
  18.     f = h - i;
  19.     p = v *  (1 - s);
  20.     q = v * (1 - s * f);
  21.     t = v * (1 - s * (1 - f));
  22.    
  23.     switch( i ) {
  24.         case 0:
  25.             r = v;
  26.             g = t;
  27.             b = p;
  28.             break;
  29.         case 1:
  30.             r = q;
  31.             g = v;
  32.             b = p;
  33.             break;
  34.         case 2:
  35.             r = p;
  36.             g = v;
  37.             b = t;
  38.             break;
  39.         case 3:
  40.             r = p;
  41.             g = q;
  42.             b = v;
  43.             break;
  44.         case 4:
  45.             r = t;
  46.             g = p;
  47.             b = v;
  48.             break;
  49.         default:        // case 5:
  50.             r = v;
  51.             g = p;
  52.             b = q;
  53.             break;
  54.     }
  55.     return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
  56. }
  57.  
  58.  
  59. //
  60. //  -- test it out by drawing a few things
  61. //
  62.  
  63. var canvas:BitmapData = new BitmapData(720, 360, false, 0x000000);
  64.  
  65. addChild(new Bitmap(canvas));
  66.  
  67. canvas.lock();
  68. var size:int = canvas.width * canvas.height;
  69. var xp:int, yp:int, c:Array, i:int;
  70.  
  71. for (i = 0; i<size; i++){
  72.     xp = i % 360;
  73.     yp = i / 360;
  74.     c =  hsv(xp, 1, yp / 360);
  75.     canvas.setPixel(xp, yp, c[0] <<16 | c[1] <<8 | c[2]);
  76. }
  77.  
  78. var dx:Number, dy:Number, dist:Number, ang:Number;
  79.  
  80. for (i = 0; i<size; i++){
  81.     xp = i % 360;
  82.     yp = i / 360;
  83.     dx = xp - 180;
  84.     dy = yp - 180;
  85.     dist = 1 - Math.sqrt((dx * dx) + (dy * dy)) / 360;
  86.     ang = Math.atan2(dy, dx) / Math.PI * 180;
  87.     if (ang <0){
  88.         ang += 360;
  89.     }
  90.     c =  hsv(ang, 1, dist);
  91.     canvas.setPixel(360 + xp, yp, c[0] <<16 | c[1] <<8 | c[2]);
  92. }
  93. canvas.unlock();

This is one of those things I've been meaning to play with for awhile. The above demos a function called hsv() which takes 3 arguments: angle (0-360), saturation(0-1) and value(0-1). The function returns an array of rgb values each with a range of (0-255).

There's some room for optimization here, but for clarity I left as is. Even just playing with HSV (also know as HSB) for a few minutes, I see some interesting potential for dynamically generating color palettes for generative style experiments.

I looked around for the most elegant looking code snippet to port in order to write this... I eventually stumbled upon this great resource.

If you test the above on your timeline it will generate this image:

I usually only post one snippet a day... not sure why I decided to post two today.

Posted in BitmapData, color, graphics algorithms, pixel manipulation, setPixel | Tagged , , | 6 Comments

Math.min() Math.max() …rest

Actionscript:
  1. trace("min", Math.min(100, 99, 32, 75, 44, 90));
  2. trace("max", Math.max(100, 99, 32, 75, 44, 90));
  3. /*outputs:
  4. 32
  5. 100
  6. */

It's easy not to notice that Math.min() and Math.max() can take any number of arguments. I've seen people nest min/max calls instead of using the above option.... like this:

Actionscript:
  1. trace(Math.min(1, Math.min(2, 3)));

Posted in misc | Tagged , | Leave a comment

Simple BlendMode Nav

Actionscript:
  1. stage.frameRate=30;
  2. var nav:Sprite = Sprite(addChild(new Sprite()));
  3. nav.x=nav.y=150;
  4.  
  5. var cover:Sprite;
  6. var coverDest:Number=0;
  7. var spacing:int=4;
  8. var btnNum:int=6;
  9.  
  10. buildNav();
  11.  
  12. addEventListener(Event.ENTER_FRAME, onLoop);
  13.  
  14. function onLoop(evt:Event):void {
  15.     cover.x += (coverDest - cover.x) /4;
  16. }
  17.  
  18. function buildNav():void {
  19.     for (var i:int = 0; i<btnNum; i++) {
  20.         var b:Sprite=makeBox(50,50);
  21.         b.x = i * (b.width + spacing);
  22.         b.buttonMode=true;
  23.         b.addEventListener(MouseEvent.CLICK, onClick);
  24.     }
  25.     cover=makeBox(54, 60);
  26.     cover.blendMode=BlendMode.INVERT;
  27. }
  28.  
  29. function onClick(evt:MouseEvent):void {
  30.     coverDest=evt.currentTarget.x;
  31. }
  32.  
  33. function makeBox(w:Number, h:Number) {
  34.     var b:Sprite = new Sprite();
  35.     with (b.graphics) {
  36.         beginFill(0x000000),drawRect(-w/2,-h/2,w,h);
  37.     }
  38.     nav.addChild(b);
  39.     return b;
  40. }

This is something I do in my intermediate flash classes... the only difference is that we do the graphics in the flash IDE during class time instead of drawing them with ActionScript.

Posted in motion | Tagged , | Leave a comment

MYSQL SOUNDEX

C:
  1. SELECT * FROM _users WHERE SOUNDEX(name) LIKE SOUNDEX('jon');

Not ActionScript, but the coolest thing I've seen in Mysql in awhile, the soundex function will convert a string into a soundex index... read more about it on wikipedia.

I did some tests and it matches things like:

what's your name? & whats yer name

very cool... since this isn't ActionScript, I will post another snippet right after this.

UPDATE: Actually started reading more about this stuff and dug up some algorithms... metaphone etc... fun stuff, maybe I'll port some of it to actionscript...

Posted in misc, string manipulation, strings | Leave a comment

Circles & cacheAsBitmap

Actionscript:
  1. [SWF(width=600,height=400,backgroundColor=0x000000,frameRate=30)]
  2. var mcs:Vector.<MovieClip> = new Vector.<MovieClip>();
  3. var num:int = 2000;
  4. for (var i:int = 0; i<num; i++){
  5.     var s:MovieClip = new MovieClip();
  6.     s.graphics.lineStyle(0,0xFFFFFF);
  7.     s.graphics.drawCircle(0,0, Math.random()*30 + 3);
  8.     s.x = Math.random()*stage.stageWidth;
  9.     s.y = Math.random()*stage.stageHeight;
  10.        // comment out to kill your cpu
  11.     s.cacheAsBitmap = true;
  12.     addChild(s);
  13.     s.vx  = Math.random() * 2 - 1;
  14.     s.vy  = Math.random() * 2 - 1;
  15.     mcs.push(s);
  16. }
  17. addEventListener(Event.ENTER_FRAME, onCenter);
  18. function onCenter(evt:Event):void{
  19.     for (var i:int = 0; i<num; i++){
  20.         mcs[i].x += mcs[i].vx;
  21.         mcs[i].y += mcs[i].vy;
  22.     }
  23. }

This was created in response to a question about the real speed gain of cacheAsBitmap. Just comment out the cacheAsBitmap line to see the difference.

Despite it's extreme simplicity, this is actually a rather fun file to play with, change some of the graphics class method calls around and see what happens.

Posted in DisplayObject, Graphics | Tagged , | 1 Comment

split() hacks & RegExp

Actionscript:
  1. var path:String = "section/home.swf";
  2.  
  3. var deepLinkValue:String = path.split("/")[1].split(".swf")[0];
  4.  
  5. trace(deepLinkValue);
  6. /*outputs:
  7. home
  8. */

As a primarily self taught programmer there was a time when I didn't know what a regular expression was. There was also a time when ActionScript didn't have them (you had to use a library). Sometimes when I'm in a rush I still do weird things like the above instead of regular expressions... pretty nasty I know.

Here are two different regular expressions that do the same thing:

Actionscript:
  1. var path = "section/home.swf"
  2.  
  3. trace(path.match(/\w+(?=\.)/))
  4. /*outputs:
  5. home
  6. */
  7.  
  8. trace(path.replace(/.+\/|\..+/g, ""))
  9. /* also outputs:
  10. home
  11. */

Actually, I'd be curious to see other regular expressions that only return one value (not an array) that achieve this same thing... feel free to post of a comment if you can think of one...

Posted in string manipulation, strings | Tagged , | Leave a comment

substr() Remove First Character

Actionscript:
  1. var someString:String = "_file";
  2. trace(someString.substr(1));
  3. /*
  4. ouptuts:
  5. file
  6. */

Turns out the second argument of substr() is optional..... not sure how I never noticed that before.

Posted in string manipulation, strings | Tagged , | Leave a comment