Cargue una imagen en este fragmento de pila y mueva el mouse sobre él. Se dibujará una curva negra que sigue el ángulo de tono , comenzando en el punto del cursor:
<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>
Solo probé este fragmento en Google Chrome.
Por ejemplo, cuando el cursor está por encima de rojo, la curva tiene una pendiente de 0 °, pero cuando está por encima de amarillo, tiene una pendiente de 60 °. La curva continúa durante la longitud especificada, cambiando continuamente su pendiente para que coincida con el tono.
Cargue esta imagen y cuando desplace el cursor sobre ella, la línea justo alrededor del cursor debe hacer un giro completo en sentido antihorario:
Esta y estas son otras imágenes interesantes para probar. (Deberá guardarlos y luego cargarlos con el fragmento. No se pueden vincular directamente debido a restricciones de origen cruzado).
Aquí hay una versión no minificada del fragmento:
Desafío
Escriba un programa que haga lo que está haciendo el fragmento, pero no de forma interactiva. Tome una imagen y una coordenada (x, y) en los límites de la imagen, y una longitud máxima de la curva. Imprima la misma imagen con la curva negra agregada que sigue los ángulos de tono que comienzan en (x, y) y finaliza cuando alcanza la longitud máxima o alcanza un límite de imagen.
Específicamente, comience la curva en (x, y) y mida el ángulo del tono allí. Vaya una unidad (el ancho de un píxel) en esa dirección, observando que su nueva posición probablemente no sea una coordenada entera . Marque otro punto en la curva y muévase nuevamente, usando el tono del píxel más cercano (usando algo como floor
o round
, no lo comprobaré con precisión). Continúe así hasta que la curva salga de los límites o exceda la longitud máxima. Para finalizar, trace todos los puntos de la curva como píxeles negros individuales (nuevamente, use los píxeles más cercanos) superpuestos en la imagen y envíe esta nueva imagen.
El "ángulo de matiz" es solo el matiz :
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
Tenga en cuenta que para los valores de escala de grises que técnicamente no tienen un tono, esto devuelve 0, pero está bien.
(Esta fórmula utiliza atan2
la mayoría de las bibliotecas matemáticas incorporadas. R, G, B son de 0 a 1, no de 0 a 255).
- Puede utilizar cualquier formato de archivo de imagen sin pérdida común, así como cualquier biblioteca de imágenes.
- Tome la entrada de stdin o la línea de comando, o escriba una función con argumentos para el nombre del archivo de imagen, x e y, y la longitud máxima.
- La longitud máxima y x e y son siempre enteros no negativos. Puede suponer que x e y están dentro del rango.
- Guarde la imagen de salida con un nombre de su elección o simplemente muéstrela.
- Su implementación no tiene que coincidir exactamente con el fragmento. Unos pocos píxeles en lugares ligeramente diferentes debido a un método de redondeo / cálculo ligeramente diferente está bien. (En casos caóticos, esto podría conducir a curvas que terminan siendo muy diferentes, pero siempre y cuando se vean correctamente visualmente, está bien).
Puntuación
La presentación más pequeña en bytes gana.