Circular Blues


21

Écrivez un programme ou une fonction qui prend un entier positif N et recrée ce motif de cercles mis à l'échelle pour s'adapter à une image de pixels N × N:

cercles de fantaisie

Cette image est un exemple de sortie valide pour N = 946.

Dans le cas où ce n'est pas clair, tous les petits cercles bleu clair ont le même rayon et sont positionnés dans les quatre cercles bleu foncé de la même manière. Les cercles bleu foncé ont le double de ce rayon et sont positionnés de manière similaire dans le grand cercle bleu clair.

  • Deux couleurs visuellement distinctes peuvent être utilisées à la place des deux nuances de bleu.

  • Le carré de fond doit être coloré.

  • L'anticrénelage est facultatif.

  • Enregistrez l'image dans un fichier, affichez-la ou dirigez les données d'image brutes vers stdout.

  • Tout format de fichier d'image courant est autorisé.

Le code le plus court en octets gagne.

Brownie pointe si vous étendez les aspects récursifs de ce motif de cercle à d'autres niveaux. (Gardez cela distinct de votre défi.)


Qu'entendez-vous par "Le carré de fond doit être coloré"? Si l'arrière-plan a une certaine couleur par défaut, puis-je simplement l'utiliser comme l'une des 2 couleurs sans le remplir explicitement?
aditsu

Je veux dire que le bg ne peut pas être une troisième couleur différente
Calvin's Hobbies

Réponses:


5

CJam, 83 octets

"P1"li___,.5f+2.@/f*1fm2m*{[3{_~mh1<[[VX][ZmqV]]_Wff*+@2f*f.+{~mh}$0=}*;0]0#2%}%]S*

Essayez-le en ligne

CJam n'a pas de fonctionnalité de sortie d'image dédiée. Mon code génère une image en PBM ASCII. Pour la publication, j'ai converti cette image en PNG à l'aide de GIMP.

Notez qu'aucune fonctionnalité de dessin de cercle, ou quelque chose comme ça, il a utilisé. L'image est calculée pixel par pixel.

Exemple de sortie

Des degrés plus élevés de la subdivision peuvent facilement être créés en augmentant la constante 3autour du milieu du code.

Les images de degré 4 et 5 ressemblent à ceci:

Degré 4Degré 5

La séquence globale du code est la suivante:

  1. Génère les coordonnées de tous les pixels, normalisées pour s'étendre [-1,0, 1,0].
  2. Boucle sur tous les pixels.
  3. Boucle sur les degrés de subdivision.
  4. Pour chaque subdivision, vérifiez si le pixel est à l'intérieur / à l'extérieur et conservez le résultat. L'échelle / translate les coordonnées des pixels dans les systèmes de coordonnées centrés sur l'un des 4 sous-cercles. Choisissez celui où les coordonnées transformées sont les plus proches du centre.
  5. À partir des résultats binaires intérieur / extérieur de chaque degré, trouvez le premier 0, correspondant au premier degré où le pixel était à l'extérieur, et prenez son modulo 2 pour déterminer la couleur du pixel.

Explication:

"P1"    Start of header for PBM ASCII file.
li      Get input n.
__      Two copies for the width/height of the image in the PBM header.
_,      Generate [0 .. n - 1].
.5f+    Add 0.5 to each list entry, since we want to test the pixel centers.
2.@/    Calculate 2.0 / n, which is the distance between two pixels.
f*      Multiply the unscaled pixel coordinates with the pixel distance.
        We now have coordinates in the range [0.0, 2.0].
1fm     Subtract one from each, giving coordinates in range [-1.0, 1.0].
2m*     Cartesian power to calculate all y/x pairs.
{       Start loop over all pixel coordinates.
  [       Start wrapping the inside/outside results for all degrees.
  3{      Start loop over degrees.
    _~mh    Calculate distance from center.
    1<      Compare with 1. This gives inside/outside result for degree.
    [       Start building list of centers for 4 sub-circles.
    [VX]    One is at [0 1]. Note that coordinate order is y/x.
    [ZmqV]  Next one is at [sqrt(3) 0].
    ]       Wrap these two...
    _       ... and copy them.
    Wff*    Mirror all coordinates by multiplying with -1.
    +       Concatenate, giving the centers of all 4 sub-circles.
    @       Get current coordinates to top.
    2f*     Multiply them by 2. Note that the coordinates need to be scaled up by
            a factor 2 to give a circle with half the radius when we test the distance
            to the origin against 1.0.
    f.+     Add the current coordinates to the centers of all 4 sub-circles.
            For each sub-circle, this puts the current coordinates in a coordinate
            space with the origin at the center, and with a radius of 1.0
    {~mh}$  Sort them by distance to the origin...
    0=      ... and take the first one. This picks the sub-circle which has its
            center closest to the current coordinates.
            We now have one coordinate pair, for the closest sub-circle, and are
            ready for the next loop iteration, which tests the next degree of the
            subdivision.
  }*      End loop over degrees.
  ;       Have remaining coordinate pair on stack, pop it.
  0       Add a sentinel for find operation before, so that a 0 is always found.
  ]       End wrapping the inside/outside results for all degrees.
  0#      Find the first 0 (outside) degree.
  2%      Modulo 2 to determine color.
}%      End loop over all pixel coordinates.
]       Wrap the pieces of the PBM header and the pixel list.
S*      Join them with spaces, to produce the necessary spaces for the header.

17

Python 2 + PIL, 262 octets

entrez la description de l'image ici

Cette approche détermine la couleur de chaque coordonnée de pixel individuelle à l'aide de la fonction récursive c. c(x,y,0)rend un cercle; c(x,y,1)rend un cercle avec quatre cercles découpés; c(x,y,2)rend l'image dans l'OP. Tout ce qui dépasse 2 me rapporte des points brownie.

import PIL.Image as I
d=3**.5/2
c=lambda x,y,l=0:c(x,y)&~any(c((x+i)*2,(y+j)*2,l-1)for i,j in[(.5,0),(-.5,0),(0,d),(0,-d)])if l else x*x+y*y<1
z=input()
f=lambda s:2.*s/z-1
I.frombytes("L",(z,z),"".join(" ~"[c(f(i%z),f(i/z),2)]for i in range(z*z))).save("p.png")

Version non golfée:

from PIL import Image
import math
def in_shape(x,y, level=0):
    d = math.sqrt(3)/2
    if level == 0:
        return x**2 + y**2 <= 1
    else:
        t = True
        for dx,dy in [(0.5, 0), (-0.5, 0), (0, d), (0,-d)]:
            if in_shape((x+dx)*2, (y+dy)*2, level-1):
                t = False
        return in_shape(x,y) and t

f = lambda s: ((2*s / float(size))-1)

size = input()
img = Image.new("RGB", (size, size))
pix = img.load()
for i in range(size):
    for j in range(size):
        if in_shape(f(i), f(j), 2):
            pix[i,j] = (0,0,0)
        else:
            pix[i,j] = (255,255,255)
img.save("output.png")

Image extra-récursive bonus:

entrez la description de l'image ici


Au lieu de .save("p.png")simplement utiliser.show()
Albert Renshaw

7

PostScript, 335 octets.

%!
/D{def}def/B{bind D}D/E{exch}B/A{add}D/c{3 copy 3 -1 roll A E moveto 0 360 arc}B/f{5 dict begin/d E D/r E D/y E D/x E D gsave x y r c clip d 2 mod setgray x y r c fill d 0 gt{/h 3 sqrt 2 div r mul D/r r 2 div D/d d 1 sub D x r A y r d f x r sub y r d f x y h A r d f x y h sub r d f}if grestore end}B 512 2 div dup dup 2 f showpage

PostScript n'est pas seulement un format de fichier graphique avec des capacités vectorielles et bitmap, c'est en fait un langage de programmation Turing-complet basé sur des objets. Le code ci-dessus est une implémentation de fonction récursive assez simple. Tous les opérateurs PostScript sont des fonctions, et il est courant de les redéfinir pour condenser le code. Notez que PostScript utilise la notation polonaise inversée (aussi appelée notation postfixée).

Les interprètes PostScript lisent généralement les métadonnées (comme la taille de la page et le titre) des commentaires spéciaux au début du fichier; de toute évidence, j'ai supprimé tout sauf le commentaire %!de signature PostScript essentiel de mon entrée, mais il devrait toujours s'afficher correctement dans tout interpréteur PostScript standard, par exemple GhostScript ou Okular. Il peut également être affiché à l'aide de l' utilitaire d' affichage fourni avec ImageMagick / GraphicsMagick.

Notez que le fichier doit se terminer par un retour à la ligne (que j'ai inclus dans mon nombre d'octets), ou l'interpréteur peut se fâcher.

Le paramètre de taille Npour ce code est 512; il est divisé par 2 et dupliqué deux fois pour créer les paramètres de l'appel initial de la fonction récursive f. La profondeur de récursivité est 2, qui est donnée juste avant l' fentrée 512 2 div dup dup 2 f. Pour garder la taille petite, la sortie est en noir et blanc. Bien que vous puissiez définir une profondeur de récursion entière non négative raisonnable, cette version ne semble bonne qu'avec des profondeurs paires.

Cette image est un graphique vectoriel, elle peut donc être affichée dans n'importe quelle résolution sans pixelisation, en fonction de la qualité et des paramètres de l'interpréteur / imprimante PostScript utilisé. (FWIW, PostScript utilise des courbes cubiques de Bézier pour dessiner des arcs circulaires, avec suffisamment de splines utilisées pour garantir que l'erreur est toujours inférieure à un pixel dans l'espace du périphérique). Pour le visualiser à l'aide de l' affichage ImageMagick de qualité raisonnablement élevée, vous pouvez faire:

display -density 300 -geometry 512x512 -page 512x512

les mêmes paramètres sont également bons si vous souhaitez utiliser ImageMagick convertpour le convertir dans un autre format. Par exemple, voici une version 640x640 du code PostScript ci-dessus converti en PNG:

640x640 fractale en cercle N & B


Voici une version légèrement plus grande qui gère les couleurs RVB et les profondeurs de récursivité impaires:

%!PS-Adobe-3.0
/D{def}def/N 512 D/d 2 D/B{bind D}D/E{exch}B/A{add}D/c{3 copy 3 -1 roll A E moveto 0 360 arc}B/k{2 mod 0 eq{.3 .6 .9}{0 .2 .5}ifelse setrgbcolor}B d 1 A k 0 0 N N rectfill/f{5 dict begin/d E D/r E D/y E D/x E D gsave x y r c clip d k x y r c fill d 0 gt{/h 3 sqrt 2 div r mul D/r r 2 div D/d d 1 sub D x r A y r d f x r sub y r d f x y h A r d f x y h sub r d f}if grestore end}B N 2 div dup dup d f showpage

Il vous permet également de définir le paramètre de taille Net la profondeur de récursivité dprès du haut du script.

640x640 fractal de cercle de couleur, profondeur == 2


Enfin, voici la forme la plus lisible du code. (Malheureusement, la coloration syntaxique utilisée ici pour PostScript laisse beaucoup à désirer, mais je suppose que c'est mieux que rien ...). Les interprètes Smart PostScript liront la géométrie de la page à partir du %%BoundingBox:commentaire spécial.

%!PS-Adobe-3.0
%%BoundingBox: 0 0 640 640
%%Title: Circle fractal
%%Creator: PM 2Ring
%%Creationdate: (Oct 29 2015)
%%Pages: 1 1
%%EndComments

% for http://codegolf.stackexchange.com/questions/61989/circular-blues

% ----------------------------------------------------------------------

16 dict begin

%Total image width & height in points / pixels
/N 640 def

%Maximum recursion depth
/Depth 4 def

% ----------------------------------------------------------------------

%Draw a circle centred at (x,y), radius r. x y r circle -
/circle{
    3 copy      % x y r  x y r
    3 -1 roll   % x y r  y r x
    add exch    % x y r  x+r y
    moveto
    0 360 arc 
}bind def

% ----------------------------------------------------------------------

%Select 1st color if n is even, select 2nd color if n is odd. n color -
/color{
    2 mod 0 eq
    {.36 .6 .9}
    {0 .25 .5}
    ifelse
    setrgbcolor
}bind def

%Do background square
Depth 1 add color
0 0 N N rectfill

/Q 3 sqrt 2 div def

%Recursive circle pattern. x y r Depth cfrac -
/cfrac{
    5 dict begin
    /Depth exch def
    /r exch def
    /y exch def
    /x exch def

    gsave
    x y r circle clip
    Depth color
    x y r circle fill

    Depth 0 gt
    {
        /dy Q r mul def
        /r r 2 div def
        /Depth Depth 1 sub def 

        x r add y r Depth cfrac
        x r sub y r Depth cfrac
        x y dy add r Depth cfrac
        x y dy sub r Depth cfrac
    }if
    grestore
    end
}bind def

%Call it!
N 2 div dup dup Depth cfrac

showpage

% ----------------------------------------------------------------------

%%Trailer
end
%%EOF

Et voici la profondeur == 4 sortie au format PNG, encore une fois créée en utilisant convert (et optimisée avec optipng ):

640x640 fractal de cercle de couleur, profondeur == 4


6

Python 2 + PIL, 361 octets

import PIL.Image as p,PIL.ImageDraw as d
W=input()
q=W/4
h=2*q
t=3*q
e=W/8
o=int(q*3**.5)
I,J=[p.new("1",(s,s),s>h)for s in[W,h]]
Q=lambda i,x,y,s=q,c=0:d.Draw(i).ellipse((x,y,x+s,y+s),fill=c)
Q(I,0,0,W)
Q(J,0,0,h,1)
[Q(J,k,e)for k in[0,q]]
[Q(J,e,e+k/2)for k in[-o,o]]
[I.paste(1,k,J)for k in[(0,q,h,t),(h,q,4*q,t),(q,q-o,t,t-o),(q,q+o,t,t+o)]]
I.save("c.png")

Enregistre l'image en noir et blanc dans le fichier c.png:

exemple de sortie

Je génère essentiellement l'un des demi-cercles de l'image J . Je m'utilise ensuite comme masque pour peindre la forme sur l'image I, qui a le cercle principal.

Il pourrait être raccourci en utilisant I.show() à la fin à la place de I.save("c.png"), mais je ne l'ai pas fait fonctionner sur Python 2. Si quelqu'un peut confirmer que cela fonctionne sur Python 2, je changerai cela.

Le programme suivant génère l'image comme dans la question (419 octets):

import PIL.Image as p,PIL.ImageDraw as d
W=int(input())
q=W/4
h=2*q
t=3*q
e=W/8
o=int(q*3**.5)
I,J=[p.new(["1","RGB"][s>h],(s,s),s>h and"rgb(13,55,125)")for s in[W,h]]
Q=lambda i,x,y,s=q,c=0:d.Draw(i).ellipse((x,y,x+s,y+s),fill=c)
Q(I,0,0,W,"rgb(97,140,224)")
Q(J,0,0,h,1)
[Q(J,k,e)for k in[0,q]]
[Q(J,e,e+k/2)for k in[-o,o]]
[I.paste("rgb(13,55,125)",k,J)for k in[(0,q,h,t),(h,q,4*q,t),(q,q-o,t,t-o),(q,q+o,t,t+o)]]
I.save("c.png")

-1 pas aussi joli que l'image de Calvin;)
Beta Decay

Je peux confirmer que .show () fonctionne
Albert Renshaw

Ok, merci, je vais utiliser ça à la place de save.
Kevin

3

SVG (1249 caractères)

Oui, beaucoup de personnages. Mais il est statique et s'affiche à n'importe quelle taille, ce qui lui donne un bonus.

<svg xmlns="http://www.w3.org/2000/svg"><path d="M15,33c-2.5,0-4.6,1.9-4.9,4.3c2.8,1.6,6.1,2.6,9.5,2.6c0.3-0.6,0.4-1.3,0.4-2C20,35.2,17.8,33,15,33zM15,7c2.8,0,5-2.2,5-5c0-0.7-0.1-1.4-0.4-2c-3.5,0.1-6.7,1-9.5,2.6C10.4,5.1,12.5,7,15,7zM25,33c-2.8,0-5,2.2-5,5c0,0.7,0.1,1.4,0.4,2c3.5-0.1,6.7-1,9.5-2.6C29.6,34.9,27.5,33,25,33zM25,7c2.5,0,4.6-1.9,4.9-4.3C27.1,1,23.9,0.1,20.4,0C20.1,0.6,20,1.3,20,2C20,4.7,22.2,7,25,7zM35,28.7C34.8,26,32.6,24,30,24s-4.8,2.1-5,4.7c-3-1.7-5-5-5-8.7c0,3.7-2,6.9-5,8.7C14.8,26,12.6,24,10,24S5.2,26,5,28.7c-3-1.7-5-5-5-8.7c0,7.4,4,13.9,10,17.3c0.1-1.2,0.4-2.4,0.8-3.4c0.9-1.9,2.3-3.5,4.1-4.5c0,0,0,0,0.1,0c0.2,2.6,2.3,4.7,5,4.7s4.8-2.1,5-4.7c0,0,0,0,0.1,0c1.8,1,3.2,2.6,4.1,4.5c0.5,1.1,0.8,2.2,0.8,3.4c6-3.5,10-9.9,10-17.3C40,23.7,38,26.9,35,28.7zM5,11.3c0.2,2.6,2.3,4.7,5,4.7s4.8-2.1,5-4.7c3,1.7,5,5,5,8.7c0-3.7,2-6.9,5-8.7c0.2,2.6,2.3,4.7,5,4.7s4.8-2.1,5-4.7c3,1.7,5,5,5,8.7c0-7.4-4-13.9-10-17.3c-0.1,1.2-0.4,2.4-0.8,3.4C28.3,8,26.8,9.6,25,10.6c0,0,0,0-0.1,0C24.8,8,22.6,6,20,6s-4.8,2.1-5,4.7c0,0,0,0-0.1,0c-1.8-1-3.2-2.6-4.1-4.5C10.4,5,10.1,3.9,10,2.6C4,6.1,0,12.6,0,20C0,16.3,2,13,5,11.3z"/><circle cx="15" cy="20" r="5"/><circle cx="5" cy="20" r="5"/><circle cx="35" cy="20" r="5"/><circle cx="25" cy="20" r="5"/></svg>

Extrait visible:

svg { fill: #9FD7FF; background: #2176AA; }
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 40 40">
  <path d="M15,33c-2.5,0-4.6,1.9-4.9,4.3c2.8,1.6,6.1,2.6,9.5,2.6c0.3-0.6,0.4-1.3,0.4-2C20,35.2,17.8,33,15,33zM15,7c2.8,0,5-2.2,5-5c0-0.7-0.1-1.4-0.4-2c-3.5,0.1-6.7,1-9.5,2.6C10.4,5.1,12.5,7,15,7zM25,33c-2.8,0-5,2.2-5,5c0,0.7,0.1,1.4,0.4,2c3.5-0.1,6.7-1,9.5-2.6C29.6,34.9,27.5,33,25,33zM25,7c2.5,0,4.6-1.9,4.9-4.3C27.1,1,23.9,0.1,20.4,0C20.1,0.6,20,1.3,20,2C20,4.7,22.2,7,25,7zM35,28.7C34.8,26,32.6,24,30,24s-4.8,2.1-5,4.7c-3-1.7-5-5-5-8.7c0,3.7-2,6.9-5,8.7C14.8,26,12.6,24,10,24S5.2,26,5,28.7c-3-1.7-5-5-5-8.7c0,7.4,4,13.9,10,17.3c0.1-1.2,0.4-2.4,0.8-3.4c0.9-1.9,2.3-3.5,4.1-4.5c0,0,0,0,0.1,0c0.2,2.6,2.3,4.7,5,4.7s4.8-2.1,5-4.7c0,0,0,0,0.1,0c1.8,1,3.2,2.6,4.1,4.5c0.5,1.1,0.8,2.2,0.8,3.4c6-3.5,10-9.9,10-17.3C40,23.7,38,26.9,35,28.7zM5,11.3c0.2,2.6,2.3,4.7,5,4.7s4.8-2.1,5-4.7c3,1.7,5,5,5,8.7c0-3.7,2-6.9,5-8.7c0.2,2.6,2.3,4.7,5,4.7s4.8-2.1,5-4.7c3,1.7,5,5,5,8.7c0-7.4-4-13.9-10-17.3c-0.1,1.2-0.4,2.4-0.8,3.4C28.3,8,26.8,9.6,25,10.6c0,0,0,0-0.1,0C24.8,8,22.6,6,20,6s-4.8,2.1-5,4.7c0,0,0,0-0.1,0c-1.8-1-3.2-2.6-4.1-4.5C10.4,5,10.1,3.9,10,2.6C4,6.1,0,12.6,0,20C0,16.3,2,13,5,11.3z"/>
  <circle cx="15" cy="20" r="5"/>
  <circle cx="5" cy="20" r="5"/>
  <circle cx="35" cy="20" r="5"/>
  <circle cx="25" cy="20" r="5"/>
</svg>


Notez que, comme l'a dit Mego, SVG ne satisfait pas à nos critères pour être qualifié de langage de programmation . Cependant, le PO peut de toute façon autoriser cette réponse; ça dépend de lui.
Alex A.

SVG est très bien dans ce cas.
Calvin's Hobbies

Pouvez-vous omettre la première 0des constantes à virgule flottante? Par exemple, remplacez 0.4par .4? Dans la plupart des langues, c'est valable. Et un aperçu très rapide de la spécification SVG suggère qu'elle devrait probablement fonctionner également.
Reto Koradi

@RetoKoradi Ouais, et vous pouvez probablement croquer quelques chiffres de plus en arrondissant efficacement, ou en changeant la taille d'une manière qui nécessite moins de décimales, mais tbh. les chemins résultants sont tout simplement trop compliqués pour que cela fasse une énorme différence. Mais je peux essayer une autre solution en utilisant des masques plus tard.
poke

2

Mathematica 336 359 octets

Les principaux objets graphiques sont des régions définies par des combinaisons logiques d'équations.

r=Red;i=ImplicitRegion;m=i[-2<x<2&&-2<y<2,{x,y}];n=Input[];
t[a_,b_,c_]:=i[(x+a)^2+(y+b)^2<=c,{x,y}];
a_~f~b_:={t[a,b,1],t[-.5+a,b,1/4],t[.5+a,b,1/4],t[a,b-.865,1/4],t[a,b+.865, 1/4]}
g@d_:=RegionIntersection[m,BooleanRegion[#1&&!#2&&!#3&&!#4&&!#5&,d]]
RegionPlot[{m,t[0,0,4],g@f[1,0],g@f[-1,0],g@f[0,1.75], 
g@f[0, -1.75]},ImageSize->n,PlotStyle->{r,Blue,r,r,r,r}]

pic


1

Java, 550

import javafx.application.*;import javafx.scene.*;import javafx.scene.layout.*;import javafx.scene.shape.*;import javafx.stage.*;public
class C extends Application{static long n;Shape d(float m,float k,float x,float y){float h=m/2;Shape
s=new Circle(x+h,y+h,h);return k>0?s.subtract(s,s.union(s.union(s.union(d(h,k-1,x,y+m/4),d(h,k-1,x+h,y+m/4)),d(h,k-1,x+m/4,y-m*.183f)),d(h,k-1,x+m/4,y+m*.683f))):s;}public
void start(Stage s){s.setScene(new Scene(new Pane(d(n,2,0,0))));s.show();}public
static void main(String[]a){n=Long.valueOf(a[0]);launch();}}

Essentiellement juste pour expérimenter avec JavaFX.

Capture d'écran:

capture d'écran

Pour les points brownie, remplacez le 2dans le code ( d(n,2,0,0)) par un nombre différent.

Ancienne version, 810

import javafx.application.*;import javafx.scene.*;import javafx.scene.canvas.*;import javafx.scene.effect.*;import javafx.scene.layout.*;import javafx.scene.paint.*;import javafx.stage.*;public
class C extends Application{static long n;Canvas c;GraphicsContext g;void
d(float m,float k,float x,float y){if(k>0){float
h=m/2;g.save();g.beginPath();g.arc(x+h,y+h,h,h,0,360);g.clip();g.fillRect(x,y,m,m);d(h,k-1,x,y+m/4);d(h,k-1,x+h,y+m/4);d(h,k-1,x+m/4,y-m*.183f);d(h,k-1,x+m/4,y+m*.683f);g.restore();}}public
void start(Stage s){c=new Canvas(n,n);g=c.getGraphicsContext2D();g.setGlobalBlendMode(BlendMode.DIFFERENCE);g.setFill(Color.TAN);g.fillRect(0,0,n,n);d(n,3,0,0);Pane
p=new Pane();p.getChildren().add(c);s.setScene(new Scene(p));s.show();}public
static void main(String[]a){n=Long.valueOf(a[0]);launch();}}

Il laisse des bords indésirables comme vous pouvez le voir sur cette capture d'écran .


0

JavaScript (ES6), 279

Créez récursivement des toiles et ajoutez quatre fois le canevas enfant à son canevas parent. Au niveau inférieur, la toile est un seul cercle; ce canevas est tamponné quatre fois sur un canevas parent, puis ce canevas est tamponné quatre fois sur le canevas maître final.

(n,o=0)=>(r=o-2&&f(n/2,o+1),c=document.createElement`canvas`,X=c.getContext`2d`,d=(x,Q)=>(X.drawImage(r,x,k+Q*k*Math.sqrt(3)),d),c.width=c.height=n,m=n/2,k=n/4,X.fillStyle=o%2||"red",X.fill(X.clip(X.arc(m,m,m,0,7))),r&&d(0,0)(m,0)(k,-1)(k,1),o?c:location=c.toDataURL`image/jpeg`)

image de soumission

Démo exécutable:

Avec des espaces, des commentaires et légèrement non golfés:

f=(n,o=0)=>(
    // recursively create another canvas if we're not at the deepest layer
    var r;
    if(o < 2) { r = f(n/2,o+1); }

    // create this canvas
    c=document.createElement("canvas"),
    c.width=c.height=n,
    X=c.getContext("2d"),

    // helpful postions
    m=n/2, k=n/4, q=k*Math.sqrt(3),

    // draw a circle and clip future draws within this circle
    // either fills red (the shortest color name) or a non-color that defaults to black
    X.fillStyle= o%2 || "red",
    X.arc(m,m,m,0,7),
    X.clip(),
    X.fill(),

    // define a chainable `drawImage` alias (the `d` function returns itself)
    d=(x,y)=>(X.drawImage(r,x,y),d)

    // if we have a recursive canvas, draw it four times by chaining `d`
    if(r) { d(0,k)(m,k)(k,k-q)(k,k+q); }

    // if this is the top-layer (o==0), show the final jpeg
    if(o == 0) { location = c.toDataURL("image/jpeg"); }

    // return this canvas, to be used recursively
    c
)

Cela peut facilement produire des couches de récursivité plus profondes en modifiant la valeur initiale o-2ou toute autre o-zvaleur plus grande.

Notez que cette soumission ne s'exécutera que dans Firefox, en raison de l'utilisation des fonctionnalités ES6 et de l'incohérence dans l'API Canvas pour fillet les cliparguments.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.