このスタックスニペットに画像をロードし、マウスをその上に移動します。カーソルポイントから始まる、色相角に続く黒い曲線が描画されます。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><style>canvas{border:1px solid black;}</style>Load an image: <input type='file' onchange='load(this)'><br><br>Max length <input id='length' type='text' value='300'><br><br><div id='coords'></div><br><canvas id='c' width='100' height='100'>Your browser doesn't support the HTML5 canvas tag.</canvas><script>function load(t){if(t.files&&t.files[0]){var e=new FileReader;e.onload=setupImage,e.readAsDataURL(t.files[0])}}function setupImage(t){function e(t){t.attr("width",img.width),t.attr("height",img.height);var e=t[0].getContext("2d");return e.drawImage(img,0,0),e}img=$("<img>").attr("src",t.target.result)[0],ctx=e($("#c")),ctxRead=e($("<canvas>"))}function findPos(t){var e=0,a=0;if(t.offsetParent){do e+=t.offsetLeft,a+=t.offsetTop;while(t=t.offsetParent);return{x:e,y:a}}return void 0}$("#c").mousemove(function(t){function e(t,e){var a=ctxRead.getImageData(t,e,1,1).data,i=a[0]/255,r=a[1]/255,o=a[2]/255;return Math.atan2(Math.sqrt(3)*(r-o),2*i-r-o)}if("undefined"!=typeof img){var a=findPos(this),i=t.pageX-a.x,r=t.pageY-a.y;$("#coords").html("x = "+i.toString()+", y = "+r.toString());var o=parseInt($("#length").val());if(isNaN(o))return void alert("Bad max length!");for(var n=[i],f=[r],h=0;n[h]>=0&&n[h]<this.width&&f[h]>=0&&f[h]<this.height&&o>h;)n.push(n[h]+Math.cos(e(n[h],f[h]))),f.push(f[h]-Math.sin(e(n[h],f[h]))),h++;ctx.clearRect(0,0,this.width,this.height),ctx.drawImage(img,0,0);for(var h=0;h<n.length;h++)ctx.fillRect(Math.floor(n[h]),Math.floor(f[h]),1,1)}});</script>
このスニペットはGoogle Chromeでのみテストしました。
たとえば、カーソルが赤の上にある場合、曲線の傾きは0°ですが、黄色の上にある場合、傾きは60°です。曲線は、指定された長さだけ継続し、色相に合わせて傾斜を連続的に変更します。
この画像をロードし、カーソルをパンすると、カーソルの周りの線が完全に反時計回りに回転します。
これとこれは、試してみるのに適した他の画像です。(保存してからスニペットで読み込む必要があります。クロスオリジン制約のため、直接リンクすることはできません。)
スニペットの縮小されていないバージョンは次のとおりです。
チャレンジ
スニペットが実行していることを実行するプログラムを作成します。対話型ではありません。画像と画像の境界内の(x、y)座標、および最大曲線長を取得します。(x、y)から始まり、最大長に達するか、画像の境界に達すると終了する色相角に続く追加の黒い曲線を使用して、同じ画像を出力します。
具体的には、(x、y)で曲線を開始し、そこで色相角を測定します。その方向に1単位(1ピクセルの幅)移動します。新しい位置はおそらく整数座標ではないことに注意してください。曲線上の別の点をマークし、最も近いピクセルの色相を使用して再度移動しますfloor
またはのround
、これを正確に確認しません)。曲線が範囲外になるか、最大長を超えるまでこのように続けます。終了するには、すべての曲線ポイントを画像上に重ねられた単一の黒いピクセル(再び、最も近いピクセルを使用)としてプロットし、この新しい画像を出力します。
「色相角」は色相です。
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
技術的に色相を持たないグレースケール値の場合、これは0を返しますが、それで問題ないことに注意してください。
(この式はatan2
、ほとんどの組み込み数学ライブラリが持っているものを使用します。R、G、Bは0〜255ではなく、0〜1です。)
- 一般的なロスレス画像ファイル形式だけでなく、画像ライブラリも使用できます。
- stdinまたはコマンドラインから入力を取得するか、イメージファイル名、xおよびy、および最大長の引数を使用して関数を記述します。
- 最大長とxおよびyは常に非負の整数です。xとyが範囲内にあると仮定できます。
- 選択した名前で出力画像を保存するか、単に表示します。
- 実装はスニペットと完全に一致する必要はありません。わずかに異なる丸め/計算方法により、わずかに異なる場所にあるいくつかのピクセルは問題ありません。(混chaとした場合、これは大きく異なるカーブにつながる可能性がありますが、視覚的に正しいように見える限り問題ありません。)