Załaduj obraz do tego fragmentu stosu i przesuń nad nim kursor myszy. Narysowana zostanie czarna krzywa, która podąża za kątem barwy , zaczynając od punktu kursora:
<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>
Ten fragment kodu przetestowałem tylko w Google Chrome.
Na przykład, gdy kursor znajduje się powyżej czerwonego, krzywa ma nachylenie 0 °, ale gdy jest powyżej żółtego, ma nachylenie 60 °. Krzywa jest kontynuowana dla określonej długości, stale zmieniając jej nachylenie, aby dopasować do odcienia.
Załaduj ten obraz, a kiedy przesuniesz na nim kursor, linia wokół kursora powinna wykonać pełny obrót w lewo:
To i to inne fajne obrazy do wypróbowania. (Musisz je zapisać, a następnie załadować za pomocą fragmentu. Nie można ich bezpośrednio połączyć z powodu ograniczeń krzyżowych.)
Oto niezamknięta wersja fragmentu:
Wyzwanie
Napisz program, który robi to, co robi fragment kodu, ale nie interaktywnie. Zrób zdjęcie i współrzędne (x, y) w granicach obrazu oraz maksymalną długość krzywej. Wyprowadź ten sam obraz z dodaną czarną krzywą, która podąża za kątami odcienia, zaczynając od (x, y) i kończy się, gdy osiągnie maksymalną długość lub osiągnie granicę obrazu.
W szczególności rozpocznij krzywą od (x, y) i zmierz tam kąt barwy. Idź o jedną jednostkę (szerokość jednego piksela) w tym kierunku, zauważając, że twoja nowa pozycja najprawdopodobniej nie jest współrzędną całkowitą . Zaznacz kolejny punkt na krzywej i rusz się ponownie, używając odcienia z najbliższego piksela (używając czegoś w rodzaju floor
lub round
, nie będę tego dokładnie sprawdzać). Kontynuuj w ten sposób, aż krzywa wyjdzie poza granice lub przekroczy maksymalną długość. Aby zakończyć, wykreśl wszystkie punkty krzywej jako pojedyncze czarne piksele (ponownie użyj najbliższych pikseli) nałożone na obraz i wyślij ten nowy obraz.
„Kąt odcienia” to tylko odcień :
hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)
Zauważ, że dla wartości w skali szarości, które technicznie nie mają odcienia, zwraca 0, ale to jest w porządku.
(Ta formuła wykorzystuje atan2
większość wbudowanych bibliotek matematycznych. R, G, B mają wartość od 0 do 1, a nie od 0 do 255.)
- Możesz użyć dowolnego popularnego formatu plików bezstratnych, a także dowolnych bibliotek obrazów.
- Weź dane wejściowe ze standardowego wiersza poleceń lub wiersza poleceń albo napisz funkcję z argumentami nazwy pliku obrazu, xiy oraz maksymalnej długości.
- Maksymalna długość i xiy są zawsze liczbami całkowitymi nieujemnymi. Możesz założyć, że xiy są w zakresie.
- Zapisz obraz wyjściowy z wybraną nazwą lub po prostu go wyświetl.
- Twoja implementacja nie musi dokładnie pasować do fragmentu. Kilka pikseli w nieco różnych miejscach ze względu na nieco inną metodę zaokrąglania / obliczania jest w porządku. (W chaotycznych przypadkach może to prowadzić do krzywych, które kończą się zasadniczo inaczej, ale dopóki wyglądają poprawnie wizualnie, jest w porządku).
Punktacja
Najmniejsze przesłanie w bajtach wygrywa.
źródło
Odpowiedzi:
MATLAB, 136
Skopiowałem większość ustawień i takie z @sanchises, ale zamiast tego używam
streamline
do obliczania i rysowania ścieżki. Wykonuje jednak antyializację linii i używa interpolacji dwuliniowej, a nie określonego najbliższego sąsiada.źródło
C z SDL,
549516 bajtówZacznę tę imprezę! Z jakiegoś powodu chciałem dziś wieczorem spróbować swoich sił w golfie. To, co robicie, jest trudne ... Jeśli jest jedna rzecz, której nie widzę na tej stronie, to SDL. Być może właśnie dowiedziałem się, dlaczego. Ten konkretny fragment kodu jest zgodny zarówno z SDL2, jak i SDL1.2, ale jest okropny. Nazywa się jak
f("imagename.bmp", xcoord, ycoord, max_length);
. Zapisuje plik o takiej samej nazwie jak podano w argumentach. Dane wyjściowe wydają się bardzo podobne do fragmentu kodu OP, ale „bardziej skomplikowane”. Może spróbuję to naprawić nieco później.Tutaj wszystko się rozwiązuje:
Powinienem zauważyć, że zadbano o to, aby był on wieloplatformowy - w trosce o uczciwość nie było dobrze, aby kodować go na stałe dla mojego komputera, nawet jeśli odciął on znaczną liczbę bajtów. Mimo to wydaje mi się, że kilka rzeczy jest tutaj zbytecznych i przyjrzę się temu później.
EDYTOWAĆ-------
W końcu to wyjście graficzne IS ... Będę aktualizować obrazami, które uważam za interesujące okresowo.
f("HueTest1.bmp", 270, 40, 200);
f("HueTest2.bmp", 50, 50, 200);
f("HueTest3.bmp", 400, 400, 300);
źródło
Python,
203172Przykładowe dane wyjściowe:
Zadzwoń z
f("image.jpg", 400, 400, 300)
Zmarnowałem wiele znaków na import, jeśli ktoś ma sugestie, aby to poprawić. Może nie działać w wersji 3.0
źródło
sqrt(3) -> 3**.5
? Nie mogę jednak wymyślić niczego dla importu.MATLAB,
186172Gra jest włączona ! Call as
t('YourImage.ext',123,456,100')
, dla obrazu dowolnego typu MATLAB-a, zaczynającego się od (x, y) = (123 456) i maksymalnej długości 100. Pozycje początkowe nie mogą znajdować się dokładnie na prawej i dolnej krawędzi (kosztowałoby mnie to dwa bajty), więc zacznij od krawędzi, użyj czegoś takiego jakx=799.99
na początekx=800
. Indeksowanie rozpoczyna się od 1, a nie od 0.Kod:
Rewizje:
Nadal używam,line
ponieważ jest to najkrótszy kod, jaki znam, aby wytworzyć piksel.Zmieniłem kolor z czarnego na niebieski, używającCo
do rozwinięciaColor
(co MATLAB robi automatycznie)źródło
x=0
luby=0
potencjalnie ważne pozycje?function
nagłówka. Specyfikacja nie wymagała indeksowania zera ani zera, więc używam MATLAB-a, więc niex=0
luby=0
nie jest poprawna w tym programie.x=X
iy=Y
zamiast tego ważne?Przetwarzanie, 323 znaków
Z białymi znakami:
Jestem pewien, że mógłbym to jeszcze skrócić, ale na razie działa.
źródło
JavaScript 414
źródło