# Monthly Archives: March 2009

## Interesting Function Composition

Actionscript:
2.
4. // 10 * 2  = 20
5. //  20 + 3 = 23
6.
8.
10. // 8 + 2 = 10
11. // 10 * 10 = 100
12.
13. var multBy2_3times:Function = repeat(3,mult(2));
14.
15. trace(multBy2_3times(3));
16. // 3 * 2 = 6;
17. // 6 * 2 = 12;
18. // 12 * 2 = 24
19.
20. // you can also chain for even less readability
22. // 4 + 1 = 5
23. // 5 * 5 = 25;
24. // 25 * 25 = 625;
25.
26. /*
27. outputs:
28. 12
29. 100
30. 24
31. 625
32. */
33.
34. // function  composition
35. const F:Function = function(a:*):*{return a};
36. function mult(scalar:Number, f:Function=null):Function{
37.     if (f == null) f = F;
38.      return function(n:Number){
39.         return f(n) * scalar;
40.     }
41. }
42.
44.      if (f == null) f = F;
45.      return function(n:Number){
46.         return f(n) + off;
47.     }
48. }
49. function sq(f:Function=null):Function{
50.      if (f == null) f = F;
51.      return function(n:Number){
52.          var v:Number = f(n);
53.         return  v * v;
54.     }
55. }
56. function repeat(times:int, f:Function):Function {
57.      if (f == null) f = F;
58.      return function (n:Number){
59.          var v:Number = n;
60.          for (var i:int = 0; i<times; i++) v = f(v);
61.          return v;
62.      }
63. }

The above shows some interesting function composition... this demo contains the following functions:

mult();
sq();
repeat();

These functions are designed to be combined to create new functions.

## ActionScript Wiki

Just wanted to post a link to Joa Ebert's ActionScript Wiki. Looks like there's some great stuff there...

## k-th Order Catmull-Rom Spline

Actionscript:
1. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
3. var pnts:Array = new Array();
4. // make 8 control points
5. for (var i:int = 0; i<8; i++){
6.     pnts.push(dot(50 + i * (30 + Math.random()*10),
7.                              50 + i * (30 + Math.random()*10)));
8. }
10. function onLoop(evt:Event):void {
11.     canvas.lock();
12.     canvas.fillRect(canvas.rect, 0x000000);
13.     curve(pnts);
14.     canvas.unlock();
15. }
16. function tangent(pk1:Sprite, pk_1:Sprite){
17.     return new Point((pk1.x - pk_1.x) / 2, (pk1.y - pk_1.y) / 2);
18. }
19. // all math from http://en.wikipedia.org/wiki/Cubic_Hermite_spline
20. function curve(p:Array, res:Number=.03):void{
21.     var px:Number = 0;
22.     var py:Number = 0;
23.     var pIter:int = p.length - 1;
24.     var m:Array = [];
25.     m[0] = tangent(p[1], p[0]);
26.     for (var i:int = 1; i<pIter; i++){
27.         m[i] = tangent(p[i + 1], p[i - 1]);
28.     }
29.     m[pIter] = tangent(p[pIter], p[pIter - 1]);
30.     for (var t:Number = 0; t <1; t+=res){
31.          var t_2:Number = t * t;
32.          var _1_t:Number = 1 - t;
33.          var _2t:Number = 2 * t;
34.          var h00:Number =  (1 + _2t) * (_1_t) * (_1_t);
35.          var h10:Number =  t  * (_1_t) * (_1_t);
36.          var h01:Number =  t_2 * (3 - _2t);
37.          var h11:Number =  t_2 * (t - 1);
38.          for (var k:int = 0; k <pIter; k++){
39.              var k1:int = k + 1;
40.              var pk:Sprite = p[k];
41.              var pk1:Sprite = p[k1];
42.              var mk:Point = m[k];
43.              var mk1:Point = m[k1];
44.              px = h00 * pk.x + h10 * mk.x + h01 * pk1.x + h11 * mk1.x;
45.              py = h00 * pk.y + h10 * mk.y + h01 * pk1.y + h11 * mk1.y;
46.              canvas.setPixel(px, py, 0xFFFFFF);
47.          }
48.     }
49. }
50. // draggable dot
51. function dot(xp:Number, yp:Number, col:uint = 0xFF0000, rad:Number=4):Sprite {
52.     var s:Sprite = Sprite(addChild(new Sprite));
53.     s.x = xp;
54.     s.y = yp;
56.     s.buttonMode = true;
58.     return s;
59. }
60. function onDrag(evt:MouseEvent):void {
61.     evt.currentTarget.startDrag()
62. }
64. function onUp(evt:MouseEvent):void{
65.     stopDrag();
66. }

More Catmull-Rom stuff. This one can have any number of control points:

Check it out here:

## Catmull-Rom Spline

Actionscript:
1. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
3.
4. var p0:Sprite = dot(100, 100);
5. var p1:Sprite = dot(120, 180);
6. var p2:Sprite = dot(220, 180);
7. var p3:Sprite = dot(250, 250);
8.
10. function onLoop(evt:Event):void {
11.     canvas.lock();
12.     canvas.fillRect(canvas.rect, 0x000000);
13.
14.     curve(p0, p1, p2, p3);
15.     canvas.unlock();
16. }
17.
18.
19. // all math from http://en.wikipedia.org/wiki/Cubic_Hermite_spline
20. function curve(p0:Sprite, p1:Sprite, p2:Sprite, p3:Sprite, rez:Number=.02):void{
21.     var px:Number = 0;
22.     var py:Number = 0;
23.     var m0:Point = tangent(p1, p0);
24.     var m1:Point = tangent(p2, p0);
25.     var m2:Point = tangent(p3, p1);
26.     var m3:Point = tangent(p3, p2);
27.
28.     for (var t:Number = 0; t <1; t+=rez){
29.          var t_2:Number = t * t;
30.          var _1_t:Number = 1 - t;
31.          var _2t:Number = 2 * t;
32.
33.          var h00:Number =  (1 + _2t) * (_1_t) * (_1_t);
34.          var h10:Number =  t  * (_1_t) * (_1_t);
35.          var h01:Number =  t_2 * (3 - _2t);
36.          var h11:Number =  t_2 * (t - 1);
37.
38.          px = h00 * p0.x + h10 * m0.x + h01 * p1.x + h11 * m1.x;
39.          py = h00 * p0.y + h10 * m0.y + h01 * p1.y + h11 * m1.y;
40.          canvas.setPixel(px, py, 0xFFFFFF);
41.
42.          px = h00 * p1.x + h10 * m1.x + h01 * p2.x + h11 * m2.x;
43.          py = h00 * p1.y + h10 * m1.y + h01 * p2.y + h11 * m2.y;
44.          canvas.setPixel(px, py, 0xFFFFFF);
45.
46.          px = h00 * p2.x + h10 * m2.x + h01 * p3.x + h11 * m3.x;
47.          py = h00 * p2.y + h10 * m2.y + h01 * p3.y + h11 * m3.y;
48.          canvas.setPixel(px, py, 0xFFFFFF);
49.     }
50. }
51.
52. function tangent(pk1:Sprite, pk_1:Sprite){
53.     return new Point((pk1.x - pk_1.x) / 2, (pk1.y - pk_1.y) / 2);
54. }
55.
56. // draggable dot
57. function dot(xp:Number, yp:Number, col:uint = 0x507399, rad:Number=5):Sprite {
58.     var s:Sprite = Sprite(addChild(new Sprite));
59.     s.x = xp;
60.     s.y = yp;
62.     s.buttonMode = true;
64.     return s;
65. }
66. function onDrag(evt:MouseEvent):void {
67.     evt.currentTarget.startDrag()
68. }
70. function onUp(evt:MouseEvent):void{
71.     stopDrag();
72. }

This is snippet draws a Catmull-Rom spline based on 4 control points. A nice feature of Catmull-Rom splines is that they always pass through each of their control points.

have a look at the swf here:

I first learned about Catmull-Rom splines somewhere in the processing forums.

I got all my info for this snippet from this wikipedia page.

There is a good deal of room for optimization here... I may post an optimized version in the future.

Posted in Math, graphics algorithms, setPixel | Tagged , | 5 Comments