Affianca l'aereo con questo cerchio modificato


22

Prendi un cerchio unitario centrato sull'origine. In due quadranti vicini , rispecchia la curva del cerchio attraverso le linee che collegano le intercettazioni x e y del cerchio.

Con la forma risultante, puoi affiancare il piano:

tassellatura del cerchio

Ho realizzato questa immagine con l'incredibile sandbox di fisica 2D Algodoo !

Scrivi un programma che emette un'immagine simile a questa in un formato di file di immagine lossless comune. Puoi salvare l'immagine come file con il nome che preferisci oppure puoi semplicemente visualizzarla. Nessun input dovrebbe essere preso.

Regole:

  • L' intera immagine deve essere tassellata con le tessere del cerchio modificato utilizzando due colori RGB visivamente distinti: uno per le tessere che puntano verticalmente, uno per le tessere che puntano orizzontalmente.

  • Il raggio delle tessere del cerchio dovrebbe essere di almeno 32 pixel. (Il raggio nell'immagine sopra è di circa 110 pixel.)

  • L'immagine dovrebbe essere larga almeno 4 tessere e alta 4 tessere. Questo, combinato con la regola sopra, significa che le immagini possono avere una dimensione minima di 256 × 256 pixel. (L'immagine sopra è di 4 tessere per 4 tessere.)

  • La tassellatura può essere tradotta per qualsiasi importo. Ad esempio, l'angolo in alto a sinistra dell'immagine non deve necessariamente essere il vertice in cui le piastrelle si incontrano. (Tuttavia, la tassellatura non deve essere ruotata.)

  • È possibile utilizzare librerie grafiche esterne che dispongono di comandi per disegnare cerchi e produrre immagini e simili.

  • Le curve dovrebbero davvero approssimare i cerchi, come si può fare con l' algoritmo del cerchio di punto medio , che la maggior parte delle librerie grafiche farà per te.

  • L'anti-aliasing attorno ai bordi delle piastrelle è consentito ma non necessario.

Vince l'invio più breve in byte.

Risposte:


4

gs2, 49 byte

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

Genera un'immagine PBM:

produzione

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}

inserisci qui la descrizione dell'immagine
Sto usando il maggior numero possibile di parametri predefiniti per telecamera e sorgente luminosa, ecco perché è un po 'buio. Consente prima di tutto

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>}

È ovvio cosa sta succedendo quando aumentiamo l'offset dell'asse del cilindro e cambiamo la prospettiva

inserisci qui la descrizione dell'immagine


1
I bordi non saranno leggermente distorti grazie alla prospettiva 3D?
orlp

6
Con un'altezza di 0.1e un offset del 0.001disco è inclinato di $ \ phi = \ arctan (0,01) = 0,57 ° $, guardando dall'alto i dischi appaiono schiacciati da un fattore di $ \ cos (\ phi) = 0.99995 $, questo è molto meno di un pixel.
DenDenDo

@DenDenDo pov-ray non è in grado di mettere una telecamera all'infinito?
Casuale 832,

@ Random832 può, con camera{orthographic location -9z}. Ma poiché la scena è fondamentalmente 2D non fa alcuna differenza, puoi anche renderizzarla con una visione angle 170senza alcuna distorsione fisheye nel risultato.
DenDenDo

11

Gnuplot, 182

Ho notato che i confini tra le cellule sembrano molto sinusoidali, quindi ho optato per una soluzione analitica con un'equazione di base molto semplice
inserisci qui la descrizione dell'immagine

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

inserisci qui la descrizione dell'immagine
Mentre sembra simile, i cerchi sono troppo quadrati. Con la stessa idea, sostituisco sincon una curva fatta da archi a quarto di cerchio concatenati e la giro di 45 ° sostituendo xe ycon x+yex-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

inserisci qui la descrizione dell'immagine



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>

Per provare, salva come file html e aprilo con un browser. Altrimenti, esegui lo snippet

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>

A grande richiesta, ecco l'immagine di output. Non così eccitante dopo tutto ...

piastrelle


1
Potresti voler pubblicare un'immagine in modo che il codice non debba essere eseguito ogni volta che qualcuno vuole vedere l'output.
Calvin's Hobbies,

@ Calvin'sHobbies vabbè è abbastanza veloce e funziona in ogni browser moderno.
Ingrandirò

È vero. Ho pensato che usasse =>molti dei tuoi post e avrebbe funzionato solo su Firefox. Ma non preoccuparti.
Hobby di Calvin

1
Motivo migliore per pubblicare un'immagine: questi frammenti non funzionano molto bene sui dispositivi mobili :(
Sp3000,

6

IDL 8.3, 201 193 183 byte

L'immagine viene emessa in una finestra grafica IDL; Ho fatto uno screenshot, di seguito.

EDIT: grazie a @AlexA. e @ Sp3000 per avermi aiutato a radere alcuni byte

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

inserisci qui la descrizione dell'immagine


6

Mathematica: 86 byte (o 82 byte)

Grazie all'infinito @alephalpha per un metodo intelligente basato su array:

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

All'interno dell'array c'è una funzione anonima, che usa un trucco intelligente per aggiungere i suoi argomenti ( +##) e determinare se la somma è dispari. Quel booleano è usato come condizionale per un modello che sostituisce l'intera piastrella 'bianca' con la piastrella 'nera' trasformata. Da lì, ArrayFlattenunisce le tessere e le Imagevisualizza.

Si noti l'uso del più corto Threadda sostituire Transpose. Possiamo comunque salvare 4 byte usando invece il simbolo di trasposizione.

Precedente: 97 byte (o 90 byte)

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

È possibile ridurre il numero di byte sostituendo Transpose@#con il simbolo apice-t (punto di codice U + F3C7, collegamento ESCtrESC). In UTF-8 che porta il totale a 90 byte in 88 caratteri .

inserisci qui la descrizione dell'immagine

Iniziamo con DiskMatrix, che genera una matrice binaria:

DiskMatrix@32 // Image

inserisci qui la descrizione dell'immagine

Spostiamo quindi circolare le file della matrice per produrre la cella unitaria per la piastrellatura:

RotateLeft[DiskMatrix@32, 32] // Image

inserisci qui la descrizione dell'immagine

Se l'aereo è una scacchiera, questi sono i quadrati "bianchi". Per i quadrati "neri", dobbiamo invertire i colori e ruotare di 90 gradi. Possiamo invertire sottraendo da 1 ( 1 - 1 -> 0e 1 - 0 -> 1) e ruotare prendendo la trasposizione:

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

inserisci qui la descrizione dell'immagine

Se le dimensioni dell'immagine sono pari (come la dimensione minima, 4), una tessera sul bordo destro sarà la stessa di quella successiva sul bordo sinistro. Tuttavia, l'aggiunta di una tessera per ottenere una dimensione dispari (5), quindi la concatenazione delle righe produce un modello alternato regolare.

Questo suggerisce che possiamo ottenere l'immagine completa avvolgendo una singola fila di tessere alternate con Partition. Usiamo Tableper creare un elenco di 13coppie di tessere bianco / nero e Joinper appiattire l'elenco di coppie in un elenco di 26 tessere. Poi abbiamo Partitionla lista in una 5dalla 5matrice di piastrelle ( Partitionscarta la finale 26 ° tegola):

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

inserisci qui la descrizione dell'immagine

Infine, ArrayFlattentrasforma la matrice delle matrici delle tessere in una matrice piatta e Imagevisualizza il risultato.

Precedente: 111 byte

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

inserisci qui la descrizione dell'immagine


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

4

Java, 550 540 508 504 byte

Questa è un'applet Java.

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);}}

Espanso con piastra caldaia:

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);
    }
}

Applet: un piccolo programma applicativo che può essere richiamato per l'uso mentre si lavora in un'altra applicazione.

Immagine di esempio:

inserisci qui la descrizione dell'immagine

Spiegazione:

Funziona utilizzando un metodo per stampare ogni riquadro. Prima di creare il metodo, viene assegnato un oggetto grafico che utilizza un sistema di coordinate centrato nell'angolo in alto a sinistra di ogni riquadro:

Per creare un riquadro, utilizziamo il seguente metodo:

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);
}

Tuttavia, ogni altra piastrella deve essere riflessa in orizzontale per produrre l'immagine corretta.

Per riflettere un riquadro, modifichiamo semplicemente l' graphicsoggetto fornito con questo codice:

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

Grazie @CoolGuy per 4 byte.


1
Puoi giocare a golf più dichiarando xe ycome campi della classe:int a = 98, b = 49,x,y;
Spikatrix

4

Mathematica 299 256

Wordy ma è stato bello capire.

Il riquadro di base è r (mostrato sotto), che è una regione visualizzata da RegionPlot. Viene creato un riflesso sinistro-destro della piastrella e unito con r. La figura assemblata con due tessere viene quindi ripetuta per piastrellare lo spazio.

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}

piastrella


1

C, 237 209 180 byte

180 byte. Questa versione include le modifiche suggerite da edc65 in un commento. Fornisce 9 avvisi del compilatore quando si crea su un Mac con clang e opzioni predefinite:

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, utilizzando alcuni suggerimenti dai commenti di Martin. Compila senza avvisi con clang:

#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("");}}

Versione originale, 237 byte:

#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("");}}

Risultato (256x256):

inserisci qui la descrizione dell'immagine

Codice originale con spazi bianchi per una migliore leggibilità:

#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("");
    }
}

Questo non utilizza alcuna libreria grafica, il rendering è completamente contenuto nel codice.

L'idea di base è quella di passare semplicemente su tutti i 256x256 pixel e vedere se sono dentro / fuori dall'arco circolare del sotto-quadrato 32x32 in cui si trovano. I 5 bit inferiori delle coordinate globali del pixel definiscono le coordinate relative del pixel all'interno il sub-quadrato. Il test interno / esterno di (x, y)essere all'interno dell'arco con raggio rè quindi lo standard:

x * x + y * y < r * r

La maggior parte della logica serve a posizionare il centro dell'arco nell'angolo corretto del sotto-quadrato e determinare quale colore è interno / esterno.

Alcuni commenti sulla soluzione:

  • Il codice genera l'immagine nel formato ASCII PBM. Ho caricato il risultato in GIMP e ho fatto una copia e incolla in Paint per generare il file effettivo che ho pubblicato qui. Quindi il formato è stato convertito, ma il contenuto è esattamente come l'output originale.
  • Se osservi attentamente, potresti notare che la qualità non è eccezionale. Questo perché il calcolo interno / esterno viene eseguito per l'angolo del pixel, anziché per il centro del pixel, facendo sì che il tutto sia a mezzo pixel fuori. Non penso che sarebbe molto difficile fare di meglio, ma renderebbe il codice un po 'più lungo. E poiché non c'erano requisiti di qualità specifici, credo che questo sia sufficiente.
  • Il codice è stato compilato usando clang su un Mac. L'ultima versione fornisce avvisi, la versione iniziale no.
  • Questa è la prima volta che ho mai provato uno di questi, quindi probabilmente ho perso alcuni trucchi per salvare l'ultimo byte possibile.

3
Benvenuti in PPCG! Non sono un grande giocatore di golf in C, ma penso di poter vedere alcuni miglioramenti: raggruppa le tue dichiarazioni come int a,b,c,d,x,y;... Penso che potresti anche essere in grado di farlo, main(a,b,c,d,x,y)ricordo qualcosa che il tipo predefinito è int. Una volta che ti sei liberato di questo, puoi spostare le assegnazioni in d, xey nell'istruzione forincrementale interna come d=c+32&64,...,++c(probabilmente anche spostare ++in un altro posto dove menzioni ccomunque), e quindi puoi omettere le parentesi graffe di l'interno for. Bel lavoro, a proposito! :)
Martin Ender,

Grazie! Ho visto il trucco nel dichiarare argomenti senza tipi in un elenco di suggerimenti, ma sembrava così sporco che non riuscivo a farmi andare lì. ;) Non credo che avere argomenti non standard main()sia conforme allo standard. Dovrei certamente raggruppare le dichiarazioni. E lo spostamento degli incrementi salverà anche un paio di byte. Il puts()per la newline è nel ciclo esterno, quindi non sono sicuro di riuscire a sbarazzarmi delle parentesi graffe.
Reto Koradi,

Di solito andiamo bene fino a quando si compila in un compilatore comune (quindi non deve essere interamente C standard). Sì, non penso che tu possa sbarazzarti delle parentesi graffe esterne, ma dovresti essere in grado di rimuovere quelle interne.
Martin Ender,

Ridotto a 210 byte. Grazie per le idee
Reto Koradi,

1
Suggerimenti: stdionon necessario, utilizzare la dichiarazione di funzione predefinita. intè predefinito per i globali e può essere omesso (variabili e principale). In primo luogo putspuò andare dentro per. c var non viene utilizzato all'interno del loop interno, quindi incrementare in condizione. 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("");}}(compila con molti avvertimenti ma viene eseguito)
edc65
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.