Carica un'immagine in questo frammento di stack e sposta il mouse su di essa. Verrà disegnata una curva nera che segue l' angolo di tonalità , a partire dal punto del cursore:
<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>
Ho testato questo frammento solo su Google Chrome.
Ad esempio, quando il cursore si trova sopra il rosso, la curva ha una pendenza di 0 °, ma quando è sopra il giallo, ha una pendenza di 60 °. La curva continua per la lunghezza specificata, cambiando continuamente la sua pendenza per adattarla alla tonalità.
Carica questa immagine e quando fai scorrere il cursore su di essa, la linea proprio attorno al cursore dovrebbe compiere una svolta completa in senso antiorario:
Questa e questa sono altre immagini pulite da provare. (Dovrai salvarli e caricarli con lo snippet. Non possono essere collegati direttamente a causa di vincoli di origine incrociata.)
Ecco una versione non ridotta dello snippet:
Sfida
Scrivi un programma che fa ciò che fa lo snippet, ma non in modo interattivo. Prendi un'immagine e una coordinata (x, y) nei limiti dell'immagine e una lunghezza massima della curva. Stampa la stessa immagine con la curva nera aggiunta che segue gli angoli di tonalità a partire da (x, y) e termina quando ha raggiunto la lunghezza massima o raggiunge un limite dell'immagine.
In particolare, inizia la curva su (x, y) e misura l'angolo di tonalità lì. Vai di un'unità (una larghezza di un pixel) in quella direzione, notando che la tua nuova posizione probabilmente non è una coordinata intera . Segna un altro punto sulla curva e spostati di nuovo, usando la tonalità del pixel più vicino (usando qualcosa come floor
o round
, non lo verificherò con precisione). Continua così fino a quando la curva non supera i limiti o supera la lunghezza massima. Per finire, traccia tutti i punti della curva come singoli pixel neri (di nuovo, usa i pixel più vicini) sovrapposti sull'immagine e genera questa nuova immagine.
L '"angolo di tonalità" è solo la tonalità :
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
Si noti che per i valori in scala di grigi che tecnicamente non hanno una tonalità, questo restituisce 0, ma va bene.
(Questa formula utilizza la atan2
maggior parte delle librerie matematiche integrate. R, G, B sono compresi tra 0 e 1, non tra 0 e 255.)
- È possibile utilizzare qualsiasi formato di file immagine lossless comune nonché librerie di immagini.
- Prendi l'input da stdin o dalla riga di comando o scrivi una funzione con argomenti per il nome del file di immagine, x e ye la lunghezza massima.
- La lunghezza massima e xey sono sempre numeri interi non negativi. Puoi supporre che x e y siano nell'intervallo.
- Salva l'immagine di output con un nome a tua scelta o semplicemente visualizzala.
- L'implementazione non deve corrispondere esattamente allo snippet. Alcuni pixel in posizioni leggermente diverse a causa di un metodo di arrotondamento / calcolo leggermente diverso vanno bene. (In casi caotici questo potrebbe portare a curve che finiscono per essere sostanzialmente diverse, ma purché appaiano visivamente corrette, va bene.)
punteggio
Vince il più piccolo invio in byte .