Pythagoras Clock

Illustration of Pythagorean triple, 3, 4, 5, and units of time

The traditional clock shows the hour divided into 12 periods of 5 minutes, 6 periods of 10 minutes, 4 periods of 15 minutes ( a quarter of an hour ), 3 periods of 20 minutes, and 2 periods of 30 minutes (half an hour). This neat divisibility is a consequence of the factorizations of the number of hours in a day and minutes in an hour: one day = 12 hours = 3*4 hours – resulting in integer factors of 2, 3, 4 and 6 hours. One hour = 60 minutes = 3*4*5 minutes – resulting in integer factors of 2, 3, 4, 5, 6, 10, 15, 20, 30 minutes. If there were 61 instead of 60 minutes in an hour, then half an hour, a quarter of an hour – none of these would correspond to a whole number of minutes.

There is something else special about these numbers: 3, 4 and 5 make up the least Pythagorean triple: a right angled triangle can be drawn with sides 3, 4, and 5 units long.

A few years ago, I designed the Pythagoras Clock, based on this coincidence.

The clock is powered by an Atmel ATMega168. The clock display is made of laser cut acrylic, housing 19 colored LEDs laid out in two intersecting Pythagorean triangles.

Pythagoras Clock

The two lines in the upper right corner – excluding the diagonal – represent fractions of a day, and the three lines in the bottom left corner plus the diagonal, represent fractions of an hour.

Pythagoras clock with explanatory overlay

When the clock boots, it shows up at 9 o’clock. The following video shows the clock working at increasingly accelerated speed, starting from 9 o’clock:

The top line, of white LEDs, divides each day up into four quarters. If the leftmost of those quarters is lit, then we are in the first quarter of the day, i.e. between twelve o’clock and three o’clock; if the rightmost quarter is lit, then we are in the fourth quarter of the day, i.e. between nine o’clock and twelve o’clock. The orange line on the right edge divides each of those quarters of a day into three thirds. If the topmost of those LEDs is lit, then we are in the first third of the quarter of the day represented by the top line, and if the bottommost is lit, then we are in the last third of the quarter of a day.

In the diagram, the second white LED is lit, meaning the time is between three and six, and the first orange LED is lit, meaning the time is in the first third of that range, i.e. it is four. More mathematically, the hour is 1 x 12/4 + 0 * (12/4)/3 = 4.

Similarly, the bottom line counts time in units of a quarter of an hour, the leftmost line counts time in units of a third of a quarter of an hour (five minutes), and the diagonal counts time in fifths of thirds of quarters of an hour, i.e. minutes.

So in the diagram the hour is 4, as we have already seen, and the minutes are zero quarters (bottom line), two thirds of a quarter (left line), and four fifths of a third of a quarter (diagonal), i.e. 0 x 60/4 + 2 x (60/4)/3 + 4 x ((60/4)/3)/5 = 14.

I am releasing the source code and designs under open source licenses – the source code is available under an MIT license, and the designs are licensed under a Creative Commons Attribution-ShareAlike 4.0 International license. You can download them from Github

The circuit assigns one pin for each LED, and one for the button which is used to set the clock or place it in demo mode.

Pythagoras clock circuit

The clock spent a long time on a proto board, but I finally did get some boards made. If you’d like one let me know.

An assembled circuit for the Pythagoras Clock.

The body of the clock is a sandwich of eight pieces of acrylic, which I cut with a laser cutter at Techshop. The Corel Draw file is on github.

The acrylic cuts.

The LEDs each sit in a little pocket, with a rectangular slit set on top of and to the edge of the pocket.

During assembly of the acrylic.

This gives a uniform rectangle of light.

Light rectangle

Progress deploying Clojure to Google App Engine

I have been struggling for the last couple of days trying to deploy a test Clojure application to Google App Engine, with helpful prods from @perezd. I am using appengine-magic. The HEAD is broken, and the stable 0.5.0 branch has old dependencies. I fixed up some of the breakage in appengine-magic HEAD, coming up with the same solution as this unpulled pull request. Still, that didn’t quite do it. lein appengine-prepare was building a jar which lacked the needed Clojure language dependencies, so when uploaded to App Engine, the app page would just give a 500 error. lein uberjar would build a jar file including those dependencies, so I used that and followed the key steps in appengine_prepare.clj to put the jar in the right place.

Here’s how I finally got it to work:

Add the following to the project.clj file:

:aot [foobar.core, foobar.app_servlet]

Build, prepare and deploy with:

lein compile
lein uberjar
mv target/foobar-0.1.0-SNAPSHOT-standalone.jar war/WEB-INF/lib/ --enable_jar_splitting --oauth2 update war


No Lovejoy

I got up at 6am today to try to catch Comet Lovejoy, which should be visible in binoculars around 30 degrees above the horizon at that time. Unfortunately, seeing was quite bad despite a cloudless sky. I could not even reliably make out ζ Herculis, which has magnitude +2.81, compared to Lovejoy’s current +5 or so.

So, I will have to wait until I am at a darker location. I found a usefulchart, showing Lovejoy’s position throughout December.

Position of Comet Lovejoy 2013 throughout December.
Position of Comet Lovejoy 2013 throughout December.

On Clojure

The longer I work as a software engineer, the more I am convinced that we are doing it completely wrong.

Programming. You're doing it completely wrong.

Really, programming is a lot of typing.

There is a lot of boiler-plate. For example, when you write a for loop, a lot of what you type is for the compiler’s benefit. It has little to do with the expression of an algorithm. Similarly for other constructs.

Related program logic is often broken up and placed in different methods and classes. This is a kind of coupling, which is bad.

Program comprehension and refactoring have limited tool support.

I have wandered through the programming language landscape, as I said above, only increasing my dissatisfaction with mainstream languages. I pondered Scala recently, but the syntax felt a little bulky.

Finally, I come to Clojure! The syntax is minimal – close to lambda calculus, with the additional benefit of rich collection types, variable arity functions, amongst other benefits. Leiningen seems to be a very nice package manager.

I don’t know yet about refactoring tools for Clojure. A little search just now found the following page for visualizing the Clojure core.

Back on the horse!

I had to take down this blog a while ago, because it had been hacked. I removed suspicious php files, changed all the passwords, but took the whole thing offline to be on the safe side.

What has been happening?

Well… I started working for Google as a Software Engineer on the iOS Google+ app.

And I have become very interested in Clojure and in machine learning (and the combination of the two). I just rediscovered Incanter, an R-alike data analysis platform for Clojure.

That is all for now!

Automatic @synthesis and refactoring

With the addition of automatic property synthesis to Objective C, the @synthesize statement is usually no longer necessary. However, the XCode refactoring operation has not been appropriately updated. Renaming ‘foo’ to ‘bar’ in the code below works – the property gets renamed to bar, but it remains linked to an ivar called _foo. Remove the @synthesize statement, however, and refactoring breaks as the implicit ivar will – after refactoring – now be called _bar, but the init body will still try to assign to _foo.

@interface Test
@property id foo;
@implementation Test
@synthesize foo = _foo;
- (id)init {
   if ((self = [super init])) {
      _foo = self;
   return self;

A few useful (for me) Erlang functions for 3D work

Here are some functions I have written for working with 3D points, vectors and angles. If you spot any issues, please let me know.

Copyright (c) 2011, 2012 Julian Richardson

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.


spherical_cartesian( { Phi, Theta, R } ) ->
    { R*sin(Phi)*cos(Theta), R*cos(Phi), R*sin(Phi)*sin(Theta) }.

cartesian_spherical( { X, Y, Z } ) ->
    R = math:sqrt(X*X+Y*Y+Z*Z),
    S = math:sqrt(X*X+Z*Z),
    AZS = if S > 0.0 -> math:asin(Z/S) ; true -> 0.0 end,
    { math:acos(Y/R), if 0.0 =< X -> AZS ; true -> math:pi() - AZS end, R }.

rotate_about_Z(Phi, V) ->
    RotationByPhiAboutZ = { { cos(Phi), sin(Phi), 0.0 }, % was -sin(Phi)
                            { -sin(Phi), cos(Phi), 0.0 }, % was sin(Phi)
                            { 0.0, 0.0, 1.0 } },
    mvmul3(RotationByPhiAboutZ, V).

rotate_about_Y(Theta,V) ->
    RotationByThetaAboutY = { { cos(Theta), 0.0, -sin(Theta) },
                              { 0.0,      1.0, 0.0 },
                              { sin(Theta), 0.0, cos(Theta) } },
    mvmul3(RotationByThetaAboutY, V).

mvmul3( { { A, B, C },
          { D, E, F },
          { H, I, J } },
        { K, L, M } ) ->
    { A*K+B*L+C*M, D*K+E*L+F*M, H*K+I*L+J*M }.

mmmul3( { { A, B, C },
          { D, E, F },
          { H, I, J } },
        { { K, L, M },
          { N, O, P },
          { Q, R, S} } ) ->
    { { A*K+B*N+C*Q, A*L+B*O+C*R, A*M+B*P+C*S },
      { D*K+E*N+F*Q, D*L+E*O+F*R, D*M+E*P+F*S },
      { H*K+I*N+J*Q, H*L+I*O+J*R, H*M+I*P+J*S } }.

smmul3(X, { A, B, C })  ->
    { svmul3(X, A), svmul3(X, B), svmul3(X,C) }.

mdet3( { { A, B, C },
         { D, E, F },
         { G, H, I } } ) ->

svmul2(S, {X,Y}) ->

vvplus2({A,B},{C,D}) ->

vvminus2({A,B},{C,D}) ->

vvplus3({A,B,C},{D,E,F}) ->

vvminus3({A,B,C},{D,E,F}) ->


svmul3(S,{X,Y,Z}) ->
    {S*X, S*Y, S*Z}.

normv3(V) ->

len({X,Y,Z}) ->

vdot2({A,B},{C,D}) ->

vdot3({A1,A2,A3},{B1,B2,B3}) ->

mid3() ->
    { { 1.0, 0.0, 0.0 },
      { 0.0, 1.0, 0.0 },
      { 0.0, 0.0, 1.0 } }.

crossProduct3( { A1, A2, A3 }, { B1, B2, B3 } ) ->
    { A2*B3-A3*B2, A3*B1-A1*B3, A1*B2-A2*B1 }.

vlen3(V) ->
    math:sqrt(distancev3(cartesian, V, { 0.0, 0.0, 0.0 } )).

vlen4({ X, Y, Z, W }) ->

qlen(Q) ->

qnorm(Q) ->
    S = qlen(Q),
    { X, Y, Z, W } = Q,
    { X/S, Y/S, Z/S, W/S }.

angle_between(V1,V2) ->

axis_angle_to_quaternion(V,Angle) ->
    { Ax, Ay, Az } = normv3(V),
    SinA = math:sin(Angle/2.0),
    CosA = math:cos(Angle/2.0),
    qnorm({ Ax*SinA, Ay*SinA, Az*SinA, CosA }).

quaternion_to_matrix(Q) ->
    { X, Y, Z, W } = Q,
    { { 1 - 2 * (Y*Y+Z*Z), 2 * (X*Y + Z*W), 2 * (X*Z - Y*W) },
      { 2 * (X*Y - Z*W), 1 - 2 * (X*X+Z*Z), 2 * (Y*Z + X*W) },
      { 2 * (X*Z + Y*W), 2 * (Y*Z-X*W), 1 - 2 * (X*X+Y*Y) } }.

New open source iOS search project SearchTouch

I just released the first version of SearchTouch, hosted on Github at This is a search engine written in Objective C which compiles and runs on Mac OS X or iOS. It is designed to allow searches to be efficiently carried out on a device.

The code builds an index for a document set consisting of an inverted index for each word in a document set. The index can be stored on the device, and can be efficiently searched to produce a ranked list of every document which contains all of any given set of search terms.

There is a strict separation between the search and indexing code, and the data structures used to store indexes. This separation is mainly achieved by defining the Index class as a class cluster, although a prototcol is also used.

The main storage backend uses Core Data. There is a second back end which is purely in memory using CFTrees.