# Tile the plane with this modified circle

Take a unit circle centered on the origin. In any two neighboring quadrants, mirror the curve of the circle across the lines connecting the circle's x and y intercepts.

With the resulting shape, you can tile the plane:

I made this image with the awesome 2D physics sandbox Algodoo!

Write a program that outputs an image similar to this one in some common lossless image file format. You may save the image as a file with the name of your choice or you may simply display it. No input should be taken.

Rules:

• The entire image must be tessellated with the modified-circle tiles using any two visually distinct RGB colors: one for the vertically pointing tiles, one for the horizontally pointing tiles.

• The radius of the circle tiles should be at least 32 pixels. (The radius in the image above is about 110 pixels.)

• The image should be at least 4 tiles wide and 4 tiles tall. This, combined with the rule above, means that images can have a minimum size of 256×256 pixels. (The image above is 4 tiles by 4 tiles.)

• The tessellation may be translated by any amount. For example, the top left corner of the image does not need to be the vertex where tiles meet. (The tessellation should not be rotated, however.)

• You may use external graphics libraries that have commands for drawing circles and outputting images and the like.

• The curves really should approximate circles, as can done with the midpoint circle algorithm, which most graphics libraries will do for you.

• Anti-aliasing around the edges of the tiles is allowed but not required.

The shortest submission in bytes wins.

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


I am using as many default parameters for camera and lightsource as possible, thats why it is a little dark. Lets ungolf it first

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
#end
#end
}
object{L pigment{color x}} // x is the <1,0,0> vector, here interpreted as RGB
object{L rotate<0,0,90>}


It is obvious what is happening once we increase the offset of the cylinder axis and change the perspective

• Won't the edges be slightly distorted thanks to 3d perspective?
– orlp
May 9, 2015 at 4:04
• With a height of 0.1 and an offset of 0.001 the disk is tilted by $\phi=\arctan(0.01) = 0.57°$, looking from the top the disks appear squeezed by a factor of $\cos(\phi) = 0.99995$, thats far less than a pixel. May 9, 2015 at 7:20
• @DenDenDo is pov-ray not able to put a camera at infinity? May 10, 2015 at 4:03
• @Random832 it can, with camera{orthographic location -9z}. But since the scene is basically 2D it makes no difference, you can even render it with a viewing angle 170 without any fisheye distortion in the result. May 10, 2015 at 9:21

# Gnuplot, 182

I noticed that the boundaries between the cells look very sinusoidal, so i went for an analytical solution with a very simple core equation

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


While it looks similar, the circles are way too square. With the same idea, I replace sin by a curve made from concatenated quartercircle-arcs and rotate it 45° by replacing x and y with x+y and x-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


## Context Free, 99 bytes

startshape d CF::Tile=[s 4]CF::Symmetry=CF::pmg,0,1,0path d{ARCTO(-1,1,1)ARCTO(1,1,-1)ARCTO(0,0,1)}


You can see the result at the Context Free Gallery.

• Nice one, that's an amazing use of Context Free. :) May 9, 2015 at 23:45

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


To test, save as html file and open with a browser. Or else, run the 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>

Due to popular demand, here is the output image. Not so exciting after all...

• You may want to post an image so the code doesn't have to be run each time someone wants to see the output. May 9, 2015 at 19:27
• @Calvin'sHobbies oh well it's fast enough and run in every modern browser. I'll make the image bigger instead May 9, 2015 at 19:34
• That's true. I thought it used => like a lot of your posts and would only work in Firefox. But no worries. May 9, 2015 at 19:39
• Better reason for posting an image: These snippets don't work very well on mobile :( May 9, 2015 at 20:05

# IDL 8.3, 201193 183 bytes

The image is output into an IDL graphics window; I took a screenshot, below.

EDIT: thanks to @AlexA. and @Sp3000 for helping me shave some bytes

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


# Mathematica: 86 bytes (or 82 bytes)

Thanks to the infinite @alephalpha for a clever array-based method:

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


Inside the array is an anonymous function, which uses a clever trick to add its arguments (+##) and determine whether the sum is odd. That boolean is used as the conditional to a pattern that replaces the whole 'white' tile with the transformed, 'black' tile. From there, ArrayFlatten joins together the tiles and Image displays them.

Note the use of the shorter Thread to replace Transpose. We can still save 4 bytes by using the transpose symbol instead.

## Previous: 97 bytes (or 90 bytes)

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


You can reduce the number of bytes by replacing Transpose@# with the superscript-t symbol (codepoint U+F3C7, shortcut ESCtrESC). In UTF-8 that brings the total to 90 bytes in 88 characters.

We start with DiskMatrix, which generates a binary matrix:

DiskMatrix@32 // Image


We then circular-shift the rows of the matrix to produce the unit cell for the tiling:

RotateLeft[DiskMatrix@32, 32] // Image


If the plane is a chessboard, these are the 'white' squares. For the 'black' squares, we need to invert the colors and rotate by 90 degrees. We can invert by subtracting from 1 (1 - 1 -> 0 and 1 - 0 -> 1), and rotate by taking the transpose:

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


If the dimensions of the image are even (like the minimum size, 4), then a tile on the right edge will be the same as the next one on the left edge. However, adding one tile to get an odd size (5) then concatenating the rows produces a regular alternating pattern.

This suggests that we can get the full image by wrapping a single row of alternating tiles with Partition. We use Table to make a list of 13 black/white tile pairs, and Join to flatten the list of pairs to a list of 26 tiles. Then we Partition the list into a 5 by 5 matrix of tiles (Partition discards the trailing 26th tile):

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


Finally ArrayFlatten turns the matrix of tile matrices into a flat matrix, and Image displays the result.

## Previous: 111 bytes

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


• Image@ArrayFlatten@Array[RotateLeft[DiskMatrix@32,32]/.a_/;OddQ[+##]:>1-Thread@a&,{5,5}] May 12, 2015 at 5:37

# gs2, 49 bytes

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


Generates a PBM image:

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


# Java, 550540508 504 bytes

This is a java applet.

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


Expanded with boilerplate:

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: A small application program that can be called up for use while working in another application.

Example image:

Explanation:

This works by using a method to print each tile. Before the method is created, it is given a graphics object that uses a coordinate system centered on the upper left corner of each tile:

To create a tile, we use the following method:

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


However, every other tile must be reflected horizontally in order to produce the correct image.

To reflect a tile, we simply modify the supplied graphics object with this code:

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


Thanks @CoolGuy for 4 bytes.

• You can golf it more by declaring x and y as fields of the class:int a = 98, b = 49,x,y; May 10, 2015 at 13:33

# Mathematica 299 256

Wordy but it was nice to figure out.

The basic tile is r (shown below),which is a region displayed by RegionPlot. A left-right reflection of the tile is made and joined with r. The two tile assembled figure is then repeated to tile the space.

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}


## C, 237209 180 bytes

180 bytes. This version includes changes suggested by edc65 in a comment. It gives 9 compiler warnings when building on a Mac with clang and default options:

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 bytes, using some suggestions from comments by Martin. Compiles without warnings with 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("");}}


Original version, 237 bytes:

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


Result (256x256):

Original code with whitespace for better readability:

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


This does not use any graphics library, the rendering is completely contained in the code.

The basic idea is to simply loop over all 256x256 pixels, and see if they are inside/outside the circular arc of the 32x32 sub-square they are in. The bottom 5 bits of the overall pixel coordinates define the relative coordinates of the pixel within the sub-square. The inside/outside test of (x, y) being inside the arc with radius r is then the standard:

x * x + y * y < r * r


Most of the logic is for placing the center of the arc in the correct corner of the sub-square, and determining which color is inside/outside.

• Welcome to PPCG! I'm not a big C golfer, but I think I can see a few improvements: group your declarations like int a,b,c,d,x,y; ... I think you might even be able to just do main(a,b,c,d,x,y) I remember something that the default type is int. Once you're rid of that, you can move the assignments to d, x and y into the inner for's increment statement like d=c+32&64,...,++c (probably even move the ++ into some other place where you mention c anyway), and then you can omit the braces of the inner for. Nice job, btw! :) May 9, 2015 at 23:43
• Thanks! I saw the trick with declaring arguments without types in a list of tips, but it seemed so dirty that I couldn't get myself to go there. ;) I don't think having non-standard arguments for main() is standard compliant. I should certainly group the declarations. And moving the increments will save a couple of bytes, too. The puts() for the newline is in the outer loop, so I'm not sure if I can get rid of the braces. May 9, 2015 at 23:56
• Hints: stdio not needed, use default declaration of function. int is default for globals and can be omitted (variables and main). First puts can go inside the for. c var is not used inside the inner loop, so increment in condition. 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("");}} (compiles with many warnings but runs) May 10, 2015 at 1:01