Friday, May 18, 2012

Compass and Straightedge geometry meets HTML5

This is a proof of concept build of an HTML5 engine to perform classical Greek compass and straightedge calculations, as described in this Wikipedia article. In brief, an initial set of points can be created, and then points can be connected by lines, circles can be drawn with one point as center and another as one point in the circumference, and finally the points where circles and/or lines intersect can be added as new points. With those simple rules, angles and line segments can be bisected, and certain regular (equilateral) shapes can be created.

I have created a rudimentary language to describe the adding of points, lines, and circles, and finding their intersections, which I discuss briefly after the demo below. Without further ado, choose a sample "program" to run to bisect an angle or create a regular shape. If you're a fan of Gauss, be sure to check out the heptadecagon.

Display area

Frame delay (ms)

Bisect an angle
Construct a regular triangle

The language

  • point [x] [y] [name]
    This creates a point at canvas position [x,y], and labels it [name]. This is intended only to be used for creating starting points to be used by the remaining commands. In HTML5 canvases, point 0,0 is the upper-left corner, and numbers increase as you move right and down.
  • line [a] [b]
    This draws a line between points a and b.
  • circle [a] [b]
    This draws a circle centered at point a, with point b as a point on the circumference (line ab describes the circle's radius)
  • intersect [circle|line] [a] [b] [circle|line] [c] [d]
    Identify's the intersection points between two circles, two lines, or a circle and a line (for this last combination, specify the circle first). This doesn't add any new points, it just identifies the intersections. A separate "point" command must follow an intersect command to add new points
  • point i [0|1] [a]
    This creates a new point [a] based on the two possible results of the last "intersect" command. You will need to test whether intersect point 0 or 1 is the one you need. In fact, if you're building your own program, you'll want to do several tests as you go. I recommend setting the frame delay to 0 before testing to speed things up.
  • : [text]
    Sets the current "label" in the display area, used for giving the audience an idea about what they're looking at.
  • # [comment]
    Comments in the instructions that aren't shown in the display area


  1. Neat. here's a simpler way to build a regular triangle:

    : Construct an equilateral triangle
    # Initial circle
    point 320 300 O
    point 320 470 P0
    circle O P0

    # Base of triangle
    circle P0 O
    intersect circle P0 O circle O P0
    point i 0 P1
    point i 1 P2
    delete circle P0 O
    delete point P0
    delete point O

    # Top of triangle
    circle P1 P2
    intersect circle P1 P2 circle O P0
    point i 0 P3
    delete circle P1 P2
    delete circle O P0

    # Draw triangle
    line P1 P2
    line P1 P3
    line P2 P3

  2. Nice. The blog entry following this one (4 ways to construct a pentagon) has an improvement to triangle making using this engine, and I also added some features to use a lightbox-ish display for the animation, and comments turn into stopping points, giving the user time to read what's going on before clicking on to the next steps. It's hiding at the very bottom of the post.

  3. Maravilloso y sencillo script Canvas sobre geometría con compás

    Puedo usar el código o parte de él? Que tipo de licencia?

  4. Thanks, Jose. You're welcome to use the code under an LGPL3 license. Also your tumblr page looks very interesting, and makes me wish I spoke Spanish better... or is that Portuguese?

  5. Son pocas palabras. Nos entenderemos (Spanish)

    Yo construí esto y quedó estático

    Ahora con su permiso

  6. I update
    Relative and polar coordinates

  7. Josep, first, sorry for getting your name wrong initially.
    I like the relative and polar coordinate change, very nice!

  8. Jose correct for my friends.

    Would be nice successive relative coordinates
    Your application can evolve much

  9. #draw a reuleaux triangle
    :Draw point A
    point 400 180 A
    :Draw point B
    point 320 315 B
    :Circle from A to B
    circle A B
    :Circle from B to A
    circle B A
    :Find the intersection of the two circles
    intersect circle A B circle B A
    :Label the intersection as D
    point i 1 D
    :Draw a circle centred on D that touches B (it will also touch A)
    circle D B
    :we have a Reuleaux triangle!