将图像加载到该堆栈片段中,然后将鼠标移到该片段上。将绘制一条从您的光标点开始跟随色相角的黑色曲线:
<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)处开始曲线,并在那里测量色相角。在该方向上移动一个单位(一个像素的宽度),请注意您的新位置很可能不是整数坐标。使用最接近像素的色相(使用类似floor
或的round
,我将不会对此进行精确检查)。继续这样,直到曲线超出范围或超过最大长度。最后,将所有曲线点绘制为覆盖在图像上的单个黑色像素(再次使用最近的像素),然后输出此新图像。
“色相角”只是色相:
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
请注意,对于技术上没有色调的灰度值,它返回0,但这很好。
(此公式使用atan2
大多数内置数学库具有的公式。R,G,B为0到1,而不是0到255。)
- 您可以使用任何常见的无损图像文件格式以及任何图像库。
- 从stdin或命令行获取输入,或编写带有图像文件名,x和y以及最大长度的参数的函数。
- 最大长度以及x和y始终是非负整数。您可以假设x和y在范围内。
- 使用您选择的名称保存输出图像或仅显示它。
- 您的实现不必与代码段完全匹配。由于舍入/计算方法略有不同,在稍有不同的地方放置了几个像素就可以了。(在混乱的情况下,这可能会导致曲线最终有很大不同,但是只要它们在视觉上看起来正确,就可以了。)
计分
以字节为单位的最小提交数获胜。