Celem tego wyzwania jest stworzenie animacji układu napędu łańcuchowego , składającego się z zestawu kół zębatych połączonych ze sobą łańcuchem .
Ogólne wymagania
Twój program otrzyma listę kół zębatych , określonych jako (x, y, radius)
trojaczki. Powstały układ napędowy łańcuch składa się z tych kół zębatych, połączonych ze sobą za pomocą zamkniętego łańcucha napiętego przechodzącej przez każdego z nich, w celu . Twoim celem jest stworzenie nieskończenie zapętlonej animacji pokazującej system w ruchu. Na przykład biorąc pod uwagę dane wejściowe
(0, 0, 16), (100, 0, 16), (100, 100, 12), (50, 50, 24), (0, 100, 12)
, wynik powinien wyglądać mniej więcej tak
.
Układ współrzędnych powinien być taki, aby oś x była skierowana w prawo, a oś y była skierowana w górę. Możesz założyć, że promienie są liczbami parzystymi większymi lub równymi 8 (zobaczymy, dlaczego to ma znaczenie później). Możesz również założyć, że są co najmniej dwa koła łańcuchowe i że koła zębate się nie przecinają . te jednostkiwejścia nie są zbyt krytyczne. Wszystkie przykłady i przypadki testowe w tym poście wykorzystują piksele jako jednostki wejściowe (więc na przykład promień środkowej zębatki na poprzedniej ilustracji wynosi 24 piksele;) staraj się nie odchylać zbytnio od tych jednostek. W pozostałej części wyzwania wielkości przestrzenne są rozumiane jako podane w tych samych jednostkach co dane wejściowe - pamiętaj, aby zachować odpowiednie proporcje! Te wymiary wyjścia powinna być nieco większa niż obwiedni wszystkich kół zębatych, wystarczająco duży, tak że cały system jest widoczny. W szczególności bezwzględne położenia kół łańcuchowych nie powinny wpływać na wydajność; tylko ich względne pozycje powinny (więc na przykład, gdybyśmy przesunęli wszystkie koła łańcuchowe w powyższym przykładzie o tę samą wartość, wynik pozostanie taki sam.)
Łańcuch powinien być styczny do kół łańcuchowych, przez które przechodzi, we wszystkich punktach styku i prosto wszędzie. Łańcuch powinien przechodzić nad kołami łańcuchowymi, tak aby sąsiednie segmenty łańcucha (to znaczy części łańcucha między dwoma kołami łańcuchowymi, które spotykają się na tej samej zębatce) nie przecinały się .
.
Na przykład, podczas gdy lewy system powyżej jest prawidłowy, środkowy nie jest, ponieważ dwa sąsiednie segmenty łańcucha, które przechodzą nad dolną lewą zębatką, przecinają się. Należy jednak pamiętać, że właściwy system jest prawidłowy, ponieważ dwa przecinające się segmenty łańcucha nie sąsiadują ze sobą (ten system jest wytwarzany przez inny wkład niż dwa pozostałe).
Dla uproszczenia (r) możesz założyć, że żadne koło łańcuchowe nie przecina wypukłego kadłuba dwóch sąsiednich kół lub wypukłych kadłubów każdego z sąsiadów i drugiego sąsiada. Innymi słowy, górna zębatka na poniższym schemacie nie może przecinać żadnego z zacienionych obszarów.
Segmenty łańcucha mogą przecinać koła łańcuchowe inne niż te, które mijają (na przykład w ostatnim przypadku testowym). W takim przypadku łańcuch powinien zawsze pojawiać się przed zębami.
Wymagania wizualne
Łańcuch powinien składać się z szeregu ogniw o przemiennych szerokościach. Szerokość wąskiego łącza powinna wynosić około 2, a szerokość szerokiego łącza powinna wynosić około 5. Długość obu typów łączy powinna być w przybliżeniu równa. okresłańcucha, to znaczy całkowita długość szerokiej / wąskiej pary ogniw, powinna być liczbą najbliższą 4π, która odpowiada liczbie całkowitej na długości łańcucha. Na przykład, jeśli długość łańcucha wynosi 1000, wówczas jego okres powinien wynosić 12,5, co jest liczbą najbliższą 4π (12.566 ...), która pasuje do liczby całkowitej (80) na 1000. Ważne jest, aby kropka pasowała do liczby całkowitej liczbę razy, tak aby nie było żadnych artefaktów w miejscu, w którym łańcuch się owija.
Koło łańcuchowe o promieniu R powinno składać się z trzech koncentrycznych części: środkowej osi , która powinna być okręgiem o promieniu około 3; w korpus koła łańcuchowego jest wokół osi, która powinna być w kole o promieniu R - 4,5; oraz obręcz koła łańcuchowego wokół ciała, która powinna być okręgiem o promieniu około
R - 1,5. Obręcz powinna również zawierać zęby koła łańcuchowego , które powinny mieć szerokość około 4; rozmiar i odstępy między zębami powinny odpowiadać rozmiarom ogniw łańcucha, aby były dobrze osadzone.
Okres zębów koła łańcuchowego, to znaczy odległość między dwoma kolejnymi zębami wzdłuż obwodu koła łańcuchowego, powinna odpowiadać okresowi łańcucha. Ponieważ okres wynosi około 4π, a promień koła zębatego ma być równy, okres powinien pasować do obwodu koła zębatego prawie całkowitą liczbę razy, aby nie było żadnych zauważalnych artefaktów w punkcie, w którym zęby zębatki owijają się.
Możesz użyć dowolnej kombinacji kolorów dla łańcucha, różnych części zębatki i tła, o ile można je łatwo rozróżnić . Tło może być przezroczyste. Przykłady w tym poście wykorzystują #202020
łańcuch, #868481
oś i obręcz #646361
koła łańcuchowego oraz korpus koła łańcuchowego.
Wymagania dotyczące animacji
Pierwsza zębatka na liście wejściowej powinno obracać się w prawo ; reszta kół zębatych powinna się odpowiednio obracać. Łańcuch powinien poruszać się z prędkością około 16π (około 50) jednostek na sekundę; szybkość klatek zależy od Ciebie, ale animacja powinna wyglądać wystarczająco płynnie.
Animacja powinna być płynnie zapętlona .
Zgodność
Niektóre wizualne atrybuty i proporcje są celowo określone tylko z grubsza - nie musisz ich dokładnie dopasowywać . Wyjście twojego programu nie musi być repliką pikseli z podanych tu przykładów, ale powinno wyglądać podobnie. W szczególności dokładne proporcje łańcucha i kół łańcuchowych oraz dokładny kształt ogniw łańcucha i zębów koła łańcuchowego są elastyczne.
Najważniejsze punkty do naśladowania to:
- Łańcuch powinien przechodzić nad zębatkami, w kolejności wprowadzania, z właściwego kierunku.
- Łańcuch powinien być styczny do kół łańcuchowych we wszystkich punktach styku.
- Ogniwa łańcucha i zęby kół zębatych powinny dobrze zagłębiać się, przynajmniej do prawidłowego odstępu i fazy.
- Odstęp między ogniwami łańcucha a zębami kół łańcuchowych powinien być taki, aby nie było zauważalnych artefaktów w miejscu, w którym się owijają.
- Koła łańcuchowe powinny obracać się we właściwym kierunku.
- Animacja powinna być płynnie zapętlona.
Na koniec, chociaż technicznie celem tego wyzwania jest napisanie najkrótszego kodu, jeśli masz ochotę być kreatywnym i uzyskać bardziej skomplikowane wyniki, zdecydowanie, idź!
Wyzwanie
Napisz program lub funkcję , pobierając listę kół zębatych i generując odpowiednią animację systemu napędu łańcuchowego, jak opisano powyżej.
Wejście i wyjście
Możesz pobrać dane wejściowe z wiersza poleceń , poprzez STDIN , jako argumenty funkcji lub przy użyciu równoważnej metody . Możesz użyć dowolnego dogodnego formatu danych wejściowych, ale pamiętaj, aby podać go w swoim poście.
Jako wynik możesz wyświetlić animację bezpośrednio , utworzyć plik animacji (np. Animowany GIF) lub sekwencję plików klatek (jednak w tym przypadku istnieje niewielka kara; patrz poniżej). Jeśli używasz pliku wyjściowego, upewnij się, że liczba ramek jest rozsądna (przykłady w tym poście używają bardzo niewielu ramek;) liczba ramek nie musi być minimalna, ale nie powinieneś tworzyć zbyt wielu zbędnych ramek. Jeśli wyprowadzasz sekwencję klatek, pamiętaj o określeniu liczby klatek w poście.
Wynik
To jest golf golfowy . Najkrótsza odpowiedź w bajtach, wygrywa.
+ 10% Kara Jeśli twój program tworzy sekwencję klatek jako wyjście, zamiast bezpośrednio wyświetlać animację lub tworzyć pojedynczy plik animacji, dodaj 10% do swojego wyniku.
Przypadki testowe
Test 1
(0, 0, 26), (120, 0, 26)
Test 2
(100, 100, 60), (220, 100, 14)
Test 3
(100, 100, 16), (100, 0, 24), (0, 100, 24), (0, 0, 16)
Test 4
(0, 0, 60), (44, 140, 16), (-204, 140, 16), (-160, 0, 60), (-112, 188, 12),
(-190, 300, 30), (30, 300, 30), (-48, 188, 12)
Test 5
(0, 128, 14), (46.17, 63.55, 10), (121.74, 39.55, 14), (74.71, -24.28, 10),
(75.24, -103.55, 14), (0, -78.56, 10), (-75.24, -103.55, 14), (-74.71, -24.28, 10),
(-121.74, 39.55, 14), (-46.17, 63.55, 10)
Test 6
(367, 151, 12), (210, 75, 36), (57, 286, 38), (14, 181, 32), (91, 124, 18),
(298, 366, 38), (141, 3, 52), (80, 179, 26), (313, 32, 26), (146, 280, 10),
(126, 253, 8), (220, 184, 24), (135, 332, 8), (365, 296, 50), (248, 217, 8),
(218, 392, 30)
Odpowiedzi:
JavaScript (ES6),
2557191518971681 bajtówTo naprawdę nie jest gra w super- dupera ; jest zminimalizowany - częściowo ręcznie - ale to nic specjalnego. Bez wątpienia byłbym krótszy, gdybym grał bardziej w golfa przed minifikacją, ale spędziłem (więcej niż) wystarczająco dużo czasu na tym.
Edycja: Ok, więc spędziłem na nim więcej czasu i grałem w golfa więcej kodu, zanim go zminimalizowałem (tym razem bardzo ręcznie). Kod nadal korzysta z tego samego podejścia i ogólnej struktury, ale mimo to udało mi się zaoszczędzić 642 bajty. Niezbyt obskurny, jeśli sam to powiem. Prawdopodobnie przegapiłem kilka możliwości oszczędzania bajtów, ale w tym momencie nawet nie jestem pewien, jak to działa. Jedyną rzeczą, która różni się pod względem wyników, jest to, że używa teraz nieco innych kolorów, które można by bardziej precyzyjnie napisać.
Edycja 2 (znacznie później): Zapisano 18 bajtów. Dzięki ConorO'Brien w komentarzach za zwrócenie uwagi na oślepiająco oczywiste, że całkowicie za nim tęskniłem.
Edycja 3: Pomyślałem więc, że opracuję kod źródłowy, ponieważ szczerze mówiąc, nie pamiętałem, jak to zrobiłem, i straciłem niepoprawne wersje. Więc przeszedłem i oto znalazłem kolejne 316 bajtów do zaoszczędzenia poprzez restrukturyzację i trochę mikro golfa.
Powyższa funkcja dołącza do dokumentu element SVG (w tym animacje). Np. Aby wyświetlić 2. przypadek testowy:
Wydaje się działać - przynajmniej tutaj w Chrome.
Wypróbuj go we fragmencie poniżej (kliknięcie przycisków spowoduje narysowanie każdego z przypadków testowych OP).
Pokaż fragment kodu
Kod rysuje zęby łańcucha i koła zębatego jako pociągnięcia przerywane. Następnie używa
animate
elementów do animowaniastroke-dashoffset
atrybutu. Wynikowy element SVG jest samowystarczalny; nie ma animacji opartej na JS ani stylów CSS.Aby wszystko układało się dobrze, pierścień zębów każdego koła zębatego jest w rzeczywistości narysowany jako ścieżka składająca się z dwóch łuków, więc ścieżka może rozpocząć się dokładnie w punkcie stycznym, w którym styka się łańcuch. To sprawia, że dużo łatwiej jest ustawić go w szeregu.
Co więcej, wydaje się, że istnieje wiele błędów zaokrąglania podczas używania pociągnięć kreskowanych SVG. Tak przynajmniej widziałem; im dłuższy łańcuch, tym gorzej będzie się zazębiał z każdym kolejnym biegiem. Aby zminimalizować problem, łańcuch składa się z kilku ścieżek. Każda ścieżka składa się z łukowego segmentu wokół jednego biegu i linii prostej do następnego biegu. Ich przesunięcia są obliczane tak, aby pasowały do siebie. Cienka „wewnętrzna” część łańcucha stanowi jednak tylko jedną pętlę, ponieważ nie jest animowana.
źródło
R=g=>...
<g>
, ale umieszczałem je bezpośrednio w katalogu głównym svg. Znalazłem też miejsce, w którym przekształciłeś flagę zamiatania i flagę dużego łuku z wartości logicznej na1*x
+x
C # 3566 bajtów
W ogóle nie grałem w golfa, aledziała (myślę)Ungolfed w historii edycji.
Używa Magick.NET do renderowania gif.
Klasa P ma funkcję F; Przykład:
źródło
public
modyfikatora przed każdym polem w swojej klasie?using
klauzule lub typy w pełni kwalifikowane, gdy są używane, i należy zauważyć odniesienie do System.Drawing w odpowiedzi (czy to powinno dodać do wyniku, którego nie znam). W każdym razie imponująca odpowiedź.JavaScript (ES6) 1626 bajtów
To rozwiązanie jest wynikiem inżynierii odwrotnej rozwiązania @ Flambino, zamieszczam je z jego zgodą.
Wersja bez golfa:
źródło