Functional Geometry is described in the two papers of P. Henderson (1982, 2002). The funcgeo package implements a picture language much like those described in (1982, 2002).
The funcgeo package for R can be installed from my Drat repository:
#install.packages("drat")
drat::addRepo("MHenderson")
install.packages("funcgeo")
Below, Square Limit by Escher is recreated using the same approach as (1982). This involves first building simpler pictures which are combined using operations on pictures to create more complex pictures.
In the next section we introduce the basic fish pictures and show how they can be combined into slightly more complex pictures in such a way that the lines of the fish are connected. In section 3 we show how to draw side1 and side2 which are used in section 4 to create corner which is then used in section 5 to create Square Limit.
The fish in (1982) are made available as package data objects fish_p, fish_q, fish_r and fish_s. These can all be drawn by base::plot.
library(funcgeo)
plot(fish_p)
Picture operations from (1982) like rot, flip and cycle are package functions. For example, the quartet operation described in (1982) can be combined with the four fish to create one of the building blocks, t, of Square Limit.
t <- quartet(fish_p, fish_q, fish_r, fish_s)
plot(t)
The cycle and rot functions can be composed to create picture u from fish_q.
u <- cycle(rot(fish_q))
plot(u)
The quartet function is also required to build one of the more complex pieces of Square Limit, side1. This picture also requires the rot operation and the nil empty picture.
side1 <- quartet(nil, nil, rot(t), t)
plot(side1)
Then side2 is created as a quartet involving several pictures, including side1.
side2 <- quartet(side1, side1, rot(t), t)
plot(side2)
In this section the goal is to reproduce the corner picture from (1982). Square Limit is created by calling the cycle operation on corner. To create corner we first have to create corner2, which itself is based on the picture we create next, corner1.
corner1 <- quartet(nil, nil, nil, u)
plot(corner1)
Now corner2 is created by using quartet with corner1 and several earlier pictures.
corner2 <- quartet(corner1, side1, rot(side1), u)
plot(corner2)
The nonet function is a \(3 \times 3\) variant of quartet and is used with corner2 as well as several variations on earlier pictures to create corner, the main constituent of Square Limit.
corner <- nonet(
corner2, side2, side2,
rot(side2), u, rot(t),
rot(side2), rot(t), rot(fish_q)
)
plot(corner)
Finally, we can assemble Square Limit by calling cycle on corner.
squarelimit <- cycle(corner)
plot(squarelimit)