Thoughts...


...on proofreading, editing, maths, miscellaneous

Coordinates, lines and OpenSCAD

Hexagon mural

My family and I are creating a 3d-printed hexagon mural, inspired by this project by @100Hex. I put the first few tiles on the wall this week; the plan is that the mural will grow as we’re inspired to design and print more hexagons.

The mural is supposed to represent us as a family, so there are, or will be, tiles to represent our hobbies, history, interests, and so on. I’ve snuck in a few mathsy tiles – these represent one of my hobbies and they are fun to design. I created them using OpenSCAD, which is a 3d modelling language that is fairly simple to pick up, although it does have some interesting quirks.

Two of my favourite hexagons so far involve the same concept: generating curves from lines.

Hexagon tile with curves made from straight lines

The first creates curves by drawing lines between axes in a specific way. You’ll often see this done with Cartesian axes, producing a curved diamond effect, but as my axes join the corners of a hexagon they are at 60° to each other, producing something more like a spider’s web. Peter Rowlett wrote a lovely article about these curves in The Aperiodical’s Big Internet Math-Off, in which he showed that such a curve made on perpendicular axes is parabolic. The curves look parabolic on 60° axes; I haven’t yet done the maths to check that they are.

Hexagon tile with curve of pursuit design

The second uses a curve of pursuit to produce curves that spiral in from the corners towards the centre. Why is it called a curve of pursuit? It models the paths of six dogs starting at the corners of a hexagonal field and chasing each other around the field. Woolly Thoughts have created a knitting pattern that shows the effect nicely.

I love the fact that even though both of these tiles are made entirely from straight lines, they contain beautifully smooth curves.

It took some fiddling to generate the models in OpenSCAD. It’s straightforward to use a loop to generate the coordinates to plot – but although OpenSCAD has the concept of an origin and it displays axes in its preview window, it doesn’t use coordinates in that way! You can draw a line by making a very thin rectangle with the square command1. By default it will be plotted with its bottom left corner at the origin. You can rotate and translate the line, but you can’t explicitly state the coordinates of its start and end points.

To get around this, I wrote a module that takes two pairs of coordinates and plots a line between them. It uses some school-level trigonometry to calculate the angle of rotation (remembering the edge cases for vertical and horizontal lines) and the distance-between-two-points formula to calculate the length of the line. The code is included below. I’m not an expert in OpenSCAD and it’s likely that there is a more efficient way to do this, but I enjoyed coming up with it and it works for what I need to do.

module line(x1,y1,x2,y2,t) {
//x1,y1: first pair of coordinates
//x2,y2: second pair of coordinates
//t: thickness of line

    //First quadrant
    if (x2>x1 && y2>y1) {
        angle=atan((y2-y1)/(x2-x1));
        _line(x1,y1,x2,y2,t/2,angle);
    }
    //Second quadrant
    if (x2<x1 && y2>y1) {
        angle=180+atan((y2-y1)/(x2-x1));
        _line(x1,y1,x2,y2,t/2,angle);
    }
    //Third quadrant
    if (x2<x 1&& y2<y1) {
        angle=180+atan((y2-y1)/(x2-x1));
        _line(x1,y1,x2,y2,t/2,angle);
    }
    //Fourth quadrant
    if (x2>x1 && y2<y1) {
        angle=atan((y2-y1)/(x2-x1));
        _line(x1,y1,x2,y2,t/2,angle);
    }
    //Parallel to x-axis
    if (y2==y1 && x2>x1) {
        _line(x1,y1,x2,y2,t/2,0);
    }
    if (y2==y1 && x2<x1) {
        _line(x1,y1,x2,y2,t/2,180);
    }
    //Parallel to y-axis
    if (x2==x1 && y2>y1) {
        _line(x1,y1,x2,y2,t/2,90);
    }
    if (x2==x1 && y2<y1) {
        _line(x1,y1,x2,y2,t/2,270);
    }
  
        
}

module _line(x1,y1,x2,y2,t,angle)  {
//x1,y1: first pair of coordinates
//x2,y2: second pair of coordinates
//t: thickness of line
//angle: angle of rotation

    //calculate length
    length=sqrt(pow(x2-x1,2)+pow(y2-y1,2));
    //move to correct place
    translate([x1,y1,0]) { 
        //rotate around z-axis
        rotate([0,0,angle]) {
            //drop by half the thickness so centred on x-axis
            translate([0,-t/2,0]) { 
                square([length,t]);
            }
        }   
    } 
}

You’ll notice that although the tiles are 3d printed, all these calculations relate to two dimensions. The whole model is extruded along the z-axis to make a three-dimensional model.

Now that I can plot lines using coordinates, there are lots of interesting maths-related hexagons I can make. Whether or not I’ll be allowed to add them to the mural is another matter.

1 Yes, the command is ‘square’ but you can specify a different height and width. Don’t get me started.

Tags: ,

About Sam Hartburn

Sam offers proofreading, copy-editing and answer checking for maths textbooks and digital resources at all levels and for popular and recreational maths books and content. Follow her on Twitter at @SamHartburn or find her on LinkedIn

No comments yet.