Functions

directedangle[a_,b_]:=If[Sign@Det[{a,b}]≥0,VectorAngle[a,b],2Pi-VectorAngle[a,b]];

Options[SquareConnect]={LineThickness->3};
SquareConnect[points_,OptionsPattern[]]:=Module[
{flatlist,list,i,pair,n,p1,p2,center,r,d1,d2},
flatlist=StringSplit[points,{"(",")",","," "}];
list={};
i=1;
While[i<=Length[flatlist],
pair={};
n=4;
While[i<Length[flatlist]&& StringLength[flatlist[[i]]]==0 ,i++];
If[StringLength[flatlist[[i]]]==0,Break[]];
While[Length[pair]<n || flatlist[[i]]=="@",
If[flatlist[[i]]=="@",n=6,
AppendTo[pair,ToExpression[flatlist[[i]]]]];
i++;
If[i>Length[flatlist],Break[]];
While[i<Length[flatlist] && StringLength[flatlist[[i]]]==0 ,i++]
];
AppendTo[list,pair]
];
Graphics[
{{Lighter[Gray,0.5],Rectangle[]},
Table[{AbsoluteThickness[OptionValue[LineThickness]],If[Length[list[[i]]]==4,
Line[Partition[list[[i]],2]],
{p1,p2,center}=Partition[list[[i]],2];
r=EuclideanDistance[center,p1];
d1=directedangle[{1,0},p1-center];
d2=directedangle[{1,0},p2-center];
If[d1<d2,d2-=2Pi];
Circle[center,r,{d1,d2}]]},
{i,1,Length[list]}]},
ImagePadding->0,PlotRangePadding->0,ImageSize->100]];

Options[UniformGrid]={PlotSize->10,TileSpacing->0};
UniformGrid[RandomChoice_,OptionsPattern[]]:=Grid[
Table[ToExpression[RandomChoice],
{i,1,OptionValue[PlotSize]},{j,1,OptionValue[PlotSize]}],
Spacings->{OptionValue[TileSpacing],OptionValue[TileSpacing]}];

Options[FourOrientGrid]={PlotSize->10,TileSpacing->0};
FourOrientGrid[RandomChoice_,OptionsPattern[]]:=Grid[
Table[Rotate[ToExpression[RandomChoice],If[OddQ[i],If[OddQ[j],0,-90],If[OddQ[j],-270,-180]]Degree],
{i,1,OptionValue[PlotSize]},{j,1,OptionValue[PlotSize]}],
Spacings->{OptionValue[TileSpacing],OptionValue[TileSpacing]}];

Options[Grid5by5]={TileSpacing->0};
Grid5by5[tile_,OptionsPattern[]]:=Grid[
Table[Which[
i==3 && j==3, Rotate[ToExpression[tile[[1]]], RandomChoice[{0,90,180,270}] Degree],
i<3 && j≤3, Rotate[ToExpression[tile[[3*(2-i)+5-j]]], 0 Degree],
i≥3 && j<3, Rotate[ToExpression[tile[[3*(2-j)+i-1]]], 90 Degree],
i>3 && j≥3, Rotate[ToExpression[tile[[3*(i-4)+j-1]]], 180 Degree],
i≤3 && j>3, Rotate[ToExpression[tile[[3*(j-4)+5-i]]], 270 Degree]],
{i,1,5},{j,1,5}],
Spacings->{OptionValue[TileSpacing],OptionValue[TileSpacing]}];

Define patterns on a tile

Use SquareConnect to define a pattern on a square tile:
tilename=SquareConnect[“((x1, y1), (x2, y2)) @ (cx, cy), ...”]
(x1, y1) and (x2, y2) define the start and end points of a line. 
The bottom left, top left, top right and bottom right corners of the square are (0, 0), (0, 1), (1, 1) and (1, 0), respectively.
(cx, cy) defines the center of an arc, clockwise connecting the start point to the end point.
When @ is missing, the points are connected by a straight line.

arcTile=SquareConnect["((0, 1/2), (1/2, 0)) @ (0, 0), ((1, 1/2), (1/2, 1)) @ (1, 1)"]

crossTile=SquareConnect["((0, 1/2), (1, 1/2)), ((1/2, 0), (1/2, 1))"]

Use LineThickness to change the thickness of lines shown. The default thickness is 3.

arcTile=SquareConnect["((0, 1/2), (1/2, 0)) @ (0, 0), ((1, 1/2), (1/2, 1)) @ (1, 1)",LineThickness->5]

crossTile=SquareConnect["((0, 1/2), (1, 1/2)), ((1/2, 0), (1/2, 1))",LineThickness->5]

Use Export to save your tile design as a png file (or jpg, eps, svg, etc).

SetDirectory[NotebookDirectory[]];
Export["arcTile.png",arcTile];

Generate random arrays on a uniform grid

Use UniformGrid to generate a random array of a square tile on the uniform grid:
arrayname=UniformGrid[“Rotate[tilename,RandomChoice[{p1,p2,...}->{o1,o2,...}] Degree]”] 
oi defines an orientation of the tile.
pi is the probability of oi.
The default probability is 1=n, where n is the total number of choices.

The random choice can also involve multiple types of tiles:
arrayname=UniformGrid[“RandomChoice[{p1,p2,...}->{tilename1,tilename2,...}]”] 
or multiple types of tiles and their orientations:
arrayname=UniformGrid[“RandomChoice[{p1,p2,...}->{Rotate[tilename1, o1 Degree],Rotate[tilename2,o2 Degree],...}]”]

arcArray=UniformGrid["Rotate[arcTile,RandomChoice[{0,90}] Degree]"]

Use Export to save your example random array as a png file (or jpg, eps, svg, etc).

SetDirectory[NotebookDirectory[]];
Export["arc_array.png",arcArray];

arcArray=UniformGrid["Rotate[arcTile,RandomChoice[{1,0}->{0,90}] Degree]"]

arccrossArray=UniformGrid["RandomChoice[{arcTile,crossTile}]"]

arccrossArray=UniformGrid["RandomChoice[{arcTile,Rotate[arcTile,90 Degree],crossTile}]"]

Generate random arrays on a four-orientation grid

Use FourOrientGrid to generate a random array of a square tile on the four-orientation grid:
arrayname=FourOrientGrid[“Rotate[tilename,RandomChoice[{p1,p2,...}->{o1,o2,...}] Degree]”] 
oi defines an orientation of the tile.
pi is the probability of oi.
The default probability is 1=n, where n is the total number of choices.

The random choice can also involve multiple types of tiles:
arrayname=FourOrientGrid[“RandomChoice[{p1,p2,...}->{tilename1,tilename2,...}]”] 
or multiple types of tiles and their orientations:
arrayname=FourOrientGrid[“RandomChoice[{p1,p2,...}->{Rotate[tilename1, o1 Degree],Rotate[tilename2,o2 Degree],...}]”]

arcArray=FourOrientGrid["Rotate[arcTile,RandomChoice[{1,0}->{0,90}] Degree]"]

Adjusting the appearence of the random array shown

Use TileSpacing to change the spacing between tiles. The default spacing is 0.

arcArray=UniformGrid["Rotate[arcTile,RandomChoice[{0,90}] Degree]",TileSpacing->0.2]

arcArray=UniformGrid["Rotate[arcTile,RandomChoice[{0,90}] Degree]",TileSpacing->-0.1]

Use PlotSize to change the size of the random array shown. The default size is 10 by 10.

arcArray=UniformGrid["Rotate[arcTile,RandomChoice[{0,90}] Degree]",PlotSize->20]

Generate random arrays on a finite grid of size 5 by 5

Use Grid5y5 to generate a random array of seven square tiles on the finite grid of size 5 by 5:
arrayname=Grid5by5[{tile1, tile2, tile3, tile4, tile5, tile6, tile7}]
each tile is defined as one of the following five options:
1) "tilename”
2) “Rotate[tilename, orient Degree]”]
    orient defines a specific orientation of the tile. 
3) “Rotate[tilename,RandomChoice[{p1,p2,...}->{o1,o2,...}] Degree]”] 
    oi defines an orientation of the tile.
    pi is the probability of oi.
    The default probability is 1=n, where n is the total number of choices.
4) “RandomChoice[{p1,p2,...}->{tilename1,tilename2,...}]”] 
5) “RandomChoice[{p1,p2,...}->{Rotate[tilename1, o1 Degree],Rotate[tilename2,o2 Degree],...}]”]

tile1="arcTile";
tile2="Rotate[arcTile, RandomChoice[{0,90}] Degree]";
tile3="Rotate[arcTile, RandomChoice[{0,90}] Degree]";
tile4="Rotate[arcTile, 90 Degree]";
tile5="Rotate[arcTile, 90 Degree]";
tile6="Rotate[arcTile, 90 Degree]";
tile7="Rotate[arcTile, 90 Degree]";

arcArray5by5=Grid5by5[{tile1,tile2,tile3,tile4,tile5,tile6,tile7}]

A fun example tile designed by Stella Wang (BE/CS 196a, Spring 2015)

fishgearTile=SquareConnect["((1/3, 0), (2/3 ,0)) @ (1/2, 0), ((0, 1/3), (1, 1/3)) @ (1/2, -1/2),((1/3, 1), (0, 2/3)) @ (-1/2, 3/2), ((1, 2/3), (2/3, 1)) @ (3/2, 3/2)"]

fishgearArray=FourOrientGrid["Rotate[fishgearTile,RandomChoice[{0,90,180,270}] Degree]",TileSpacing->-0.15]