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.
fuente
Respuestas:
MATLAB, 136
Copié la mayor parte de la configuración y similares de @sanchises, pero en su lugar uso
streamline
para calcular y dibujar la ruta. Sin embargo, hace antialias en la línea y usa interpolación bilineal, en lugar de la vecina más cercana como se especifica.fuente
C con SDL,
549516 bytes¡Comenzaré esta fiesta! Por alguna razón, tuve ganas de probar suerte en el golf esta noche. Lo que ustedes hacen es difícil ... Si hay algo que no veo en este sitio, es SDL. Puede que haya descubierto por qué. Este fragmento en particular cumple con SDL2 y SDL1.2, pero es atroz. Llamado así
f("imagename.bmp", xcoord, ycoord, max_length);
. Guarda un archivo con el mismo nombre que se da en los argumentos. La salida parece ser muy similar al fragmento de código del OP, pero "más difusa". Puedo tratar de arreglar esto un poco más tarde.Aquí está todo desvelado:
Debo tener en cuenta que se tomó la precaución de hacerlo multiplataforma: en aras de la honestidad, no me sentí bien codificarlo para mi máquina, incluso si cortaba una cantidad sustancial de bytes. Aún así, siento que un par de cosas son superfluas aquí, y lo volveré a ver más tarde.
EDITAR-------
Esta es una salida gráfica, después de todo ... actualizaré con imágenes que encuentro interesantes periódicamente.
f("HueTest1.bmp", 270, 40, 200);
f("HueTest2.bmp", 50, 50, 200);
f("HueTest3.bmp", 400, 400, 300);
fuente
Pitón,
203172Salida de muestra:
Llamar con
f("image.jpg", 400, 400, 300)
He desperdiciado muchos caracteres para la importación, si alguien tiene sugerencias para mejorarlo. Puede no funcionar en 3.0
fuente
sqrt(3) -> 3**.5
:? Sin embargo, no puedo pensar en nada para las importaciones.MATLAB,
186172El juego está en marcha! Llame como
t('YourImage.ext',123,456,100')
, para obtener una imagen de cualquier tipo que MATLAB admita, comenzando en (x, y) = (123,456) y longitud máxima 100. Las posiciones iniciales no pueden ser exactamente en los bordes derecho e inferior (eso me costaría dos bytes), por lo que comenzar en el borde, usar algo comox=799.99
comenzar enx=800
. La indexación comienza en 1, no en 0.Código:
Revisiones
Todavía lo usoline
porque ese es el código más corto que conozco para producir un píxel.Cambió el color de negro a azul, usandoCo
para expandir aColor
(lo que MATLAB hace automáticamente)fuente
x=0
o sony=0
posiciones potencialmente válidas?function
encabezado. Las especificaciones no requerían una indexación basada en cero o en una, por lo que estoy usando MATLAB de una base, por lo que no,x=0
oy=0
no es válido en este programa.x=X
yy=Y
válido en su lugar?Procesamiento, 323 caracteres
Con espacios en blanco:
Estoy seguro de que podría acortar esto aún más, pero funciona por ahora.
fuente
JavaScript 414
fuente