仕事でjavascriptをいじることになりそうだ。
そいで、canvas+javascriptって昔の図形言語するのに最適じゃね?って感じだったので丸写ししてみた。

今検索したらやってるひといっぱいいるね。
何匹目のどじょうやら。

相変わらず関数を返すときにどう書けばいいのか迷う。
schemeを丸写しするときに、引数の間にコンマ入れるのを忘れる。

昔とちがってwaveを自力で書いた。

<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<script type="text/javascript">
var canWidth,
	canHieght,
	ctx;

window.onload = function() {

  var canvas = document.getElementById('mycanvas');
  canWidth = +canvas.getAttribute('width');
  canHeight = +canvas.getAttribute('height');
  ctx = canvas.getContext('2d');
  console.log(canWidth + ", " + canHeight);
  paint();
  ctx.fillStyle = 'rgb(255, 0, 0)';
};


var draw_line = function (start_v, end_v) {
  var x1 = canWidth * start_v.x,
      y1 = canHeight * start_v.y,
      x2 = canWidth * end_v.x,
      y2 = canHeight * end_v.y;
  ctx.moveTo(x1, y1);	
  ctx.lineTo(x2, y2);	
};

var segments_painter = function(seg_list) {
  return function(frame) {
    var i,
	trans_func = frame_coord_map(frame);
    console.log(seg_list[0][0].x);
    console.log(seg_list[0][0].y);
    console.log(seg_list[0][1].x);
    console.log(seg_list[0][1].y);
    for(i=0; i<seg_list.length; i++) {
      console.log("y =" + seg_list[i][1].y);
      draw_line(trans_func(seg_list[i][0]), 
		trans_func(seg_list[i][1]));
    }
  };
};

var make_vect = function(x, y) {
  return {
    x: x,
    y: y
  };
};

var add_vect = function(v1, v2) {
  return {
    x: v1.x + v2.x,
    y: v1.y + v2.y
  };
};
var sub_vect = function(v1, v2) {
  return {
    x: v1.x - v2.x,
    y: v1.y - v2.y
  };
};

var scale_vect = function(s, v) {
  return {
    x: v.x * s,
    y: v.y * s
  };
};

var make_frame = function (origin, edge1, edge2) {
  return {
    origin: origin,
    edge1: edge1,
    edge2: edge2
  };
};

var origin_frame = function(frame) {
  return frame.origin;
};

var edge1_frame = function(frame) {
  return frame.edge1;
};
var edge2_frame = function(frame) {
  return frame.edge2;
};


var frame_coord_map = function(frame) {
  return function(vec) {
    return add_vect(
    origin_frame(frame),
		    add_vect(scale_vect(vec.x, edge1_frame(frame)),
			     scale_vect(vec.y, edge2_frame(frame))));
  };
};

var transform_painter = function(painter,origin, corner1, corner2) {
  return function(frame) {
    var m = frame_coord_map(frame);
    var new_origin = m(origin);
    painter(make_frame(
    new_origin,
    sub_vect(m(corner1), new_origin),
    sub_vect(m(corner2), new_origin)));
  };
};

var x_painter = segments_painter([
		[{x:0.0,y:0.0},{x:1.0,y:1.0}],
		[{x:1.0,y:0.0},{x:0.0,y:1.0}],
		]);

var wave = segments_painter([
		[{x:0.4,y:0.0},{x:0.35,y:0.2}],
		[{x:0.35,y:0.2},{x:0.4,y:0.4}],
		[{x:0.4,y:0.4},{x:0.3,y:0.4}],
		[{x:0.3,y:0.4},{x:0.15,y:0.45}],
		[{x:0.15,y:0.45},{x:0.0,y:0.15}],
		[{x:0.0,y:0.4},{x:0.15,y:0.5}],
		[{x:0.15,y:0.5},{x:0.3,y:0.45}],
		[{x:0.3,y:0.45},{x:0.35,y:0.5}],
		[{x:0.35,y:0.5},{x:0.2,y:1.0}],
		[{x:0.4,y:1.0},{x:0.5,y:0.75}],
		[{x:0.5,y:0.75},{x:0.6,y:1.0}],
		[{x:0.8,y:1.0},{x:0.6,y:0.5}],
		[{x:0.6,y:0.5},{x:1.0,y:0.85}],
		[{x:1.0,y:0.6},{x:0.75,y:0.4}],
		[{x:0.75,y:0.4},{x:0.6,y:0.4}],
		[{x:0.6,y:0.4},{x:0.65,y:0.2}],
		[{x:0.65,y:0.2},{x:0.6,y:0.0}],
		]);
var flip_vert = function(painter) {
  return transform_painter(painter, {x:0.0,y:1.0}, {x:1.0, y:1.0}, {x:0.0, y:0.0});
};

var flip_horiz = function(painter) {
  return transform_painter(painter, {x:1.0,y:0.0}, {x:0.0,y:0.0}, {x:1.0,y:1.0});
};

var shrink_to_upper_right = function(painter) {
	return transform_painter(painter, {x:0.5,y:0.0}, {x:1.0, y:0.0}, {x:0.5, y:0.5});
};

var below = function(painter1, painter2) {
  var split_point = {x:0.0, y:0.5};
  var paint_up = transform_painter(painter1, {x:0.0,y:0.0}, {x:1.0, y:0.0}, split_point);
  var paint_down = transform_painter(painter2, split_point, {x:1.0, y:0.5}, {x:0.0, y:1.0});

  return function(frame) {paint_up(frame); paint_down(frame);};
}

var beside = function(painter1, painter2) {
	var split_point = {x:0.5, y:0.0};
	var paint_left = transform_painter(painter1, {x:0.0,y:0.0}, split_point, {x:0.0, y:1.0});
	var paint_right = transform_painter(painter2, split_point, {x:1.0,y:0.0}, {x:0.5, y:1.0});

	return function(frame) {paint_left(frame); paint_right(frame); };
};



function right_split(painter, n) {
  if (n === 0) {
     return painter;
  } else {
    var smaller = right_split(painter, (n - 1));
    return beside(painter, below(smaller, smaller));
  }
};

function up_split(painter, n) {
   if (n === 0) {
     return painter;
   } else {
     var smaller = up_split(painter, (n - 1));
     return below(beside(smaller, smaller), painter);
   }
}

function corner_split(painter, n) {
   if (n === 0) {
     return painter;
   } else {
      var up = up_split(painter, (n - 1));
      var right  = right_split(painter, (n - 1));
      var top_left = beside(up, up);
      var bottom_right = below(right, right);
      var corner = corner_split(painter, (n - 1));

      return beside(below(top_left, painter),
                    below(corner, bottom_right));
   }
}

function squre_limit(painter, n) {
   var q = corner_split(painter, n);
   var h = beside(flip_horiz(q), q);
   return below(h, flip_vert(h));
}

var paint = function() {
    ctx.beginPath();
    squre_limit(wave, 4)
		(make_frame({x:0.0,y:0.0}, {x:1.0, y:0.0}, {x:0.0, y:1.0}));
    ctx.stroke();
    ctx.closePath();
};

</script>
</head>
<body>
<canvas id="mycanvas"  width="512" height="512"> 
サポートされていません
</canvas>
</body>
</html>