Математика, 193 183 177 173 169 166 байт
Так, математика! Я будую регіон, який задовольняє певний (досить складний) набір нерівностей:
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->#]&
Використання e[height]
, наприклад e[100]
:
Або e[200]
:
Ви можете помітити, що гостріші краї трохи закруглені. Це тому, що область може бути побудована тільки за допомогою вибірки точок у просторі, а Mathematica не вибірку кожного пікселя за замовчуванням. Роздільну здатність вибірки можна збільшити, додавши інший варіант PlotPoints->#
(для якого використовується один зразок на піксель), який додає 14 символів . Я не рекомендую запускати його з цим варіантом, оскільки це значно збільшує час виконання та ледве збільшує візуальну привабливість за межами #/4
. Отже, (після затвердження ОП) він не включається до балу.
Ось злегка незворушена версія:
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
]
);
Зауважте, що у версії для гольфу я масштабував систему координат в 2 рази, щоб уникнути .5
s, але виявляється, що кількість символів насправді однакова.
Ось пояснення того, як я опрацював формулу. Я поділив фігуру на дві області. Одна містить кільце та смуги і відрізається праворуч BCDE
нахилом та ліворуч з ухилами IJ
та GH
схилами (докладніше про це пізніше). Інше містить те саме кільце, але воно просто відрізане в координаті точки xD
. Умови для двох регіонів поєднуються з ||
, що виступає тут як встановлений союз.
Кільце просто визначається як 5 < r < 6
, де r
відстань від початку. r²
хоч і легше пропрацювати ( x²+y²
), тому я використовую, 25 < x² + y² < 36
щоб отримати всі очки на рингу.
Смуги знаходяться між ±.5
і ±1.5
. Ми можемо обробляти обидві смуги одночасно, приймаючи модуль y , тому смуги (нескінченної довжини) просто виконуються .5 < |y| < 1.5
. Знову ж таки, щоб взяти з’єднання смуг і кільця, я просто використовую ||
.
Цікаво, напевно, як отримати "маски", хоча. Точка D
має x координату 5 cos 40°
, тому маска, що береже нижній край (поєднується лише з кільцем), є просто x < 5 cos 40°
. Це можна застосувати через встановлений перетин, який перекладається &&
в логіку.
Інші маски - справді хитра частина. Спочатку давайте розберемось по схилу BCDE
. Ми можемо легко побудувати точки C
і D
, як (0, -6)
і 5 (cos 40°, sin 40°)
, відповідно. Вектор, що вказує уздовж лінії, тоді справедливий D - C = (5 cos 40°, 5 sin 40° + 6)
. Щоб застосувати маску праворуч, мені потрібно лише з’ясувати, чи лежить точка ліворуч або праворуч від цієї лінії (назвемо вектор лінійки p
). Я можу це зрозуміти, взявши вектор C
до моєї цікавої точки та спроектувавши його на вектор, перпендикулярний до p
. Знак проекції підкаже мені, на якій стороні знаходиться точка. Отримати перпендикулярний вектор досить просто в 2D: переверніть координати і поверніть знак однієї з них. Це змінна d
в моєму коді:(-5 sin 40° - 6, 5 cos 40°)
. Вектор від C
точки до інтересу q = (x, y)
є q - C = (x, y + 6)
. Проекція - це просто скалярний добуток (або крапковий продукт) між q
і d
. Те, як я вибрав d
це, трапляється вказувати ліворуч, тому я хочу d.(q-C) > 0
. Ця умова стосується правої маски.
Для лівої маски я можу використовувати в основному ту саму ідею. Нахил однаковий і тому так і є d
. Мені просто потрібно змістити свою точку від нижнього лівого кута смуг замість від C
. Вони мають координати (-7.5, 0.5)
(верхня смуга) та (-7.5, -1.5)
(нижня смуга). Отже, це вимагатиме створення двох незалежних правил для двох смуг. Однак зауважте, що всі точки, на які впливає нижня маска, знаходяться в нижній смузі і, отже, мають від'ємний y . І всі точки, на які впливає верхня маска, мають позитивний у . Так що я можу просто перемкнути моє зміщення з допомогою Sign[y]
яких є 1
для позитивних і -1
для негативних y
. Так стає моєю точкою зміщення(-7.5, -0.5 + Sign[y])
. Інакше маска працює так само, як і права маска. Звичайно, цього разу прогноз повинен бути негативним. Отже, наївно це було б щось на кшталт RH-projection > 0 && LH-projection < 0
(що теж було у мене в коді). Але ми можемо скоротити це, оскільки множення додатного і від’ємного числа має дати негативне число, тож це просто RH * LH < 0
(де RH
і LH
є відповідні прогнози).
Це воно. Зведення все це призводить до такої логічної структури:
(
(is_in_circle || is_in_stripe)
&&
is_between_left_and_right_mask
)
||
(
is_in_circle && left_of_edge
)
Щоб було зрозуміло, координати в моєму поясненні стосуються схеми побудови, наведеної в виклику. Як було сказано вище, мій код насправді помножує їх на 2
- я змінив його для збереження байтів, але кількість байтів насправді однакова, і я не міг потурбуватися відновити зміни знову. Також цілі виглядають приємніше.