Загрузите изображение в этот фрагмент стека и наведите на него указатель мыши. Будет нарисована черная кривая, которая следует за углом оттенка , начиная с точки курсора:
<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 находятся в диапазоне.
- Сохраните выходное изображение с выбранным вами именем или просто отобразите его.
- Ваша реализация не обязательно должна соответствовать фрагменту. Несколько пикселей в немного разных местах из-за немного другого метода округления / вычисления - это хорошо. (В хаотических случаях это может привести к появлению кривых, которые в основном отличаются друг от друга, но пока они выглядят правильно, это нормально.)
счет
Наименьшая подача в байтах побеждает.