Carregue uma imagem nesse snippet de pilha e mova o mouse sobre ela. Uma curva preta que segue o ângulo da tonalidade , começando no ponto do cursor, será desenhada:
<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>
Eu só testei esse snippet no Google Chrome.
Por exemplo, quando o cursor está acima do vermelho, a curva tem uma inclinação de 0 °, mas quando está acima do amarelo, tem uma inclinação de 60 °. A curva continua pelo comprimento especificado, alterando continuamente sua inclinação para corresponder à tonalidade.
Carregue esta imagem e quando você mover o cursor sobre ela, a linha ao redor do cursor deverá fazer uma volta completa no sentido anti-horário:
Este e este são outras imagens nítidas para tentar. (Você precisará salvá-los e carregá-los com o snippet. Eles não podem ser vinculados diretamente devido a restrições de origem cruzada.)
Aqui está uma versão não minificada do snippet:
Desafio
Escreva um programa que faça o que o snippet está fazendo, mas não de maneira interativa. Tire uma imagem e uma coordenada (x, y) nos limites da imagem e um comprimento máximo da curva. Emita a mesma imagem com a curva preta adicionada que segue os ângulos de matiz começando em (x, y) e termina quando atinge o comprimento máximo ou atinge o limite de uma imagem.
Especificamente, inicie a curva em (x, y) e meça o ângulo da tonalidade lá. Vá uma unidade (largura de um pixel) nessa direção, observando que sua nova posição provavelmente não é uma coordenada inteira . Marque outro ponto na curva e mova-se novamente, usando a tonalidade do pixel mais próximo (usando algo como floor
ou round
, não vou verificar isso com precisão). Continue assim até que a curva saia dos limites ou exceda o comprimento máximo. Para finalizar, plote todos os pontos da curva como pixels pretos únicos (novamente, use os pixels mais próximos) sobrepostos na imagem e produza essa nova imagem.
O "ângulo de matiz" é apenas o matiz :
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
Observe que, para valores em escala de cinza que tecnicamente não possuem matiz, isso retorna 0, mas tudo bem.
(Essa fórmula usa a atan2
maioria das bibliotecas matemáticas internas. R, G, B são de 0 a 1, não de 0 a 255.)
- Você pode usar qualquer formato de arquivo de imagem sem perdas comum, bem como quaisquer bibliotecas de imagens.
- Pegue a entrada do stdin ou da linha de comando ou escreva uma função com argumentos para o nome do arquivo de imagem, xey, e o comprimento máximo.
- O comprimento máximo e x e y são sempre números inteiros não negativos. Você pode assumir que xey estão dentro do alcance.
- Salve a imagem de saída com um nome de sua escolha ou simplesmente exiba-a.
- Sua implementação não precisa corresponder exatamente ao snippet. Alguns pixels em locais ligeiramente diferentes devido a um método de arredondamento / cálculo um pouco diferente são bons. (Em casos caóticos, isso pode levar a curvas muito diferentes, mas, desde que pareçam corretas visualmente, tudo bem.)
Pontuação
O menor envio em bytes vence.
fonte
Respostas:
MATLAB, 136
Copiei a maior parte da configuração e coisas do @sanchises, mas, em vez disso, uso
streamline
para calcular e desenhar o caminho. No entanto, antialias a linha e usa interpolação bilinear, em vez do vizinho mais próximo, conforme especificado.fonte
C com SDL,
549516 bytesEu vou começar essa festa! Por alguma razão, tive vontade de tentar jogar golfe hoje à noite. O que vocês fazem é difícil ... Se há uma coisa que eu não vejo neste site, é SDL. Eu posso ter acabado de descobrir o porquê. Esse snippet específico está em conformidade com SDL2 e SDL1.2, mas é atroz. Chamado como
f("imagename.bmp", xcoord, ycoord, max_length);
. Ele salva um arquivo com o mesmo nome dado nos argumentos. A saída parece ser muito semelhante ao trecho de código do OP, mas "mais confusa". Eu posso tentar consertar isso um pouco mais tarde.Aqui está tudo desvendado:
Devo observar que foi tomado cuidado para torná-lo entre plataformas - por uma questão de honestidade, não foi bom codificá-lo para minha máquina, mesmo que ele corte um número substancial de bytes. Ainda assim, sinto que algumas coisas são supérfluas aqui, e analisarei novamente mais tarde.
EDITAR-------
Afinal, isso é saída gráfica ... vou atualizar com imagens que acho interessantes periodicamente.
f("HueTest1.bmp", 270, 40, 200);
f("HueTest2.bmp", 50, 50, 200);
f("HueTest3.bmp", 400, 400, 300);
fonte
Python,
203172Saída de amostra:
Ligue com
f("image.jpg", 400, 400, 300)
Eu desperdicei muitos caracteres para a importação, se alguém tiver sugestões para melhorá-la. Pode não funcionar no 3.0
fonte
sqrt(3) -> 3**.5
:? Não consigo pensar em nada para as importações.MATLAB,
186172O jogo começou ! Chame como
t('YourImage.ext',123,456,100')
, para uma imagem de qualquer tipo que o MATLAB suporte, iniciando em (x, y) = (123.456) e comprimento máximo 100. As posições iniciais não podem estar exatamente nas bordas direita e inferior (isso me custaria dois bytes), para comece no limite, use algo comox=799.99
para começarx=800
. A indexação começa em 1, não em 0.Código:
Revisões:
Ainda usando,line
pois esse é o código mais curto que conheço para produzir um pixel.Mudou a cor de preto para azul, usandoCo
para expandir paraColor
(o que MATLAB faz automaticamente)fonte
x=0
ou sãoy=0
posições potencialmente válidas?function
cabeçalho. O Spec não exigiu indexação com base em zero ou em uma base; portanto, eu estou usando a base de MATLAB, então não,x=0
ouy=0
não é válida neste programa.x=X
ey=Y
válido?Processando, 323 caracteres
Com espaço em branco:
Tenho certeza de que poderia diminuir ainda mais isso, mas funciona por enquanto.
fonte
JavaScript 414
fonte