Mathematica, 193 183 177 173 169 166 bayt
Yay, matematik! Belirli (oldukça karmaşık) bir eşitsizlik setini karşılayan bölgeyi çiziyorum:
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->#]&
Kullanım e[height]
, örneğin e[100]
:
Veya e[200]
:
Keskin kenarların biraz yuvarlanmış olduğunu fark edebilirsiniz. Bunun nedeni, bölgenin yalnızca uzayda bulunan noktaları örnekleyerek çizilmesi ve Mathematica'nın varsayılan olarak her pikseli örneklememesidir. Örnekleme çözünürlüğü, 14 karakterPlotPoints->#
ekleyen başka bir seçenek (piksel başına bir örnek kullanan) eklenerek artırılabilir . Bu seçenekle çalıştırmanızı önermiyorum, çünkü çalışma süresini önemli ölçüde artırıyor ve ötesinde görsel çekiciliği zorlukla artırıyor . Bu nedenle, (OP'nin onaylanmasından sonra) puanlamaya dahil edilmez.#/4
İşte biraz ungolfed versiyonu:
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
]
);
Golf versiyonunda, koordinat sistemini .5
s'den kaçınmak için 2 kat ölçeklendirdim , ancak karakter sayısının gerçekte aynı olduğu ortaya çıktı.
Formülün nasıl çalıştığımın bir açıklaması. Şekli iki bölgeye ayırdım. Bir halka ve şeritler içerir ve sağa kesiliyor BCDE
eğim ve ile sola IJ
ve GH
yamaçları (daha sonra ayrıntılı bilgi). Diğeri aynı halkayı içerir, ancak sadece noktanın x koordinatında kesilir D
. İki bölge için şartlar ||
, burada belirlenmiş bir birliktelik görevi gören ile birleştirilir .
Halka, menşe ile olan mesafenin 5 < r < 6
olduğu r
yer olarak tanımlanmıştır . r²
Çalışmak daha kolay olsa da ( x²+y²
), bu yüzden 25 < x² + y² < 36
ringdeki tüm noktaları almak için kullanıyorum .
Şeritler arasındadır ±.5
ve ±1.5
. Her iki çizgiyi aynı anda y modülünü alarak kaldırabiliriz , böylece şeritler (sonsuz uzunluktaki) tam olarak yerine gelir .5 < |y| < 1.5
. Yine, çizgilerin ve halkanın birliğini almak için, sadece kullanıyorum ||
.
İlginç olan, muhtemelen "maskeleri" nasıl elde edeceğimizdir. Noktanın D
bir x koordinatı vardır 5 cos 40°
, bu yüzden alt kenara bakan maske (sadece halka ile birlikte) tam olarak geçerlidir x < 5 cos 40°
. Bu, &&
mantıkta çevrilen küme kesişimi ile uygulanabilir .
Diğer maskeler gerçekten zorlu kısımdır. İlk önce, eğimini alalım BCDE
. Kolayca noktaları gerçekleştirebilmesi C
ve D
yanı (0, -6)
ve 5 (cos 40°, sin 40°)
sırasıyla. Çizgi boyunca işaret eden vektör o zaman sadece D - C = (5 cos 40°, 5 sin 40° + 6)
. Maskeyi sağa uygulamak için, yalnızca bir noktanın o çizginin soluna veya sağına mı uzandığını bulmam gerekiyor (hadi çizgi vektörünü arayalım p
). Ben vektör'ı alarak bu anlamaya C
ilgi benim açımdan ve bir vektör üzerine projelendirme dik için p
. Projeksiyonun işareti bana noktanın açık olduğu tarafı söyleyecektir. Dikey vektörün elde edilmesi 2D'de oldukça basittir: koordinatları çevirin ve birinin işaretini ters çevirin. Kodumdaki değişken bu d
:(-5 sin 40° - 6, 5 cos 40°)
. Dan vektör C
ilgi bir noktaya q = (x, y)
olduğunu q - C = (x, y + 6)
. Projeksiyon arasındaki sadece skaler ürün (veya nokta ürün) olduğunu q
ve d
. Seçtiğim yol d
sola işaret ediyor, bu yüzden istiyorum d.(q-C) > 0
. Bu durum sağdaki maskeyi uygular.
Sol maske için temelde aynı fikri kullanabilirim. Eğim aynıdır ve dolayısıyla böyledir d
. Sadece amacımı, çizgilerin sol alt köşelerinden ayırmam gerekiyor C
. Bunlar koordinatlara (-7.5, 0.5)
(üst şerit) ve (-7.5, -1.5)
(alt şerit) sahiptir. Böylece bu, iki şerit için iki bağımsız kural gerektirecektir. Ancak, alt maskeden etkilenen tüm noktaların alt şeritte olduğunu ve dolayısıyla negatif y bulunduğunu unutmayın . Üst maskeden etkilenen tüm noktalar pozitifdir . Yani basitçe kullanarak bükülme benim geçiş yapabilirsiniz Sign[y]
olan 1
pozitif ve -1
negatif için y
. Böylece ofset noktam olur(-7.5, -0.5 + Sign[y])
. Aksi halde, maske sağdaki maske gibi çalışır. Tabii bu sefer projeksiyonun negatif olması gerekiyor. Yani, naif olarak böyle bir şey olurdu RH-projection > 0 && LH-projection < 0
(aynı zamanda ilk başta kodda bulunduğum şeydi ). Fakat bunu kısaltabiliriz, çünkü pozitif ve negatif bir sayıyı çarpmak, negatif bir sayı vermek zorundadır, bu yüzden sadece RH * LH < 0
( ilgili tahminler nerede RH
ve LH
nerededir).
Bu kadar. Hepsini bir araya getirmek, aşağıdaki mantıksal yapıya yol açar:
(
(is_in_circle || is_in_stripe)
&&
is_between_left_and_right_mask
)
||
(
is_in_circle && left_of_edge
)
Açık olmak gerekirse, açıklamamdaki koordinatlar mücadelede verilen yapı şemasına atıfta bulunuyor. Yukarıda da belirtildiği gibi, kodum aslında hepsini ile çarpıyor 2
- Baytları kurtarmak için değiştirdim, ancak bayt sayısı aslında aynıydı ve değişikliği tekrar geri almak için canımı sıkmadı. Ayrıca tamsayılar daha iyi görünüyor.