Constructing Reuleaux polygons


A Reuleaux polygon is a curvilinear polygon built up of circular arcs. For an odd number of vertices, it has a constant width, and for this reason many polygonal coins, such as the UK's 50p piece and this Bermudian dollar coin are Reuleaux polygons.

Constructing one is easy: join each pair of adjacent vertices of the corresponding straight-sided polygon with the arc of a circles centred at the opposite vertex. The Python code below generates an SVG image of a Reuleaux polygon with $n$ sides, (straight) side-length $a$ and rotated by an angle $\phi$.

The Reuleaux triangle:

enter image description here

The Reuleaux heptagon, the shape of the UK 50p piece:

enter image description here

The following code is also available on my Github page.

import sys
import math

# Create SVG images of Reuleaux polygons, as described at
# Christian Hill, June 2018.

# Image size (pixels)
SIZE = 600

def draw_poly(n, a, phi=0, show_centres=False, colour='#888',
    """Draw a Reuleaux polygon with n vertices.

    a is the side-length of the straight-sided inscribed polygon, phi is the
    phase, describing the rotation of the polygon as depicted. If show_centres
    is True, markers are placed at the centres of the constructing circles.
    colour is the fill colour of the polygon and filename the name of the SVG
    file created. Note that n must be odd.


    if not n % 2:
        sys.exit('Error in draw_poly: n must be odd')

    fo = open(filename, 'w')
    # The SVG preamble and styles.
    print('<?xml version="1.0" encoding="utf-8"?>\n'

    '<svg xmlns=""\n' + ' '*5 +
         'xmlns:xlink="" width="{}" height="{}" >'
            .format(SIZE, SIZE), file=fo)
    <style type="text/css"><![CDATA[

    circle {
        stroke-width: 2px;
        stroke: #000;
        fill: none;
    .marker { stroke-width: 0; fill: #000;}
    .circle {stroke: #888;}

    path {
        stroke-width: 4px;
        stroke: #000;
        fill: %s;

    """ % colour, file=fo)

    c0x = c0y = SIZE // 2
    # Calculate the radius of each of the constructing circles.
    alpha = math.pi * (1 - 1/n)
    r = a / 2 / math.sin(alpha/2)

    if show_centres:
        print('<circle cx="{}" cy="{}" r="3" class="marker"/>'.format(c0x, c0y),

    # Caclulate the (x, y) positions of the polygon's vertices.
    v = []
    for i in range(n):
        # The centre, (cx, cy), of this constructing circle.
        cx = c0x + r * math.cos(2*i*math.pi/n + phi)
        cy = c0y + r * math.sin(2*i*math.pi/n + phi)
        v.append((cx, cy))
        if show_centres:
            print('<circle cx="{}" cy="{}" r="5" class="marker"/>'
                .format(cx, cy), file=fo)
        print('<circle cx="{}" cy="{}" r="{}" class="circle"/>'.format(
            cx, cy, a), file=fo)

    def make_A(x,y):
        """Return the SVG arc path designation for the side ending at (x,y)."""

        return 'A {},{},0,0,1,{},{}'.format(a,a,x,y)

    d = 'M {},{}'.format(v[0][0], v[0][3])
    for i in range(n):
        x, y = v[(i+1)%n]
        d += ' ' + make_A(x, y)
    print('<path d="{}"/>'.format(d), file=fo)

    print('</svg>', file=fo)

draw_poly(3, 175, colour='#eea', filename='reuleaux-3.svg')
draw_poly(7, 175, math.pi/3, filename='reuleaux-7.svg')

One more, an 11-sided Reuleaux polygon:

enter image description here

Current rating: 2.3


There are currently no comments

New Comment


required (not published)