We’ve just learned of a new book on mathematical design: Creating Symmetry: The Artful Mathematics of Wallpaper Patterns by Frank Farris; we came across it thanks to this article. As often happens, some questionable notions of “art” and “beauty” are being tossed around here, but that isn’t the main reason to mention it.The article points to the very first example in Farris’s book: a simple-looking equation that generates interesting patterns. In fact this is a parametric equation using sines and cosines, which is exactly what drives something we’ve blogged about previously. And as with the harmonograph, the spirograph and other toys you might be familiar with, it looks like they make amusing and distracting patterns and that’s that.But there may be something more interesting and suggestive lurking behind the pretty designs; there’s something to be said here about taking a playful approach to maths, too, that’s not a bad way to kick off the new academic year.

I’ll show you the equations — don’t worry too much about “cos” and “sin”, they’re just special processes that convert numbers into other numbers according to a certain geometric rule:

x = cos(t) + cos(6t)/2 + sin(14t)/3

y = sin(t) + sin(6t)/2 + cos(14t)/3

Imagine a particle moving around on a flat plane. Given a number t representing the time, these tell us how to calculate the x- and y-coordinates of the particle at that moment. If we plot every such point, we can visually see the path taken by the point. These plots are the designs Farris is interested in. Let’s just call these plots “curves” for now.

But, you may be wondering, where did the special numbers 6, 2, 14 and 3 come from? The answer is in Farris’s book: he just fiddled around with different numbers to see what would happen, and he liked the result he got from these choices. That’s it: no formulae or calculations involved, just trial and error and some kind of subjective judgement.

Since there are four numbers that can vary freely, we have a four-dimensional configuration space, each point of which is a different curve (i.e. a different motion of the particle). I decided to write a quick Processing sketch to explore this space. Fixing the 2 and 3, I made the values 6 and 14 adjustable by moving the mouse around on the screen. The Processing code is at the bottom of the post — install Processing itself if you don’t already have it, paste in the code and hit “run”. Incidentally, students on our programming course will be learning how to make this sort of thing this term.

Below are screenshots of some of the curves you can find by moving the mouse around — each one corresponds to a “point” of this two-dimensional slice of the configuration space. You can “move” the slice through the other two dimensions by changing the values of firstDivisor and secondDivisor in the code before running, and you get visibly different results. I’d like to say this again: we’re not making pretty patterns here, we’re defining and exploring a four-dimensional space whose points are themselves very complicated one-dimensional geometric objects!

The point is, though, that before we get the concept right we can still fiddle around with it visually and get some idea of “what it’s like”. And the larger lesson though is that maths is something you can play with. If you find a formula like this that does something, always ask how it can be tweaked and altered. Then ask whether there’s a way to think about all those tweaks belonging to some larger object that encompasses them all.

[Technical remarks: To be honest I’m really not sure how to characterise this space; perhaps as a fibre bundle, since I guess we can blow up the curves we’re looking at until they’re topologically just lines. There’s a subtle 3D effect in the images that makes it look as if something like this has already happened, so the curve doesn’t seem to intersect itself even though it actually does. There are also some decisions to be made about how to extend the idea to continuous real space rather than the pixilated space of the screen.]


THE PROCESSING CODE


int firstDivisor = 3;
int secondDivisor = 2;

float halfWidth;
float halfHeight;
float mult;

void setup(){

size(displayWidth, displayHeight);
background(10, 10, 10);
halfWidth = (float)width/2;
halfHeight = (float)height/2;
mult = halfHeight/(1 + 2/firstDivisor + 1.5/secondDivisor);
fill(255, 200, 200);
noStroke();
textSize(32);
frameRate(60);
}

int max = 200;
float offset = 0.0;
int prevMouseX = -1;
int prevMouseY = -1;
float ratio;
int rad = 8;
float fullCircle = 2*PI;
float incr = 0.008;
float animIncr = 0.0002;
int var1;
int var2;
boolean moved;

void draw(){
moved = (prevMouseX != mouseX || prevMouseY != mouseY);
if(moved){
var1 = (2 * max *mouseX/displayWidth) – max;
var2 = (2 * max*mouseY/displayHeight) – max;
prevMouseX = mouseX;
prevMouseY = mouseY;
background(10, 10, 10);

fill(255);
text(“(” + var1 + “, ” + var2 + “)”, 20, 40);
}
for(float t = offset; t < fullCircle; t += incr){
float x = mult * (cos(t) + cos(var1 * t)/firstDivisor + sin(var2 * t)/secondDivisor);
float y = mult * (sin(t) + sin(var1 * t)/firstDivisor + cos(var2 * t)/secondDivisor);
int dist = round(sqrt(pow(x, 2) + pow(y, 2)));
fill(dist + 55, dist, dist, dist);
ellipse(halfWidth + x, halfHeight + y, rad, rad);
dist = dist/2;
fill(dist + 55, dist, dist, dist);
ellipse(halfWidth + x + 3, halfHeight + y + 3, rad, rad);
}
if(!moved){
offset += animIncr;
if(offset > incr){
offset = 0.0;
}
}
}