Mathematica, 193 183 177 173 169 166 bajtów
Tak, matematyka! Planuję region, który spełnia pewien (raczej skomplikowany) zestaw nierówności:
e=RegionPlot[(1<Abs@y<3||c)&&{x,y+12}.(d=2{-5Sin@40°-6,m=5Cos@40°})*{x+15,y+1-2Sign@y}.d<0||c&&x<2m/.c->100<x^2+y^2<144,{x,-15,9},{y,-12,12},Frame->0>1,ImageSize->#]&
Zastosowanie to e[height]np . e[100]:

Lub e[200]:

Można zauważyć, że ostrzejsze krawędzie są lekko zaokrąglone. Wynika to z faktu, że region można wykreślić tylko poprzez próbkowanie punktów w przestrzeni, a Mathematica domyślnie nie próbkuje każdego piksela. Rozdzielczość próbkowania można zwiększyć, dodając inną opcję PlotPoints->#(która wykorzystuje jedną próbkę na piksel), która dodaje 14 znaków . Nie polecam uruchamiania go z tą opcją, ponieważ znacznie wydłuża czas działania i ledwo zwiększa atrakcyjność wizualną #/4. W związku z tym (po zatwierdzeniu PO) nie jest uwzględniany w partyturze.
Oto nieco niestosowana wersja:
e[height_] := (
angle = 40°;
d = {-5 Sin[angle] - 6, 5 Cos[angle]};
RegionPlot[
(Abs[y] > .5 && Abs[y] < 1.5
||
r > 25 && r < 36)
&&
{x, y + 6}.d > 0
&&
{x + 7.5, y + .5 - Sign[y]}.d < 0
||
r > 25 && r < 36 && x < 5 Cos[angle]
/. r -> x^2 + y^2
,
{x, -7.5, 4.5},
{y, -6, 6},
Frame -> False,
ImageSize -> height
]
);
Zauważ, że w wersji golfowej przeskalowałem układ współrzędnych 2 razy, aby uniknąć .5s, ale okazuje się, że liczba znaków jest w rzeczywistości identyczna.
Oto wyjaśnienie, jak opracowałem formułę. Podzieliłem kształt na dwa regiony. Jeden zawiera pierścień i paski i jest odcięty w prawo wraz ze BCDEzboczem, a w lewo ze zboczami IJi GH(więcej na ten temat później). Drugi zawiera ten sam pierścień, ale jest po prostu odcięty na współrzędnej x punktu D. Warunki dla dwóch regionów są łączone ||, co działa tutaj jak ustalony związek.
Pierścień jest po prostu zdefiniowany jako 5 < r < 6, gdzie rjest odległość od początku. r²jest łatwiejsze do wypracowania ( x²+y²), więc używam, 25 < x² + y² < 36aby uzyskać wszystkie punkty w ringu.
Paski są pomiędzy ±.5i ±1.5. Możemy obsłużyć oba paski w tym samym czasie, przyjmując moduł y , więc paski (o nieskończonej długości) po prostu się spełniają .5 < |y| < 1.5. Ponownie, aby wziąć połączenie pasków i pierścienia, po prostu używam ||.
Ciekawe jest jednak to, jak zdobyć „maski”. Punkt Dma współrzędną x5 cos 40° , więc maska dbająca o dolną krawędź (w połączeniu tylko z pierścieniem) jest po prostu x < 5 cos 40°. Można to zastosować poprzez ustawienie przecięcia, co przekłada się &&na logikę.
Inne maski są naprawdę trudną częścią. Najpierw zdobądźmy nachylenie BCDE. Możemy łatwo konstruować punkty Ci odpowiednio Djako (0, -6)i 5 (cos 40°, sin 40°). Wektor wskazujący wzdłuż linii jest wtedy sprawiedliwy D - C = (5 cos 40°, 5 sin 40° + 6). Aby zastosować maskę po prawej stronie, muszę tylko dowiedzieć się, czy punkt znajduje się po lewej lub po prawej stronie tej linii (nazwijmy wektor linii p). Mogę to rozgryźć, biorąc wektor z Cmojego interesującego miejsca i rzutując go na wektor prostopadły do p. Znak projekcji powie mi, po której stronie jest punkt. Uzyskanie wektora prostopadłego jest dość proste w 2D: odwróć współrzędne i odwróć znak jednego z nich. To jest zmienna dw moim kodzie:(-5 sin 40° - 6, 5 cos 40°). Wektor od Cdo punktu zainteresowania q = (x, y)to q - C = (x, y + 6). Projekcja to po prostu iloczyn skalarny (lub iloczyn skalarny) pomiędzy qi d. Sposób, w jaki to wybrałem d, wskazuje na lewo, więc chcę d.(q-C) > 0. Ten warunek dotyczy maski po prawej stronie.
W przypadku maski po lewej stronie mogę użyć zasadniczo tego samego pomysłu. Nachylenie jest takie samo i dlatego tak jest d. Muszę tylko przesunąć punkt od lewego dolnego rogu pasków zamiast od C. Mają one współrzędne (-7.5, 0.5)(górny pasek) i (-7.5, -1.5)(dolny pasek). To wymagałoby dwóch niezależnych reguł dla dwóch pasków. Należy jednak pamiętać, że wszystkie punkty dotknięte dolną maską znajdują się w dolnym pasku, a zatem mają ujemne y . Wszystkie punkty dotknięte górną maską mają dodatnie y . Więc mogę po prostu zmienić swoje przesunięcie, używając tego, Sign[y]który jest 1na plus i -1na minus y. Więc mój punkt przesunięcia staje się(-7.5, -0.5 + Sign[y]). W przeciwnym razie maska działa tak jak maska po prawej stronie. Oczywiście tym razem projekcja musi być negatywna. Więc naiwnie to by było coś takiego RH-projection > 0 && LH-projection < 0(co też pierwotnie miałem w kodzie). Ale możemy to skrócić, ponieważ pomnożenie liczby dodatniej i ujemnej musi dać liczbę ujemną, więc po prostu RH * LH < 0(gdzie RHi gdzie LHsą odpowiednie prognozy).
Otóż to. Złożenie tego wszystkiego razem prowadzi do następującej logicznej struktury:
(
(is_in_circle || is_in_stripe)
&&
is_between_left_and_right_mask
)
||
(
is_in_circle && left_of_edge
)
Dla jasności współrzędne w moim wyjaśnieniu odnoszą się do schematu konstrukcyjnego podanego w wyzwaniu. Jak wspomniano powyżej, mój kod mnoży je wszystkie przez 2- Zmieniłem go, aby zapisać bajty, ale liczba bajtów jest w rzeczywistości identyczna i nie mogłem sobie pozwolić na ponowne cofnięcie zmiany. Także liczby całkowite wyglądają ładniej.