Chargez une image dans cet extrait de pile et déplacez votre souris dessus. Une courbe noire qui suit l' angle de teinte , en commençant au point du curseur, sera dessinée:
<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>
Je n'ai testé cet extrait que dans Google Chrome.
Par exemple, lorsque le curseur est au-dessus du rouge, la courbe a une pente de 0 °, mais lorsqu'elle est au-dessus du jaune, elle a une pente de 60 °. La courbe continue sur la longueur spécifiée, changeant continuellement sa pente pour correspondre à la teinte.
Chargez cette image et lorsque vous déplacez le curseur dessus, la ligne juste autour du curseur doit faire un tour complet dans le sens antihoraire:
Ceci et ce sont d'autres images soignées à essayer. (Vous devrez les enregistrer, puis les charger avec l'extrait de code. Ils ne peuvent pas être directement liés en raison de contraintes d'origine croisée.)
Voici une version non réduite de l'extrait:
Défi
Écrivez un programme qui fait ce que l'extrait fait, mais pas de manière interactive. Prenez une image et une coordonnée (x, y) dans les limites de l'image et une longueur de courbe maximale. Sortez la même image avec la courbe noire ajoutée qui suit les angles de teinte commençant à (x, y) et se termine lorsqu'elle a atteint la longueur maximale ou atteint une limite d'image.
Plus précisément, commencez la courbe à (x, y) et mesurez l'angle de teinte à cet endroit. Allez d'une unité (largeur d'un pixel) dans cette direction, en notant que votre nouvelle position n'est probablement pas une coordonnée entière . Marquez un autre point sur la courbe et déplacez-vous à nouveau, en utilisant la teinte du pixel le plus proche (en utilisant quelque chose comme floor
ou round
, je ne vérifierai pas cela précisément). Continuez comme ceci jusqu'à ce que la courbe sorte des limites ou dépasse la longueur maximale. Pour terminer, tracez tous les points de la courbe sous la forme de pixels noirs uniques (à nouveau, utilisez les pixels les plus proches) superposés sur l'image, et sortez cette nouvelle image.
"L'angle de teinte" est juste la teinte :
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
Notez que pour les valeurs de niveaux de gris qui n'ont techniquement pas de teinte, cela renvoie 0, mais c'est très bien.
(Cette formule utilise la atan2
plupart des bibliothèques mathématiques intégrées. R, G, B sont de 0 à 1, pas de 0 à 255.)
- Vous pouvez utiliser n'importe quel format de fichier d'image sans perte commun ainsi que toutes les bibliothèques d'images.
- Prenez l'entrée de stdin ou de la ligne de commande, ou écrivez une fonction avec des arguments pour le nom du fichier image, x et y, et la longueur maximale.
- La longueur maximale et x et y sont toujours des entiers non négatifs. Vous pouvez supposer que x et y sont dans la plage.
- Enregistrez l'image de sortie avec un nom de votre choix ou affichez-la simplement.
- Votre implémentation ne doit pas nécessairement correspondre exactement à l'extrait de code. Quelques pixels à des endroits légèrement différents en raison d'une méthode d'arrondi / de calcul légèrement différente conviennent. (Dans les cas chaotiques, cela pourrait conduire à des courbes qui finissent par être très différentes, mais tant qu'elles semblent correctes visuellement, c'est bien.)
Notation
La plus petite soumission en octets gagne.
la source
Réponses:
MATLAB, 136
Copié la plupart de la configuration et autres de @sanchises, mais j'utilise à la place
streamline
pour calculer et tracer le chemin. Cependant, il anticrénalise la ligne et utilise une interpolation bilinéaire, plutôt que le plus proche voisin comme spécifié.la source
C avec SDL,
549516 octetsJe vais commencer cette fête! Pour une raison quelconque, j'avais envie de m'essayer au golf ce soir. Ce que vous faites est difficile ... S'il y a une chose que je ne vois pas sur ce site, c'est SDL. Je viens peut-être de découvrir pourquoi. Cet extrait particulier est conforme à la fois à SDL2 et SDL1.2, mais est atroce. Appelé comme
f("imagename.bmp", xcoord, ycoord, max_length);
. Il enregistre un fichier avec le même nom que celui indiqué dans les arguments. La sortie semble être très similaire à l'extrait de code de l'OP, mais "plus floue". Je vais peut-être essayer de résoudre ce problème un peu plus tard.Ici, tout est démêlé:
Je dois noter que le soin a été pris pour le rendre multiplateforme - dans un souci d'honnêteté, il n'était pas bon de le coder en dur pour ma machine, même s'il coupait un nombre substantiel d'octets. Pourtant, j'ai l'impression que certaines choses sont superflues ici, et je vais y revenir plus tard.
ÉDITER-------
Cette sortie graphique EST, après tout ... Je vais mettre à jour avec des images que je trouve périodiquement intéressantes.
f("HueTest1.bmp", 270, 40, 200);
f("HueTest2.bmp", 50, 50, 200);
f("HueTest3.bmp", 400, 400, 300);
la source
Python,
203172Exemple de sortie:
Appeler avec
f("image.jpg", 400, 400, 300)
J'ai perdu beaucoup de caractères pour l'importation, si quelqu'un a des suggestions pour l'améliorer. Peut ne pas fonctionner en 3.0
la source
sqrt(3) -> 3**.5
? Je ne peux penser à rien pour les importations cependant.MATLAB,
186172Le jeu est lancé ! Appelez as
t('YourImage.ext',123,456,100')
, pour une image de tout type prise en charge par MATLAB, à partir de (x, y) = (123,456) et de la longueur maximale 100. Les positions initiales ne peuvent pas être exactement sur les bords droit et inférieur (cela me coûterait deux octets), donc pour commencer sur le bord, utiliser quelque chose commex=799.99
pour commencerx=800
. L'indexation commence à 1, pas à 0.Code:
Révisions:
J'utilisetoujoursline
car c'est le code le plus court que je connaisse pour produire un pixel.Changement de la couleur du noir au bleu, en utilisantCo
pour développerColor
(ce que MATLAB fait automatiquement)la source
x=0
ouy=0
potentiellement valides?function
tête. Spec ne nécessitait pas d'indexation à base zéro ou à base unique, j'utilise donc MATLAB à base unique, donc non,x=0
ouy=0
n'est pas valide dans ce programme.x=X
ety=Y
valable à la place?Traitement, 323 caractères
Avec espace:
Je suis sûr que je pourrais encore raccourcir cela, mais cela fonctionne pour l'instant.
la source
JavaScript 414
la source