Category Archives: Math

Connect The Dots E8

Actionscript:
  1. [SWF(width = 500, height = 500)]
  2. const TWO_PI:Number = Math.PI * 2;
  3. var centerX:Number = stage.stageWidth / 2;
  4. var centerY:Number = stage.stageHeight / 2;
  5. addEventListener(Event.ENTER_FRAME, onLoop);
  6. function onLoop(evt:Event):void{
  7.     // data
  8.     var points:Array = [];
  9.     var i:int = 0;
  10.     var pointNum : int = Math.max(2,int(mouseX / 12))
  11.    
  12.     var radius:Number = 200;
  13.     var step:Number = TWO_PI / pointNum;
  14.     var theta:Number = step / 2;
  15.     for (i = 0; i<pointNum; i++){
  16.         var xp:Number = centerX + radius * Math.cos(theta);
  17.         var yp:Number = centerY + radius * Math.sin(theta);
  18.         points[i] = new Point(xp, yp);
  19.         theta += step;
  20.     }
  21.     // render
  22.     graphics.clear();
  23.     graphics.lineStyle(0,0);
  24.     for ( i = 0; i<pointNum; i++){
  25.      var a:Point = points[i];
  26.      for (var j:int = 0; j<pointNum; j++){
  27.         var b:Point = points[j];
  28.         if (a != b){
  29.            graphics.drawCircle(a.x, a.y, 10);
  30.            graphics.moveTo(a.x, a.y);
  31.            graphics.lineTo(b.x, b.y);
  32.         }
  33.      }
  34.    }
  35. }

I've been using this geometric shape for lots of different things recently. Including during consulting gigs as a helpful visualization. Just move your mouse left and right... I particularly like the simpler forms you get by moving your mouse to the left (triangles squares and simple polygons):

While not entirely related this wikipedia article is interesting.

[EDIT : Thanks to martin for reminding me that I can do away with the if statement here in the above code ]

Actionscript:
  1. graphics.clear();
  2. graphics.lineStyle(0,0);
  3. for (i = 0; i<pointNum; i++) {
  4.     var a:Point=points[i];
  5.     for (var j:int = i+1; j<pointNum; j++) {
  6.         var b:Point=points[j];
  7.         graphics.drawCircle(a.x, a.y, 10);
  8.         graphics.moveTo(a.x, a.y);
  9.         graphics.lineTo(b.x, b.y);
  10.     }
  11. }
  12. graphics.drawCircle(a.x, a.y, 10);

I implemented that change over at wonderfl and it works nicely

Also posted in Graphics, misc | Tagged , , | 4 Comments

Polar Coordinates Distribution

If you're at all interested in watching me free from code. I recorded a video of me coding this snippet (which is about 11 minutes long or so).

In the video I create a few functions that allow you to draw shapes like these:

Mathematically this stuff is really simple ... the free form nature of the video takes a less technical perspective as you'll see (I even made a few funny mistakes).



Actionscript:
  1. [SWF(width = 600, height = 600)]
  2. var dotNum:int = 1000;
  3. var dotRad:Number = 0.5;
  4.  
  5. x = 120
  6. y = 100;
  7.  
  8. // extra stuff to display what the functions can do
  9. stage.addEventListener(MouseEvent.CLICK, onDrawAll);
  10.  
  11. function onDrawAll(evt:Event):void{
  12.     graphics.clear();
  13.     for (var i:int = 0; i<16; i++){
  14.         var m:Number;
  15.    
  16.         var rad:Number = 120;
  17.         var xp:Number = i % 4 * rad
  18.         var yp:Number = int(i / 4) * rad
  19.    
  20.         var type:int = int(Math.random() * 4);
  21.         if (type == 0){
  22.           makeShape(xp, yp, rad-60, Math.random() , 1);
  23.         }else if (type == 1){
  24.            makeShape(xp, yp, rad-60, 1,  Math.random());
  25.         }
  26.         else if (type == 2){
  27.            m = Math.random() * 2;
  28.            makeShape(xp, yp, rad-Math.random()*120, m, m);
  29.         }
  30.         else if (type == 3){
  31.            m = Math.random() * 2;
  32.            makeShape(xp, yp, rad-Math.random()*120, m, m/2);
  33.         }
  34.     }
  35. }
  36.  
  37. // main part from the video
  38. function makeShape(xp:Number, yp:Number,
  39.                    maxRad:Number = 100,m0:Number=1,
  40.                    m1:Number=1):void{
  41.     var polarX:Number;
  42.     var polarY:Number;
  43.     var radius:Number;
  44.     graphics.lineStyle(0, 0);
  45.     var theta:Number = Math.random() * Math.PI * 2;
  46.     for (var i:int = 0; i<dotNum; i++){
  47.         radius = Math.random() * maxRad
  48.         polarX = xp + radius * Math.cos(theta * m0);
  49.         polarY = yp + radius * Math.sin(theta * m1);
  50.         theta += 0.1;
  51.          
  52.         makeDot(polarX, polarY);
  53.        
  54.     }
  55. }
  56.  
  57. function makeDot(xp:Number, yp:Number, fillColor:uint = 0x000000):void{
  58.     graphics.beginFill(fillColor);
  59.     graphics.drawCircle(xp, yp, dotRad);
  60.     graphics.endFill();
  61. }

Here it is over at wonderf:

Also posted in Graphics, functions, misc | Tagged , , | 4 Comments

Prefix Notation (Lisp Style)

Today's quiz is not multiple choice. Instead, your task is to write a lisp style math parser. This may sound tricky, but it's surprisingly simple. (well... not simple exactly, it's just simple compared to what one might assume).

Lisp uses prefix notation... where the operator is placed before the operands:

10 * 10

becomes:

* 10 10

You could think of this as a function "*" with two arguments (10, 10). In Lisp this is enclosed with parens:

(* 10 10)

Let's see a few more examples:

100 / 2 + 10

becomes:

(+ (/ 100 2) 10)

...
2 * 4 * 6 * 7

becomes:

(* 2 4 6 7)

...

(2 + 2) * (10 - 2) * 2

becomes

(* (+ 2 2) (- 10 2) 2)

Remember, thinking "functions" really helps. The above can be though of as:

multiply( add(2, 2), subtract(10 , 2), 2)

You should create a function called parsePrefix() that takes a string and returns a number:

Here is some code to test if your parser works properly:

Actionscript:
  1. trace(parsePrefix("(* 10 10)"));
  2.  
  3. trace(parsePrefix("(* 1 (+ 20 2 (* 2 7) 1) 2)"));
  4.  
  5. trace(parsePrefix("(/ 22 7)"));
  6.  
  7. trace(parsePrefix("(+ (/ 1 1) (/ 1 2) (/ 1 3) (/ 1 4))"));
  8.  
  9. /* Should trace out:
  10. 100
  11. 74
  12. 3.142857142857143
  13. 2.083333333333333
  14. */

I highly recommend giving this a try, it was one of those cases where I assumed it would be much trickier than it was.

I've posted my solution here.

Also posted in Quiz | Tagged , , , , | 4 Comments

Float as a Fraction

Actionscript:
  1. // print some floats as fractions
  2. printFraction(0.5);
  3. printFraction(0.75);
  4. printFraction(0.48);
  5.  
  6. // try something a little more complex
  7. var float:Number = 0.98765432;
  8. trace("\na more complex example:");
  9. printFraction(float);
  10. var frac:Array = asFraction(float);
  11. trace("double check it:");
  12. trace(frac[0] + "/" + frac[1] +" = " + frac[0] / frac[1]);
  13.  
  14. /* outputs:
  15. 0.5 = 1/2
  16. 0.75 = 3/4
  17. 0.48 = 12/25
  18.  
  19. a more complex example:
  20. 0.98765432 = 12345679/12500000
  21. double check it:
  22. 12345679/12500000 = 0.98765432
  23. */
  24.  
  25.  
  26. function printFraction(n:Number):void{
  27.     var frac:Array = asFraction(n);
  28.     trace(n + " = " + frac[0] + "/" + frac[1]);
  29. }
  30.  
  31. // takes any value less than one and returns an array
  32. // with the numerator at index 0 and the denominator at index 1
  33. function asFraction(num:Number):Array{
  34.     var decimalPlaces:int = num.toString().split(".")[1].length;
  35.     var denom:Number = Math.pow(10, decimalPlaces);
  36.     return reduceFraction(num * denom, denom);
  37. }
  38.  
  39. // divide the numerator and denominator by the GCF
  40. function reduceFraction(numerator:int, denominator:Number):Array{
  41.     // divide by the greatest common factor
  42.     var divisor:int = gcf(numerator, denominator);
  43.     if (divisor){
  44.         numerator /= divisor;
  45.         denominator /= divisor;
  46.     }
  47.     return [numerator, denominator];
  48. }
  49.                    
  50. // get the greatest common factor of two integers
  51. function gcf(a:int, b:int):int{
  52.     var remainder:int;
  53.     var factor:Number = 0;
  54.     var maxIter:int = 100;
  55.     var i:int = 0;
  56.     while (1){
  57.         if (b> a){
  58.            var swap:int = a;
  59.            a = b;
  60.            b = swap;
  61.         }
  62.         remainder = a % b;
  63.         a = b;
  64.         b = remainder
  65.         if (remainder == 0){
  66.             factor = a;
  67.             break;
  68.         }else if (remainder==1){
  69.             break;
  70.         }else if (i> maxIter){
  71.             trace("failed to calculate gcf");
  72.             break;
  73.         }
  74.         i++;
  75.     }
  76.     return factor;
  77. }

This snippet contains a few functions for calculating fractions based on float values. Writing this brought back some memories from grade school math.

Also posted in misc | Tagged , , | 4 Comments