Mathematica, 193 183 177 173 169 166 Bytes
Ja, Mathe! Ich zeichne die Region, die eine bestimmte (ziemlich komplizierte) Menge von Ungleichungen befriedigt:
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->#]&
Verwendung ist e[height]
zB e[100]
:
Oder e[200]
:
Möglicherweise stellen Sie fest, dass die schärferen Kanten leicht abgerundet sind. Dies liegt daran, dass der Bereich nur durch Abtasten der Punkte im Raum dargestellt werden kann und Mathematica standardmäßig nicht jedes Pixel abtastet. Die Abtastauflösung kann erhöht werden, indem eine weitere Option hinzugefügt wird PlotPoints->#
(bei der ein Abtastwert pro Pixel verwendet wird), bei der 14 Zeichen hinzugefügt werden . Ich empfehle nicht, es mit dieser Option auszuführen, da dies die Laufzeit erheblich verlängert und die visuelle Attraktivität darüber hinaus kaum erhöht #/4
. Daher ist es (nach Genehmigung des OP) nicht in der Punktzahl enthalten.
Hier ist eine leicht ungolfederte Version:
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
]
);
Beachten Sie, dass ich in der Golf-Version das Koordinatensystem um den Faktor 2 skaliert habe, um das .5
s zu vermeiden. Es stellt sich jedoch heraus, dass die Zeichenanzahl tatsächlich identisch ist.
Hier ist eine Erklärung, wie ich die Formel ausgearbeitet habe. Ich habe die Form in zwei Regionen unterteilt. Eine enthält den Ring und die Streifen und nach rechts mit der abgeschnittenen BCDE
Steigung und nach links mit der IJ
und GH
Neigungen (dazu später mehr). Der andere enthält den gleichen Ring, wird aber einfach an der x- Koordinate des Punktes abgeschnitten D
. Die Bedingungen für die beiden Regionen werden mit ||
denen kombiniert , die hier als feste Einheit fungieren.
Der Ring ist definiert als 5 < r < 6
, wo r
ist der Abstand vom Ursprung. r²
ist allerdings einfacher zu trainieren ( x²+y²
), also benutze ich 25 < x² + y² < 36
, um alle Punkte im Ring zu bekommen.
Die Streifen sind zwischen ±.5
und ±1.5
. Wir können beide Streifen gleichzeitig behandeln, indem wir den Modul von y nehmen , so dass die Streifen (von unendlicher Länge) gerade erfüllen .5 < |y| < 1.5
. Nochmals, um die Vereinigung der Streifen und des Rings zu nehmen, benutze ich nur ||
.
Das Interessante ist wahrscheinlich, wie man an die "Masken" kommt. Der Punkt D
hat eine x- Koordinate von 5 cos 40°
, sodass die Maske, die sich um die untere Kante kümmert (nur in Kombination mit dem Ring), gerade ist x < 5 cos 40°
. Dies kann über eine gesetzte Schnittmenge erfolgen, die sich &&
in Logik umsetzt.
Die anderen Masken sind der wirklich knifflige Teil. Lassen Sie uns zuerst die Steigung von BCDE
. Wir können leicht Punkte C
und D
als (0, -6)
bzw. konstruieren 5 (cos 40°, sin 40°)
. Der Vektor, der entlang der Linie zeigt, ist dann gerade D - C = (5 cos 40°, 5 sin 40° + 6)
. Um die Maske rechts anzuwenden, muss ich nur herausfinden, ob ein Punkt links oder rechts von dieser Linie liegt (nennen wir den Linienvektor p
). Ich kann das herausfinden, indem ich den Vektor von C
zu meinem interessierenden Punkt nehme und ihn auf einen Vektor senkrecht zu projiziere p
. Das Zeichen der Projektion sagt mir, auf welcher Seite sich der Punkt befindet. Das Erhalten des senkrechten Vektors ist in 2D ziemlich einfach: Drehen Sie die Koordinaten und kehren Sie das Vorzeichen von einem von ihnen um. Das ist die Variable d
in meinem Code:(-5 sin 40° - 6, 5 cos 40°)
. Der Vektor von C
zu einem Punkt von Interesse q = (x, y)
ist q - C = (x, y + 6)
. Die Projektion ist nur das Skalarprodukt (oder Skalarprodukt) zwischen q
und d
. Die Art und Weise, wie ich d
sie gewählt habe, zeigt zufällig nach links, also möchte ich d.(q-C) > 0
. Diese Bedingung gilt für die rechte Maske.
Für die linke Maske kann ich grundsätzlich die gleiche Idee verwenden. Die Steigung ist die gleiche und daher auch d
. Ich muss nur meinen Punkt von den unteren linken Ecken der Streifen anstatt von versetzen C
. Diese haben Koordinaten (-7.5, 0.5)
(oberer Streifen) und (-7.5, -1.5)
(unterer Streifen). Das würde also zwei unabhängige Regeln für die beiden Streifen erfordern. Beachten Sie jedoch, dass sich alle von der unteren Maske betroffenen Punkte im unteren Streifen befinden und daher ein negatives y haben . Und alle Punkte, die von der oberen Maske betroffen sind, haben ein positives y . So kann ich einfach meine Offset mit dem Schalter Sign[y]
das ist 1
für positive und -1
für negative y
. So wird mein Versatzpunkt(-7.5, -0.5 + Sign[y])
. Ansonsten funktioniert die Maske genauso wie die rechte Maske. Diesmal muss die Projektion natürlich negativ sein. Naiv wäre das so etwas wie RH-projection > 0 && LH-projection < 0
(was ich auch ursprünglich im Code hatte). Wir können dies jedoch verkürzen, da das Multiplizieren einer positiven und einer negativen Zahl eine negative Zahl ergeben muss. Es ist also nur RH * LH < 0
(wo RH
und LH
sind die jeweiligen Projektionen).
Das ist es. Alles zusammen ergibt die folgende logische Struktur:
(
(is_in_circle || is_in_stripe)
&&
is_between_left_and_right_mask
)
||
(
is_in_circle && left_of_edge
)
Um klar zu sein, beziehen sich die Koordinaten in meiner Erklärung auf das Konstruktionsdiagramm, das in der Herausforderung angegeben ist. Wie oben erwähnt, multipliziert mein Code tatsächlich alle mit 2
- ich habe ihn geändert, um Bytes zu sparen, aber die Anzahl der Bytes ist tatsächlich identisch, und ich konnte nicht die Mühe machen, die Änderung erneut rückgängig zu machen. Auch ganze Zahlen sehen besser aus.