k-th Order Catmull-Rom Spline

Actionscript:
  1. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
  2. addChild(new Bitmap(canvas));
  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. }
  9. addEventListener(Event.ENTER_FRAME, onLoop);
  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;
  55.     with(s.graphics) beginFill(col), drawCircle(0,0,rad);
  56.     s.buttonMode = true;
  57.     s.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
  58.     return s;
  59. }
  60. function onDrag(evt:MouseEvent):void {
  61.     evt.currentTarget.startDrag()
  62. }
  63. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  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:

This entry was posted in Math, graphics algorithms, setPixel. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*