canvasで色相環

canvasを使って色相環を描いてみた
http://kar.s206.xrea.com/js/colors.html
色の変化のさせかたを自分で考えるのが目的だったのでグラデーションの技は使わず1ピクセルずつ処理してる。
なのでかなり重い処理になってるので注意。
RGB各色が0〜255の256階調なので、半径256ドット、60度(π/3ラジアン)を256分割にした。
関数psetsの引数でrのみの指定がメインとなる色、r*th/255が徐々に混じる色、0が使わない色。
関数nの255-rを生かすと中央が白から始まる円、0(=255-255)にすると中央が黒から始まる円になる。

<html>
<head>
<title>Colors</title>
<script>
window.onload = function(){
  c = document.getElementsByTagName('canvas')[0].getContext('2d');
  for(r=0;r<256;r++) for(th=0;th<256;th+=255/r){
    psets(r,    -th,       r,       0,r*th/255);
    psets(r,     th,       r,r*th/255,      0);
    psets(r, 512-th,r*th/255,       r,      0);
    psets(r, 512+th,       0,       r,r*th/255);
    psets(r,1024-th,       0,r*th/255,      r);
    psets(r,1024+th,r*th/255,       0,      r);
  }
}
function psets(r,th,rr,gg,bb){
  x = 255.5 + r * Math.cos(th * Math.PI / 768); // 256 * 3 = 768
  y = 255.5 - r * Math.sin(th * Math.PI / 768);
  c.strokeStyle = "rgb("+n(rr,r)+","+n(gg,r)+","+n(bb,r)+")";
  c.strokeRect(x,y,1,1);
  c.strokeStyle = "rgb("+n(rr,255)+","+n(gg,255)+","+n(bb,255)+")";
  c.strokeRect(1024-x,y,1,1);
}
function n(cc,r){return Math.round(cc) + 255-r}
</script>
</head>
<body><canvas width=1024 height=512></canvas></body>
</html>

縦横1ピクセルのstrokeRectで点を描いてるつもりなんだけどなぜか1ピクセル以上の幅になってしまう。
→与える座標を0.5ずらしたら解決した。なんて律儀なモデルなんだ。

線の太さが 1.0 で (3,1) から (3,5) までのパスを考えた場合、中央の図のようになります。実際に塗りつぶされる領域 (暗い青色) は中間からパスの両側のピクセルまで広がり、考えていたパスに近いものが描画されます。つまり、これらのピクセルのみが部分的に薄くされ、領域全体 (明るい青色と暗い青色) の半分が、実際に描く色として暗く塗りつぶされます。これが先のコード例の 1.0 幅の線で起こったことです。
これを修正するには、とても正確にパスを作成しなければなりません。知ってのとおり、1.0 幅の線は線幅を単位の半分からパスの両側まで広げます。右端の図は、(3.5,1) から (3.5,5) までのパスを作成した場合の結果です。最終的に 1.0 幅の線は完成し、単一ピクセルの垂直線を正確に塗りつぶすことができました。

https://developer.mozilla.org/ja/Canvas_tutorial/Applying_styles_and_colors

黄色や紫のところにうっすらと線が見えるのも気になる。境界処理をミスってるのだろうか…。