Düzlemi bu değiştirilmiş daireyle döşeyin


22

Menşei merkezli bir birim daire içine alın. Herhangi iki komşu kadranda , dairenin x ve y yakalamalarını bağlayan çizgiler boyunca dairenin eğrisini yansıtın.

Ortaya çıkan şekli ile uçağı döşeyebilirsiniz:

daire mozaik

Bu görüntüyü harika 2D fizik sanal alan Algodoo ile yaptım !

Buna benzer bir görüntü çıktısı veren bir program yaz, genel kayıpsız görüntü dosyası biçiminde. Görüntüyü, seçtiğiniz adda bir dosya olarak kaydedebilir veya yalnızca görüntüleyebilirsiniz. Giriş yapılmamalıdır.

Kurallar:

  • Tüm görüntü herhangi iki görsel olarak farklı RGB renk kullanılarak modifiye daire çinileri ile tessellated gerekir: dikey işaret fayans, yukarıya doğru bakmaktadır, fayanslar biri için bir.

  • Daire döşemelerinin yarıçapı en az 32 piksel olmalıdır. (Yukarıdaki resimde yarıçapı yaklaşık 110 pikseldir.)

  • Görüntü en az 4 karo genişliğinde ve 4 karo uzunluğunda olmalıdır. Bu, yukarıdaki kuralla birleştirildiğinde, görüntülerin minimum 256 x 256 piksel boyutunda olabileceği anlamına gelir. (Yukarıdaki resim 4 karo ile 4 karodur.)

  • Mozaikleme herhangi bir miktarda çevrilebilir. Örneğin, görüntünün sol üst köşesinin, döşemelerin buluştuğu tepe noktası olması gerekmez. (Bununla birlikte, mozaikleme döndürülmemelidir.)

  • Daire çizme ve görüntüleri ve benzeri çıktıları almak için komutları olan harici grafik kitaplıklarını kullanabilirsiniz.

  • Eğriler , çoğu grafik kütüphanesinin sizin için yapacağı orta nokta daire algoritması ile yapılabileceği gibi, çevreleri gerçekten yaklaştırmalıdır .

  • Karoların kenarlarında kenar yumuşatmaya izin verilir, ancak gerekli değildir.

Bayt cinsinden en kısa gönderme kazanır.

Yanıtlar:


4

gs2, 49 bayt

50 31 05 0d 1f 2a 48 0a 1e 2e 40 83 2c e8 64 2d
1e 73 ed 1e 33 40 20 30 9a a2 22 e8 e9 40 20 30
9a 30 40 20 30 ee 40 20 30 12 32 e9 12 32 55 e8
2b

PBM görüntüsü oluşturur:

çıktı

Mnemonics:

# Print header
"P1" space 256 double
2dup new-line

# Make 1/4 circle
64 range dup cartesian-product
square m1 sum sqrt 64 >= m6
64 /

# Make tile
dup reverse + transpose
@2 not m1 m2
dup reverse + transpose
+

# Make quarter of image
dup reverse + z1
dup reverse +

# Loop
2 * m2
2 *

# Format
show-words m1
unlines

36

POV-Ray, 199 163

Old version
camera{location -9*z}light_source{-9*z}#declare L=union{#for(X,-9,9,2)#for(Y,-9,9,2)cylinder{X*x+x+Y*y,<.001*pow(-1,(X+Y)/2),0,.1>+X*x+x+Y*y,1}#end#end}object{L pigment{color x}}object{L rotate z*90}

Same output, but golfed down further by using default light/camera, so I dont even need to specify them
#declare L=union{#for(X,-9,9,2)#for(Y,-9,9,2)cylinder{<X+1,Y,9>,<.001*pow(-1,(X+Y)/2),0,.1>+<X+1,Y,9>,1}#end#end}object{L pigment{color rgb x}rotate z*90}object{L}

görüntü tanımını buraya girin
Kamera ve ışık kaynağı için mümkün olan en fazla varsayılan parametreyi kullanıyorum, bu yüzden biraz karanlık. Önce onu ungolf sağlar

camera{location 9*z look_at 0}
light_source{9*z color 1} 
#declare L=union{
    #for(X,-9,9,2)
        #for(Y,-9,9,2)
            cylinder{<1+X,Y,0>,                                 //central axis, start
                     <1+X,Y,0> + <.001*pow(-1,(X+Y)/2), 0, .1>, //central axis, end
                      1}                                        //radius
        #end         
    #end
}                         
object{L pigment{color x}} // x is the <1,0,0> vector, here interpreted as RGB
object{L rotate<0,0,90>}

Silindir ekseninin ofsetini arttırdığımızda ve perspektifi değiştirdiğimizde ne olduğu açıktır.

görüntü tanımını buraya girin


1
3D perspektif sayesinde kenarlar hafifçe bozulmayacak mı?
orlp

6
Diskin yüksekliği 0.1ve kayması ile 0.001$ \ phi = \ arctan (0.01) = 0.57 ° $ döndürülür, üstten bakıldığında, diskler $ \ cos (\ phi) = 0.99995 $ faktörü ile sıkılmış olarak görünür, Bu bir pikselden çok daha az.
DenDenDo

@DenDenDo pov-ışını sonsuzlukta bir kamera koymak mümkün değil mi?
Random832

@ Random832 ile yapabilirsiniz camera{orthographic location -9z}. Ancak sahne temelde 2B olduğundan fark angle 170yaratmaz, sonuçta herhangi bir balık gözü çarpıklığı olmadan görüntülemeyle bile görüntüleyebilirsiniz .
DenDenDo

11

Gnuplot, 182

Hücreler arasındaki sınırların çok sinüzoidal göründüğünü fark ettim, bu yüzden çok basit bir çekirdek denklemiyle analitik bir çözüme gittim
görüntü tanımını buraya girin

set view map
set isosamples 900
f(x,y)=.3*sin(x*3.14)+y
splot(ceil(f(x,y))+ceil(f(y,x)))%2?1:NaN   #can only modulo integers

görüntü tanımını buraya girin
Benzer görünse de daireler çok kare. Aynı fikir ile, yerine sinbirleştirilmiş quartercircle-yaylardan yapılmış bir eğri ve değiştirerek ° o 45 döndürmek xve yile x+yvex-y

set view map
set samples 800
set isosamples 800
d=.5**.5
c(x,k)=(-1)**k*sqrt(1-(x-d*(1+2*k))**2)-(-1)**k*d  # k-th circle arc
# s(x)=c(x,floor(x/d/2))                           # circlified sinus
# f(x,y)=d*s(x/d)+y
f(x,y)=d*c(x/d,floor(x))+y                         # combined commented functions
splot(ceil(f(x+y,x-y))+ceil(f(x-y,x+y)))%2?1:NaN

görüntü tanımını buraya girin



7

HTML + JavaScript, 277

<canvas id=C></canvas><script>r=50,C.width=C.height=9*r,T=C.getContext('2d');
for(f=1,P=Math.PI,i=0;i<45;f=-f,i+=i&7?1:2)x=2*r*(i%8-2),y=2*r*(i>>3),T.moveTo(x,y+f*r),
T.arc(x+r,y+f*r,r,P,-f*P/2,f<0),T.arc(x,y,r,0,P,f>0),T.arc(x-r,y+f*r,r,-f*P/2,0,f<0);
T.fill()</script>

Test etmek için, html dosyası olarak kaydedin ve bir tarayıcı ile açın. Veya, snippet'i çalıştırın

r=50,C.width=C.height=9*r,T=C.getContext('2d')
for(f=1,P=Math.PI,i=0;i<45;f=-f,i+=i&7?1:2)
  x=2*r*(i%8-2),y=2*r*(i>>3),
  T.moveTo(x,y+f*r),
  T.arc(x+r,y+f*r,r,P,-f*P/2,f<0),
  T.arc(x,y,r,0,P,f>0),
  T.arc(x-r,y+f*r,r,-f*P/2,0,f<0)
T.fill()
<canvas id=C></canvas>

Popüler talep nedeniyle, işte çıktı görüntüsü. Sonuçta çok heyecan verici değil ...

Fayans


1
Bir görüntü göndermek isteyebilirsiniz, böylece birileri çıktıyı görmek istediğinde kodun çalıştırılması gerekmez.
Calvin'in Hobileri

@ Calvin's Hobbies oh yeterince hızlı ve her modern tarayıcıda yayınlanıyor. Bunun yerine görseli
büyüteceğim

Bu doğru. =>Gönderilerinizin çoğu gibi kullanıldığını ve yalnızca Firefox'ta çalışacağını düşündüm . Ama endişelenme.
Calvin'in Hobileri

1
Resim göndermenin daha iyi bir nedeni: Bu pasajlar mobil cihazlarda çok iyi çalışmıyor :(
Sp3000

6

IDL 8.3, 201 193 183 bayt

Görüntü bir IDL grafik penceresine gönderilir; Aşağıda bir ekran görüntüsü aldım.

EDIT: @AlexA sayesinde. ve @ Sp3000 bazı baytları tıraş etmeme yardım ettiğim için

p=!pi/99*[0:99]
q=p[49:0:-1]
o=p[99:50:-1]
window,xs=(ys=400)
for i=0,24 do cgpolygon,i mod 5*100+50*[cos(p),cos(q)-1,cos(o)+1],i/5*100+(-1)^i*50*[sin(p),sin(q)-1,sin(o)-1],/d,/fi
end

görüntü tanımını buraya girin


6

Mathematica: 86 bayt (veya 82 bayt)

Zeki dizi tabanlı bir yöntem için sonsuz @ alfalfa sayesinde :

Image@ArrayFlatten@Array[DiskMatrix@32~RotateLeft~32/.a_/;OddQ@+##:>1-Thread@a&,{5,5}]

Dizinin içindeki, argümanlarını ( +##) eklemek ve toplamın tek olup olmadığını belirlemek için akıllıca bir numara kullanan anonim bir işlevdir . Bu boolean, tüm "beyaz" kutucuğu dönüştürülmüş, "kara" kutucuğuyla değiştiren bir desene koşullu olarak kullanılır. Oradan ArrayFlattenkiremit birleştirir ve Imagegörüntüler.

ThreadDeğiştirilecek daha kısa olanı kullanın Transpose. Bunun yerine transpoze sembolünü kullanarak 4 bayt kaydedebiliriz.

Önceki: 97 bayt (veya 90 bayt)

Image@ArrayFlatten@Partition[
 Join@@Table[{#,1-Transpose@#}&@RotateLeft[DiskMatrix@32,32],{13}],5]

Transpose@#Üst simge-t sembolüyle değiştirerek bayt sayısını azaltabilirsiniz (kod noktası U + F3C7, kısayol ESCtrESC). UTF-8'de 88 karakterde toplamı 90 bayta getirir .

görüntü tanımını buraya girin

DiskMatrixİkili bir matris üreten, ile başlayalım :

DiskMatrix@32 // Image

görüntü tanımını buraya girin

Daha sonra döşemeye ait birim hücresini üretmek için matrisin sıralarını dairesel olarak kaydırırız:

RotateLeft[DiskMatrix@32, 32] // Image

görüntü tanımını buraya girin

Uçak bir satranç tahtasıysa, bunlar 'beyaz' karelerdir. 'Siyah' kareler için renkleri ters çevirmemiz ve 90 derece döndürmemiz gerekir. 1 ( 1 - 1 -> 0ve 1 - 0 -> 1) ' den çıkartarak ters çevirebilir ve transpozisyonu alarak döndürebiliriz:

Image /@ {#, 1 - Transpose@#} &@RotateLeft[DiskMatrix@32, 32]

görüntü tanımını buraya girin

Görüntünün boyutları eşitse (minimum boyut 4 gibi), sağ kenardaki bir döşeme, sol kenardaki bir sonraki ile aynı olacaktır. Ancak, tek bir boyut (5) elde etmek için bir kiremit eklemek, ardından sıraları birleştirmek, düzenli bir alternatif desen oluşturur.

Bu, tek bir sırayla sırayla fayansları sararak tam görüntüyü elde edebileceğimizi gösteriyor Partition. Biz kullanmak Tablebir listesini yapmak için 13siyah / beyaz çini çifti ve Join26 çini bir listeye çiftlerinin listesini düzleştirmek. Daha sonra Partition, bir içine listesi 5ile 5tuğlalar matrisinin ( Partitionatar 26 arka inci kiremit):

Map[Image] /@ 
  Partition[
   Join @@ Table[{#, 1 - #\[Transpose]} &@
      RotateLeft[DiskMatrix@32, 32], {13}], 5] // MatrixForm

görüntü tanımını buraya girin

Son ArrayFlattenolarak, döşeme matrislerinin matrisini düz bir matrise dönüştürür Imageve sonucu görüntüler.

Önceki: 111 bayt

Image[ArrayFlatten[{{#, #}, {#, #}}] &[
  Join[#, Reverse@#, 2] &[
   Join[1 - Transpose@#, #] &@RotateLeft[DiskMatrix[32], 32]]]]

görüntü tanımını buraya girin


Image@ArrayFlatten@Array[RotateLeft[DiskMatrix@32,32]/.a_/;OddQ[+##]:>1-Thread@a&,{5,5}]
alephalpha

4

Java, 550 540 508 504 bayt

Bu bir java uygulaması.

import java.awt.*;public class T extends java.applet.Applet{int a=98,b=49,x,y;public void paint(Graphics g){for(x=0;x<5;x++)for(y=0;y<5;y++)a(g.create(x*a,y*a,a,a),x%2^y%2);}void a(Graphics g,int c){if(c>0){g.translate(a,0);((Graphics2D)g).scale(-1,1);}g.setColor(Color.red);g.fillRect(0,0,b,b);g.fillRect(b,b,b,b);g.setColor(Color.blue);g.fillRect(b,0,b,b);g.fillRect(0,b,b,b);g.fillArc(0,-b,a,a,180,90);g.fillArc(0,b,a,a,0,90);g.setColor(Color.red);g.fillArc(-b,0,a,a,0,-90);g.fillArc(b,0,a,a,90,90);}}

Kazan plakası ile genişletildi:

import java.awt.*;
public class T extends java.applet.Applet{
    int a = 98, b = 49, x, y; //Make these larger for better quality pictures. a = b * 2
    public void paint(Graphics g) {
        for (x=0; x < 5; x++)      //Make these larger for more tiles.
            for (y=0; y < 5; y++)  //
                a(g.create(x * a, y * a, a, a), x % 2 ^ y % 2);
    }

    void a(Graphics g, int c) {
        if (c > 0) {
            g.translate(a, 0);
            ((Graphics2D) g).scale(-1, 1);
        }
        g.setColor(Color.red);            //Change colors for nicer looking colors.
        g.fillRect(0, 0, b, b);
        g.fillRect(b, b, b, b);
        g.setColor(Color.blue);
        g.fillRect(b, 0, b, b);
        g.fillRect(0, b, b, b);
        g.fillArc(0, -b, a, a, 180, 90);
        g.fillArc(0, b, a, a, 0, 90);
        g.setColor(Color.red);
        g.fillArc(-b, 0, a, a, 0, -90);
        g.fillArc(b, 0, a, a, 90, 90);
    }
}

Uygulama: Başka bir uygulamada çalışırken kullanılabilecek küçük bir uygulama programı.

Örnek resim:

görüntü tanımını buraya girin

Açıklama:

Bu, her döşemeyi yazdırmak için bir yöntem kullanarak çalışır. Yöntem oluşturulmadan önce, her döşemenin sol üst köşesinde ortalanmış bir koordinat sistemi kullanan bir grafik nesnesi verilir:

Bir döşeme oluşturmak için aşağıdaki yöntemi kullanırız:

void a(Graphics g, int c) {
    g.setColor(Color.red);
    g.fillRect(0, 0, b, b);
    g.fillRect(b, b, b, b);
    g.setColor(Color.blue);
    g.fillRect(b, 0, b, b);
    g.fillRect(0, b, b, b);
    g.fillArc(0, -b, a, a, 180, 90);
    g.fillArc(0, b, a, a, 0, 90);
    g.setColor(Color.red);
    g.fillArc(-b, 0, a, a, 270, 90);
    g.fillArc(b, 0, a, a, 90, 90);
}

Ancak, doğru görüntüyü elde etmek için diğer her karo yatay olarak yansıtılmalıdır.

Bir döşemeyi yansıtmak için verilen graphicsnesneyi bu kodla değiştiriyoruz:

g.translate(a, 0);
((Graphics2D) g).scale(-1, 1);

4 bayt için @CoolGuy teşekkürler.


1
Bunu ilan ederek xve ysınıfın alanları olarak daha çok golf yapabilirsiniz :int a = 98, b = 49,x,y;
Spikatrix

4

Mathematica 299 256

Wordy ama anlamak güzeldi.

Temel karo, RegionPlot tarafından görüntülenen bir bölge olan r'dir (aşağıda gösterilmiştir). Döşemenin soldan sağa yansıması r ile yapılır. İki kiremit toplanmış figür daha sonra boşluğu döşemek için tekrarlanır.

r

a_~f~b_ := (x + a)^2 + (y + b)^2 <= 1;
a = ImageAssemble;
r = RegionPlot[(0~f~0 && y <= 0 && ! f[-1, 1]) \[Or] (0~f~2 && 
      y >= -2 && ! f[1, 1]), {x, -1, 1}, {y, -2, 0}, Frame -> False,
    BoundaryStyle -> None];
s = ImageCrop@Rasterize@r;
t = s~ImageReflect~Right;
i = a@{s, t};
j = a@{t, s};
a@{k = {i, i, i, i}, m = {j, j, j, j}, k, m, k, m}

kiremit


1

C, 237 209 180 bayt

180 bayt. Bu sürüm, bir yorumda edc65 tarafından önerilen değişiklikleri içermektedir. Mac'te oluştururken clang ve varsayılan seçeneklerle 9 derleyici uyarısı verir:

a,b,c,d,x,y;main(){for(puts("P1 256 256");b=a+32&64,a<256;++a){for(c=0;d=c+32&64,x=(a&64)-d?31-a&31:a&31,y=(c&64)-b?c&31:31-c&31,c++<256;)putchar(48+(x*x+y*y<962^b==d));puts("");}}

209 byte, Martin tarafından yapılan yorumlardan bazı önerileri kullanarak. Klan uyarısı olmayan derlemeler:

#include <stdio.h>
int a,b,c,d,x,y;int main(){puts("P1 256 256");for(;b=a+32&64,a<256;++a){for(c=0;d=c+32&64,x=(a&64)-d?31-a&31:a&31,y=(c&64)-b?c&31:31-c&31,c<256;++c)putchar(48+(x*x+y*y<962^b==d));puts("");}}

Orijinal sürüm, 237 bayt:

#include <stdio.h>
int main(){puts("P1 256 256");for(int a=0;a<256;++a){int b=a+32&64;for(int c=0;c<256;++c){int d=c+32&64;int x=(a&64)-d?31-a&31:a&31;int y=(c&64)-b?c&31:31-c&31;putchar(48+(x*x+y*y<962^b==d));}puts("");}}

Sonuç (256x256):

görüntü tanımını buraya girin

Daha iyi okunabilirlik için boşluklu orijinal kod:

#include <stdio.h>
int main()
{
    puts("P1 256 256");
    for (int a = 0; a < 256; ++a)
    {
        int b = a + 32 & 64;
        for (int c = 0; c < 256; ++c)
        {
            int d = c + 32 & 64;
            int x = (a & 64) - d ? 31 - a & 31 : a & 31;
            int y = (c & 64) - b ? c & 31 : 31 - c & 31;
            putchar(48 + (x * x + y * y < 962 ^ b == d));
        }
        puts("");
    }
}

Bu herhangi bir grafik kütüphanesi kullanmaz, oluşturma tamamen kodda bulunur.

Temel fikir tüm 256x256 piksellerin üzerinde döngü yapmak ve içinde bulundukları 32x32 alt karenin dairesel yayının içinde veya dışında olup olmadıklarına bakmaktır. Genel piksel koordinatlarının alt 5 bitleri, içindeki pikselin göreceli koordinatlarını tanımlar. alt kare. Daha sonra (x, y)yarıçapı olan yayın içinde olup olmadığının iç / dış testi rstandarttır:

x * x + y * y < r * r

Mantığın çoğu, yayın merkezini alt karenin doğru köşesine yerleştirmek ve hangi rengin içeride / dışarıda olduğunu belirlemek içindir.

Çözümle ilgili bazı yorumlar:

  • Kod, resmi PBM ASCII formatında oluşturur. Sonucu GIMP'ye yükledim ve buraya gönderdiğim asıl dosyayı oluşturmak için Paint'e kopyalayıp yapıştırdım. Böylece biçim dönüştürüldü, ancak içerik tam olarak orijinal çıktı kadar.
  • Yakından bakarsanız, kalitenin mükemmel olmadığını fark edebilirsiniz. Bunun nedeni, piksel merkezi yerine pikselin köşesi için iç / dış hesaplamanın yapılması ve her şeyin 1/2 piksel kapalı olmasına neden olmasıdır. Daha iyisini yapmanın çok zor olacağını sanmıyorum, ancak kodu biraz daha uzun hale getireceğini düşünüyorum. Özel kalite gereklilikleri olmadığından, bunun yeterli olduğuna inanıyorum.
  • Mac'te clang kullanılarak kod derlendi. Son sürüm uyarılar veriyor, ilk sürüm vermedi.
  • Bu, bunlardan birini ilk kez denediğimden, mümkün olan son baytı kurtarmak için birkaç numara kaçırdım.

3
PPCG'ye Hoşgeldiniz! Ben büyük bir C golfçü değilim, ancak birkaç iyileştirme görebileceğimi düşünüyorum: bildirimlerinizi gruplandırın int a,b,c,d,x,y;... Sanırım bile yapabileceğinizi bile düşünüyorum main(a,b,c,d,x,y), varsayılan türün int olduğu bir şeyi hatırlıyorum. Ondan kurtulduktan sonra, ödevleri d, x ve y forgibi içselin artım ifadesine d=c+32&64,...,++ctaşıyabilirsiniz (muhtemelen yine de ++bahsettiğiniz başka bir yere bile taşıyabilirsiniz c) ve sonra ayraçlarını atlayabilirsiniz. iç for. Güzel iş, btw! :)
Martin Ender

Teşekkürler! Bir ipucu listesinde türler olmadan argümanlar bildirerek hileyi gördüm, fakat oraya kendimi bulamadığım için çok kirli görünüyordu. ;) Standart olmayan argümanlara sahip olmanın main()standartlara uygun olduğunu sanmıyorum . Kesinlikle bildirimleri gruplamalıyım. Ve artımları hareket ettirmek de bir kaç bayttan tasarruf sağlayacaktır. puts()Yenisatır için ben parantez kurtulmak eğer ben emin değilim, dış döngü içindedir.
Reto Koradi

Bazı ortak derleyicilerde derlendiği sürece genellikle biz tamamız (bu yüzden tamamen standart C olması gerekmez). Ayrıca evet, dış parantezlerden kurtulabileceğinizi sanmıyorum, ancak iç olanları çıkarabilmelisiniz.
Martin Ender

210 byte'a indirdim. Fikirler için teşekkürler.
Reto Koradi

1
İpuçları: stdiogerekli değil, varsayılan işlev bildirimini kullanın. intgloballer için varsayılandır ve atlanabilir (değişkenler ve ana). İlk putsönce için içeri girebilir. c var iç döngü içinde kullanılmaz, bu nedenle koşullu olarak yükselir. 180: a,b,c,d,x,y;main(){for(puts("P1 256 256");b=a+32&64,a<256;++a){for(c=0;d=c+32&64,x=(a&64)-d?31-a&31:a&31,y=(c&64)-b?c&31:31-c&31,c++<256;)putchar(48+(x*x+y*y<962^b==d));puts("");}}(birçok uyarı ile derlenir ancak çalışır)
edc65
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.