Laden Sie ein Bild in dieses Stapel-Snippet und bewegen Sie die Maus darüber. Eine schwarze Kurve, die dem Farbtonwinkel ab dem Cursorpunkt folgt , wird gezeichnet:
<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>
Ich habe dieses Snippet nur in Google Chrome getestet.
Befindet sich der Cursor beispielsweise über Rot, weist die Kurve eine Neigung von 0 ° auf. Befindet er sich jedoch über Gelb, weist sie eine Neigung von 60 ° auf. Die Kurve wird für die angegebene Länge fortgesetzt, wobei die Steigung kontinuierlich geändert wird, um sie an den Farbton anzupassen.
Laden Sie dieses Bild und wenn Sie den Mauszeiger darüber bewegen, sollte die Linie um den Mauszeiger eine vollständige Drehung gegen den Uhrzeigersinn ausführen:
Dies und das sind andere nette Bilder zum Ausprobieren. (Sie müssen sie speichern und dann mit dem Snippet laden. Sie können aufgrund herkunftsübergreifender Einschränkungen nicht direkt verknüpft werden.)
Hier ist eine nicht verkleinerte Version des Snippets:
Herausforderung
Schreiben Sie ein Programm, das das tut, was das Snippet tut, nur nicht interaktiv. Nehmen Sie ein Bild und eine (x, y) Koordinate in den Bildgrenzen sowie eine maximale Kurvenlänge auf. Das gleiche Bild mit der hinzugefügten schwarzen Kurve ausgeben, die den Farbtonwinkeln ab (x, y) folgt und endet, wenn die maximale Länge erreicht ist oder eine Bildgrenze erreicht.
Beginnen Sie die Kurve bei (x, y) und messen Sie dort den Farbtonwinkel. Gehen Sie eine Einheit (ein Pixel breit) in diese Richtung und beachten Sie, dass Ihre neue Position höchstwahrscheinlich keine Ganzzahlkoordinate ist . Markieren Sie einen anderen Punkt auf der Kurve und bewegen Sie sich erneut mit dem Farbton vom nächsten Pixel (mit etwas wie floor
oder round
, ich werde dies nicht genau überprüfen). Fahren Sie so fort, bis die Kurve außerhalb der Grenzen liegt oder die maximale Länge überschreitet. Zeichnen Sie zum Abschluss alle Kurvenpunkte als einzelne schwarze Pixel (verwenden Sie wieder die nächsten Pixel), die über dem Bild liegen, und geben Sie dieses neue Bild aus.
Der "Farbtonwinkel" ist nur der Farbton :
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
Beachten Sie, dass für Graustufenwerte, die technisch gesehen keinen Farbton haben, 0 zurückgegeben wird, dies aber in Ordnung ist.
(Diese Formel verwendet atan2
die meisten eingebauten Mathematikbibliotheken. R, G, B liegen zwischen 0 und 1, nicht zwischen 0 und 255.)
- Sie können jedes gängige verlustfreie Bilddateiformat sowie alle Bildbibliotheken verwenden.
- Nehmen Sie Eingaben von stdin oder der Befehlszeile entgegen oder schreiben Sie eine Funktion mit Argumenten für den Namen der Bilddatei, x und y und die maximale Länge.
- Die maximale Länge und x und y sind immer nichtnegative ganze Zahlen. Sie können davon ausgehen, dass sich x und y im Bereich befinden.
- Speichern Sie das Ausgabebild unter einem Namen Ihrer Wahl oder zeigen Sie es einfach an.
- Ihre Implementierung muss nicht genau mit dem Snippet übereinstimmen. Ein paar Pixel an leicht unterschiedlichen Stellen aufgrund einer leicht unterschiedlichen Rundungs- / Berechnungsmethode sind in Ordnung. (In chaotischen Fällen kann dies dazu führen, dass Kurven sich stark voneinander unterscheiden. Solange sie jedoch optisch korrekt aussehen, ist dies in Ordnung.)
Wertung
Die kleinste Einsendung in Bytes gewinnt.