Intro to (images in) Go – UI

This post is part of a series. For a listing of all the posts, as well as instructions on running the code, see here.

A few posts back, we looked at how to set up a simple HTTP server and also how to communicate with a web page using WebSockets. Today we’ll combine this with the fractal generation code we looked at last time to make an application, with the backend powered by Go, while the frontend is displayed using web technologies.

Here’s what we’ll wind up with, if all goes well:
Fractal app

Why do this?

While Go was originally meant as a systems programming language, people have started using it for other things. However the standard library does not include a UI layer. Using HTML/CSS/JavaScript gives us the flexibility to deploy on any platform that can run a web browser, and gives us the flexibility to separate our client from the server, if that model fits our use case better.

Missing pieces

It turns out that the code in the WebSockets post almost did everything we needed to make a functional application. The two bits missing were:

  • A way to send messages from UI layer back to the Go application
  • A sane way of sending large images to the client. Pixel-by-pixel just isn’t going to cut it

Fractal 1

Talking to Go

With our WebSockets transport up and running, sending a message from the client is dead simple:

ws.send( "READY" );

While in our handler on the Go end, we’d receive this like so:

func UIHandler(ws *websocket.Conn) {
  for {
    var msg string
    websocket.Message.Receive(ws, &msg)
    fmt.Println("Message:", msg)
  }
}

Our application is going to display a fractal image and let us zoom in and out, re-center the image and change the gradient. For each of these, we’ll send a command to the server and it will generate a new fractal for us, which we will then display.

Once we’ve got one of these functions working, the others will be easy, and follow the same pattern.

Building the UI

For now, let’s focus on zooming. As before we’ll use a Canvas tag to display the fractal image. To control zooming we’ll have two buttons, making our HTML look something like this:

<body>
    <h2>Fractal Explorer</h2>
    <canvas id="canvas" width="512" height="512">
        Sorry, your browser does not support Canvas
    </canvas>
    <hr>
    <button id="zoomin">Zoom in</button>
    <button id="zoomout">Zoom out</button>
</body>
</html> 

To actually make our buttons do something, we’ll need to add listeners to them using JavaScript, e.g. zooming in:

var zoomInBtn = document.getElementById( "zoomin" );
zoomInBtn.addEventListener( "click", function() {
  ws.send( "ZOOMIN" );
});

Then on the Go end, we’ll need to handle this message, so we modify our handler to:

func UIHandler(ws *websocket.Conn) {
  for {
    var msg string
    websocket.Message.Receive(ws, &msg)

    // Parse message
    fields := strings.Fields(msg)
    cmd := fields[0]
    if cmd == "ZOOMIN" {
      zoom *= 2.0
    }

    // Draw fractal and send to client
  }
}

OK great, we can now control our Go code with a click of a button. How about drawing that fractal?

Fractal drawing

The fractal post gave us a function to draw a fractal based on some parameters:

drawInvMandelbrot(canvas, zoom, center, colorizer)

I actually re-factored the code a bit and moved it into a separate file, to make it easier to use from different projects. So given a canvas, we can use this function to draw a fractal at an arbitrary zoom level, center and gradient.

Fractal 2

All that remains is sending the fractal to the client. Previously, we sent images pixel by pixel, using a command like PIXEL 4 5 #ff0000, which worked fine for plotting graphs, but was slow for a large image. Based on a suggestion by cryptix, I’ve instead opted for sending the image encoded as a base64 string, and then drawing it onto the Canvas in one go. To do this, I’ve added a method to the Canvas (in Go) class:

func (c *Canvas) ToBase64() string {
  imgBuf := new(bytes.Buffer)
  imgEncoder := base64.NewEncoder(base64.StdEncoding, imgBuf)
  png.Encode(imgEncoder, c)
  imgEncoder.Close()
  return imgBuf.String()
}

With this in place we can now send the entire contents of our Canvas in Go to our JavaScript frontend:

drawInvMandelbrot(canvas, zoom, center, colorizer)
drawMsg := fmt.Sprintf("DRAW %s", canvas.ToBase64())
io.WriteString(ws, drawMsg)

Notice, that rather than using the PIXEL command, we’ve added a new DRAW command. To make our client understand this new command and to draw the image to the HTML Canvas, we’ll do:

ws.onmessage = function( e ) {
  var data = e.data.split("\n");
  for ( var line in data ) {
    var msg = data[line].split(" ");
    var cmd = msg[0];
    // ...other commands
    } else if ( cmd == "DRAW" ) {
      var imgData = msg[1];
      var img = new Image();
      img.src = "data:image/png;base64," + imgData;
      ctx.drawImage( img, 0, 0 );
    }
  }
}

Capturing mouse clicks

So now we have the full loop, the app displays a fractal, the user clicks a button, the server receives this input, draws a new fractal and sends it back to the client, ready for the virtuous circle to begin again.

Adding more functionality is now more or less repeating what we’ve already done. For changing the gradient used, we’ll add a few buttons, add click handlers and send the relevant message to the server for processing.

Re-centering the fractal is a little different, so I’ll pull it out specifically here. Rather than using a simple on click handler, we’ll want to detect where the user has clicked in the HTML Canvas:

canvas.addEventListener( "mousedown", function(e) {
  ws.send( "MOUSEDOWN " + e.offsetX + " " + e.offsetY );
});

Which will send a message of the format MOUSEDOWN 4 12 when the user clicks on the Canvas 4 pixels from the left, and 12 from the top. As this will arrive as a string on the Go end, we’ll want to parse integers using the strconv package:

fields := strings.Fields(msg)
cmd := fields[0]
// ...other commands
} else if cmd == "MOUSEDOWN" {
  x, _ := strconv.ParseInt(fields[1], 10, 0)
  y, _ := strconv.ParseInt(fields[2], 10, 0)
  // ...

Fractal 3

Finished

And that’s more or less it. To play around with the full app, check out the source on github for the server, as well as the client. To run the app, execute go run ws_fractals.go mandelbrot.go canvas.go vector.go, and then navigate to http://localhost:1234/ui.html in your browser.

The app we built today was designed for displaying fractals, but because the web client is so thin, the same code could be reused for other applications, by modifying the Go code, but keeping the web client more or less the same.

For example, you could switch out the gradient images for thumbnails of pictures, and you’d have an image browsing application. Or rather than just capturing mousedown events, we could also capture when the mouse moves, and use this to draw on the Canvas.

Finally, by splitting our business and display logic like we have, we can style our app using CSS without worrying that the Go backend will be affected.

Intro to (images in) Go – fractals

This post is part of a series. For a listing of all the posts, as well as instructions on running the code, see here.

The last couple of posts have been more about laying some foundations on how to graphically display output from our Go program in real-time, and have focused primarily on the networking side of things. So I thought it was probably only fair to play around some more with pretty pictures. Here’s one:

Fractal

Fractals

If you’re mathematically inclined, you should recognize this as a fractal. If you’re mathematically obsessed, you will recognize this as the Mandelbrot set at -0.71 + -0.25i.

For a full description of what the Mandelbrot set fractal is, have a read on Wikipedia, but all you really need to know for the purposes of this post is that is visualization of collection of complex numbers. Specifically, for each number c in the field we want to know if the following expression remains bounded when we iterate it:

z = z * z + c

Depending on how quickly this expression diverges (or doesn’t) we will set the color of a pixel corresponding to c. The code for calculating c will look something like this:

z := complex(0, 0)
for i := 0; i < iter; i++ {
  z = z*z + c
}
return cmplx.Abs(z)

Actually, it will look exactly like that, as Go helpfully comes with complex numbers included.

Don’t worry if you don’t understand complex numbers, the above code is pretty much the only place the are used. Every time a complex number c is passed in that code will spit out a magnitude which corresponds to a color on our image, e.g. a low value might be black, while a high value white.

OK, so now we know how we’ll calculate the value for a single complex number, how do we get from there to a pretty picture? Like this one:

Fractal

Coordinate systems

At a high level, we’ll want to create a Canvas, and then iterate over every pixel in that canvas, calculating the value to which our Mandelbrot expression diverges to. However, there are two other parameters that we need to pass in. To be able to pan around the fractal and zoom into it, we need to also specify the zoom and the center.

The zoom parameter corresponds to how many pixels we should draw per unit in the complex plane. So a factor of 10 means that in the range 0 -> 1 we will have 10 pixels.

The center parameter is the offset of our Canvas. In other words what value of c should the pixel in the middle of our Canvas correspond to.

Converting between a coordinate x, y in our Canvas at zoom level zoom, centered at center is fairly straightforward, we just scale linearly by zoom and then add on the center coordinate:

func toCmplx(x, y int, zoom float64, center complex128) complex128 {
  return center + complex(float64(x)/zoom, float64(y)/zoom)
}

Now we’re ready to draw:

zoom := 100.0
center := complex(-0.21, 0.25)
size := canvas.Bounds().Size()
for x := 0; x < size.X; x++ {
  for y := 0; y < size.Y; y++ {
    c := toCmplx(x-size.X/2, y-size.Y/2, zoom, center)
    mag := mandelbrot(c, 50)
    color := colorizer(mag)
    canvas.Set(x, y, color)
  }
}

Simple. The only subtlety is that when we pass in out x and y values, we need to measure them relative to the center of the Canvas, which is why you’ll see x-size.X/2 and y-size.Y/2.

However, one piece is still missing: how do we go from a magnitude value to a color?

Fractal

Colorizer

The simplest way to go from a value to a color is to just map the value directly to a color channel, e.g. 0 is black and 100 is red. However this makes for boring looking images. Much better is to create a gradient image and use that to assign the colors. These gradients can easily be created in most image editing programs, or you can use one of these.

Gradients

We already know how to load in images from earlier posts, but to streamline it I’ve created a utility method to create a Canvas directly from a filename. Check out canvas.go for details.

Now onto making that colorizer. As the function is pretty simple, rather than creating a whole new type, we’ll just use the closure support in Go to create a function using another function. Specifically, we’ll have a createColorizer function which we’ll pass a filename for our gradient, and it will return a function, colorizer(mag float64) which we’ll actually use for generating the correct colors.

func createColorizer(filename string) func(float64) color.Color {
  gradient := CanvasFromFile(filename)
  limit := gradient.Bounds().Size().Y - 1
  return func(mag float64) color.Color {
    // Clamp magnitude to size of gradient
    m := int(math.Max(math.Min(300*mag, float64(limit)), 1))
    return gradient.At(0, m)
  }

Really all the colorizer does is that it takes the value of the magnitude mag and looks up the color of the pixel corresponding to that value in the gradient image. There is also a bit of code that ensures that we don’t try and look up pixels outside the bounds of the gradient.

One thing to note is that we are accessing gradient inside the colorizer function, even though it is defined in createColorizer. The value of gradient has been bound in the closure of the returned func, so we can use it every time we want to color a pixel, however we will not have to read in the gradient image file again and again.

This is different from if we had defined gradient as a global variable. Because it is in the closure, we can create multiple colorizers with different gradients and they will each hold onto their own instance of the gradient variable. E.g. the following will produce two independent colorizers:

c1 := createColorizer("gradient1.png")
c2 := createColorizer("gradient2.png")

Fractal

Playing around

To create some fractals of your own, check out the code on github.

To run the code, use go run fractal.go canvas.go vector.go

All the logic has been bundled up into a drawFractal function, which you can pass a zoom, center and a colorizer, and experiment with what comes out. I find it’s best to start zoomed out and center the image on what looks to an interesting location. Then increase the zoom and refine the center, until you get to an image you like.

Fractal

Once you’ve found an interesting region, try recoloring with different gradients. You can also increase/decrease the number of iterations the mandelbrot function is to do before returning, which will control the level of detail present in the image.

Fractal

Intro to (images in) Go – websockets

This post is part of a series. For a listing of all the posts, as well as instructions on running the code, see here.

In the last post we looked at how to set up a HTTP server, to serve up an API or static files. Today we’ll do something more real-time, namely using WebSockets to stream data from our Go program and display it visually on a HTML5 Canvas element.

Hello WebSockets

You’ve likely already heard of WebSockets, a mechanism for essentially opening up a socket between the server and browser, to allow real-time two-way communication. To use them in Go, we’ll first need to import code.google.com/p/go.net/websocket and then write the following to get the standard echo server up and running:

func WebsocketHandler(ws *websocket.Conn) {
  io.Copy(ws, ws)
}

func main() {
  router := mux.NewRouter()
  router.Handle("/ws", websocket.Handler(WebsocketHandler))
  staticHandler := http.FileServer(http.Dir("."))
  router.PathPrefix("/").Handler(staticHandler)
  http.ListenAndServe("localhost:1234", router)
}

We’re using Mux like last time, although it isn’t really necessary – more to show that we can. Note that we have also added a handler for serving static files, using the same router as we have for WebSockets, and it happily works all together.

Now we need some sort of client to test out that this works. Naturally we could write this in Go, but given that our goal is to communicate with the browser, let’s do it in JavaScript:

function wsConnect()
{
  ws = new WebSocket( wsUri );
  ws.onopen = function( e ) {
    console.log( "CONNECTED" );
    ws.send( "READY" );
  };
  ws.onclose = function( e ) { 
    console.log( "DISCONNECTED" );
  };
  ws.onmessage = function( e ) {
    console.log( "MESSAGE: " + e.data );
  };
  ws.onerror = function( e ) {
    console.log( 'WS Error: ' + e.data );
  };
}

Not much here, really. We create a WebSocket, and register some handlers that just print out what is flowing over WebSockets to the console. We then kick off a send once the WebSocket is connected. If you launch the ws_echo_server.go example using go run ws_echo_server.go and navigate to localhost:1234/wsecho.html, you should now be able to play around with WebSocket using your browser’s console. You can try sending a message by entering something like: ws.send("hi!").

Sending an image

OK, so with that in place lets send something more interesting. Rather than just echoing back the message lets have the server stream pixels to the browser and have that display them on a HTML5 Canvas element. We’ll use a format like this to send the messsage:

PIXEL x y color

Where PIXEL is the name of the command to the client for drawing a single pixel, x and y are the coordinates, and color is the color to draw. So a message may look like so:

PIXEL 13 74 #ff23e1

Why not try to use this to send an image? Well actually it is a pretty terrible idea sending an image pixel by pixel, over WebSockets – but thats not reason not to try. We’ll need to modify our handler so that we have:

func GradientHandler(ws *websocket.Conn) {
  width, height := 200, 200
  canvas := NewCanvas(image.Rect(0, 0, width, height))
  canvas.DrawGradient()
  for x := 0; x < width; x++ {
    for y := 0; y < height; y++ {
      r, g, b, _ := canvas.At(x, y).RGBA()
      color := fmt.Sprintf("#%02x%02x%02x", r/0xFF, g/0xFF, b/0xFF)
      msg := fmt.Sprintf("PIXEL %d %d %s\n", x, y, color)
      io.WriteString(ws, msg)
    }
    time.Sleep(time.Second / 30.0)
  }

And now for the client, we’ll modify the onmessage function to draw to a Canvas element:

ws.onmessage = function( e ) {
  var data = e.data.split("\n");
  for ( var line in data ) {
    var msg = data[line].split(" ");
    var cmd = msg[0];
    if ( cmd == "PIXEL" ) {
      var x = parseInt(msg[1]);
      var y = parseInt(msg[2]);
      var color = msg[3];
      ctx.fillStyle = color;
      ctx.fillRect( x, y, 1, 1 );
    } else {
      console.log( "Unknown command: " + cmd );
    }
  }
};

To try it out have a look at the server and client on github. To run, use go run ws_canvas.go canvas.go vector.go and navigate to localhost:1234/wscanvas.html. You should wind up with a progressively loading gradient image, which’ll eventually look like this:

Gradient

Streaming data

Lets now try our hand at some animation. What we’ll do is stream a new set of pixels to the client on every frame and have it redraw the content on the canvas. To make sure we don’t draw on top of what is already there, we’ll need to add rather trivial extension to our protocol, namely a CLEAR command. Check the source for the JavaScript implementation. Our new Go handler, meanwhile will look like this:

func GraphHandler(ws *websocket.Conn) {
  width, height := 512, 512
  t := 0.0
  for {
    msg := "CLEAR\n"
    for x := 0; x < width; x++ {
      y := height/2 + int(50 * math.Sin(t/10) * math.Sin(float64(x)/10.0 + t))
      y2 := height/3 + int(60 * math.Sin(t/9) * math.Sin(float64(x)/20.0 + 2.0 * t))
      msg += fmt.Sprintf("PIXEL %d %d %s\n", x, y, "#ff0000")
      msg += fmt.Sprintf("PIXEL %d %d %s\n", x, y2, "#00ff00")
    }
    t += 0.3
    io.WriteString(ws, msg)
    time.Sleep(time.Second / 30.0)
  }
}

We iterate from the left to right of the image, and set pixels based on some mathematical equation. By including a time variable t we make the equations change over time. Another thing to notice is that rather than sending each command separately, we’ve added functionality in the client to receive multiple messages at once, i.e. the following will now work as a single message:

CLEAR
PIXEL 0 1 #00ff00
PIXEL 0 2 #00ee00
PIXEL 0 3 #00dd00
PIXEL 0 4 #00cc00

You can run this example in the same way as the gradient one above, just be sure to switch the handler that is registered with the router in the main function.

If all is well you should see some jolly sine curves dancing across your screen. Here’s a static screenshot:

Sine curve

Concurrency

One thing that is I didn’t mention before, is that this http server that we have built is taking advantage of Go’s concurrency. Namely the http module runs our handlers in a concurrent manner and as such we can load up multiple clients and have them all display the animation at the same time. We could even go further and use the input from one window to influence the output in other, by using channels to communicate between the handlers.

Intro to (images in) Go – http

This post is part of a series. For a listing of all the posts, as well as instructions on running the code, see here.

So far, we’ve pretty much always been using Go to spit out static image files. However, it’d be nice if we could do something a little bit more interactive, like generate images based on user input and the like. So here’s the plan:

  • We’ll look at how to put together a HTTP server first
  • Then we’ll add in some websockets for realtime communication with our Go code
  • And finally we’ll use the HTML5 canvas to display our creations

Today we’ll just take a look at the HTTP server, in the process explaining how to build API handlers, serve static files and “decorate” functions. So sorry, no piccies today.

Basic HTTP server

Getting a simple HTTP working in Go is a piece of cake – it is even included as part of the Tour of Go . To make things more interesting and to give ourselves more flexibility in the future we’ll also reach for a third-party component to make routing requests cleaner and easier to write. Mux is that badger, letting us define route handlers using regular expressions and more. If you’ve used Sinatra or Flask, this should be familiar.

To fetch the Mux code, use go get github.com/gorilla/mux. Once that is done, here’s is how you’d use it:

import (
  "io"
  "net/http"

  "github.com/gorilla/mux"
)

func HelloHandler(writer http.ResponseWriter, request *http.Request) {
    io.WriteString(writer, "hello!")
}

func main() {
  router := mux.NewRouter()
  router.HandleFunc("/hello", HelloHandler)
  http.ListenAndServe("localhost:1234", router)
}

There we are, one http server. Try running it and navigating to localhost:1234/hello. A few things to notice:

  • When importing the mux package, we use the full package name.
  • In the main function we create a router object and register the HelloHandler function on it, with an associated route: "/hello"
  • The HelloHandler takes 2 arguments, a writer into which we send the response and the request itself, which we can examine, e.g. to see what headers were set.

Parsing the URL

The power of Mux is that it makes it easy to parse out pieces of the URL. So if we’d like to say hello, based on the user’s name we could do:

router.HandleFunc("/hello/{name}", HelloHandler)

And then in the handler access the variables using mux.Vars():

vars := mux.Vars(request)
io.WriteString(writer, "hello " + vars["name"] + "!")

There’s much more that Mux can do, check out their docs if curious.

Serving static files

For writing an API the above is great, but what if we want to serve static files? Luckily for us, the Go library come with a FileHandler ready to go. Adding it in is just one line:

staticHandler := http.FileServer(http.Dir("."))
router.PathPrefix("/").Handler(staticHandler)

(Well, two lines. But it could be one. Rest assured, all will be explained)

The staticHandler will take the part of the route requested after the "/", and try to serve that file if it exists in the current directory. For example http://localhost:1234/sweet_goat.jpeg will return the file sweet_goat.jpeg found in the directory the code is running from. This router is then registered with our Mux router object, which will send any requests that match to it – in this case everything will match as we’ve entered "/".

There is one subtlety here though: what if we wanted to serve our static content at http://localhost:1234/static? Easy, we’d change the PathPrefix argument above from "/" to "/static/", right? Well, not quite.

The trouble is that if we do this then while our router will correctly recognise that we have navigated to /static/file, our FileServer does not know that it should throw away the static part of the URL when handling the request and tries to find the file in the static directory on its filesystem, which does not exist. To remedy this, we need some sort of way to strip out the prefix before passing the request onto the FileServer.

Again, luckily for us, the standard library comes to the rescue:

staticHandler = http.StripPrefix("/static/", staticHandler)

See here for a working example

Decorating a Handler

It’s worth taking a look at the source of the StripPrefix function. What it is doing, is wrapping the staticHandler function in another function and then returning that. For those of you know Python, this is more or less the same as decorating a function, except without the syntactic sugar.

To really understand the concept, lets create a “decorator” of our own. Specifically, let’s modify a Handler so that we set the headers in such a way to instruct a web browser to not cache our data. I find this pretty useful during development, when I want to be sure I’m running the latest code.

So, here’s our decorator:

func NoCacheDecorator(h http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
    w.Header().Set("Pragma", "no-cache")
    w.Header().Set("Expires", "0")
    h.ServeHTTP(w, r)
  })
}

Which we’ll apply to an existing Handler like so:

staticHandler = NoCacheDecorator(staticHandler)

First off, notice what it is that we’re actually returning. We are defining a function, and then calling http.HandlerFunc on it. This is just a convenient way of converting our function into a Handler object. The function itself, takes the request that will be passed onto the Handler we are decorating (in this example staticHandler) and modifies some of the headers. It then passes the request onto the decorated Handler, by invoking its ServeHttp method.

You can verify this is working by using something like the Chrome develop tools to examine the headers on the response.

One nice feature about the decorator pattern is that we can stack multiple decorators on top of each other and things will work (as long as the decorators do not interfere functionally). In fact, that is exactly what we’ve done. We’ve created a bog standard FileHandler, decorated it once using StripPrefix and then again using NoCacheDecorator. The result is a file handler which knows to strip off the correct prefix, and set the correct no caching headers.

Check out the code on github for a working example. Run using go run simple_server.go

Intro to (images in) Go – concurrency

This post is part of a series. For a listing of all the posts, as well as instructions on running the code, see here.

Turns out that despite all the shilly-shallying in the previous posts, we didn’t talk about one of Go’s most useful features, built-in concurrency implemented using go-routines and channels. Today seems like as good a day as any to give it a shot.

Concurrency in Go

Concurrency in Go is really pretty simple, when invoking a function we want to run in parallel to the execution flow, we just use the go keyword before the method invocation:

speak() // call the speak function and return when done
go speak() // create a go-routine in which speak run, returning immediately

To communicate between go-routines, channels are used. A channel is a typed conduit, which is most easily understood by means of an example:

var ch = make(chan string)

func speak() {
  s := <-ch
  fmt.Println(s) 
}

func main() {
  go speak()
  ch<-"hi"
}

First off, we create a channel ch with the type string. The speak function waits for input from this channel, and prints anything it receives before returning.

In the main function, we create a go-routine with go speak. Once this is done, our speak function is executing in parallel with our main function, until it reaches the point where it encounters <-ch. It then pauses waiting for input on the channel. The main function meanwhile gets around to sending something down the channel ch. When this happens, the speak function continues executing, jovially printing out “hi”.

Shoehorning in some image processing

I’ll be honest, it was a bit of a challenge to think of nice clean example of how to use concurrency to generate an image. So instead, here is something a little more convoluted: imagine a network of nodes (e.g. towns on a map) where each nodes is connected to the 5 nearest nodes. This might look something like this:

Network

I won’t go into the full details of how this is set up, as it’ll distract from talking about concurrency. The full nodes.go source is on github if you’re interested and want to play around with the parameters.

The important part is the Node object, which is defined as follows:

type Node struct {
  Position Vector
  Ch       chan *Node
  Peers    []*Node
  Canvas   *Canvas
  Power    uint8
}

So, each Node has a position, a channel to receive messages from other nodes on, a set of nearby peers and a power value.

To demonstrate concurrency, what we’ll do is hook up each Node, so that when it receives a message from another node, it will draw a line onto the canvas to visualize this. It will then send a message onto another node (that has yet to receive the message). The power is simply a way of keeping track of which nodes have been visited and showing how far a message has travelled.

Here’s an example of such a message propagating through a 50 node network:

Single message

The message starts off in yellow, and changes to red as it loses power with every step.

How does this work then?

Of course it would be possible to write this in a non-concurrent way, but that would be no fun. In our setup, no Node has a full understanding of the network as a whole, and only knows how to blindly send on messages to its peers. However, put together this suffices for the message to traverse the network. Here’s the relevant code:

func (n *Node) Listen() {
  // Listen for incoming connection on node's channel
  for {
    peer := <-n.Ch
    peer.Power -= 5
    n.Power = peer.Power
    n.Canvas.DrawLine(color.RGBA{255, n.Power, 0, 255}, n.Position, peer.Position)
    // Retransmit to random node
    if n.Power > 0 {
      go n.Send()
    }
  }
}

func (n *Node) Send() {
  for _, target := range n.Peers {
    if target.Power == 0 {
      target.Ch <- n
      break
    }
  }
}

Once you get your head around channels, there really isn’t much here. The Listen method just sits there, waiting for an incoming connection on n.Ch. Once it receives it, it decrements the Power, draws the line and sends a new message using Send(). Send is even simpler, it picks a peer that has yet to receive a message and sends a message to its channel Ch.

Let’s get things going

With all our nodes primed and ready for signals all that remains is to power up one Node and instruct it to send a message.

    node.Power = 255
    go node.Send()

Now we can have some fun fiddling with the parameters and seeing what results we get. One thing that is pretty neat is that we can concurrently kick off multiple signals from different nodes and have them propagate the network at the same time.

Here’s the same 50 node network as before, but with 10 messages propagating, note how some messages get cut off by others and are forced to die early.

10 messages

Or why not have 2500 nodes and see what happens?

2500 nodes

Or if that seems like too little, how about 25000?

25000 nodes

Fat-free threading

For the 25000 example above, the simulation ran no slower than when there were 100 nodes (although the initial network calculation is slow there). Go-routines are by design very light-weight, and this makes Go a great choice for writing concurrent code, e.g. for web servers.

As always, be sure to check out the full code on github

Structuring large three.js applications with amd-three.js

Recently I’ve been building something using Three.js, and started out by basing my code on one of the many excellent examples. Soon enough I was in a world of bliss, full of lights and shaders and all the other niceness gives you.

Unfortunately, my JavaScript code quickly started to get a bit bloated and hard to navigate, and I decided that it was to time to split up my code into separate files and modules to make it more manageable. I couldn’t find much guidance on how others had done this in the past, so I decided to roll my own solution using Require.js. The result is amd-three.js, with a live example here.

amd-three.js is meant as a starting point for more involved projects involving three.js, where having all the code in one file can quickly get unwieldy. It is also useful for prototyping, as a lot of the boilerplate is moved out of your way.

Require.js in 29 seconds

If you haven’t come across Require.js, it is a JavaScript module loader. With it you can split your code into modules, passing in dependencies and having Require.js figure out how to link stuff up for you.

A module, container.js might look like this:

define( ["three"], function( THREE ) {
  return document.getElementById( 'threejs-container' );
} );

…while a module that includes container.js like this:

define( ["three", "container"], function( THREE, container ) {
  // do something with container
} );

That should give you enough of an idea of what Require.js does, for more detail see http://requirejs.org

amd-three.js structure

Following Require.js convention, the JavaScript file structure is like so:

/js/
  |--require.js
  |--main.js
  /app/
    |--app.js
    |--camera.js
    |-- other app files
  /lib/
    |--three.js
    |--three.min.js
    |-- other three.js components

main.js

This is the entry point into the code, where we configure require.js and start the app.

/app/app.js

Here we have the meat of the app, with two methods init() and animate(), which main.js will call for us to get the app running.

/lib/

The lib directory is for storing the three.js library and extensions. More on this below.

app.js

When you first check out the amd-three.js source, the first place you’ll likely want to go to make modifications is /app/app.js. Here’s how it might look:

define( ["three", "camera", "geometry", "light", "material", "renderer", "scene"],
function( three, camera, geometry, light, material, renderer, scene ) {
  var app = {
    mesh: new THREE.Mesh( geometry["cube"], material["grass"] ),
    init: function() {
      scene.add( app.mesh );
      light.target = app.mesh;
    },
    animate: function() {
      requestAnimationFrame( app.animate );
      app.mesh.rotation.x += 0.005;
      renderer.render( scene, camera );
    }
  }
  return app;
} );

As you can see, quite a few dependencies are being passed in. These are all located in files with corresponding names, e.g. the source to the camera object is in app/camera.js.

The above code first creates a mesh (app.mesh) from a geometry (geometry["cube"]) and a material (material["grass"]). The init method then adds it to the scene and points the light at it. Finally, the animate method rotates our mesh and tells our renderer to render.

Singletons

The modules that we depend on in app.js also have dependencies, and it is often the case that these dependencies are shared with app.js. For example, light.js needs to know about the scene so that it can add itself to it:

define( ["three", "scene"], function( THREE, scene ) {
  var light = new THREE.DirectionalLight( 0xff3bff );
  light.position.set( 0, 0, 300 );
  scene.add( light );
  return light;
} );

An important thing to realize is that the scene object being passed in here is the same scene object that app.js receives – as Require.js only initializes the modules once. As such, we can be sure that the light will shine on the same scene that we later add the mesh to.

Bundling up three.js

Unfortunately, three.js currently doesn’t come as an AMD module and as such we need to build a shim around it, so we can include it in other modules. For details on how this is done, see the Require.js documentation. One thing to note is that the /lib/three.js file is used to bring together all of the Three.js components, so that we don’t have to inject them all separately every time we want to use Three.js.

Also, the shim does not remove the THREE object from the global namespace, so technically we don’t need to pass it in as an explicit dependency into our modules. However, it good for future compatibility to do so, so that our code continues to work when an AMD-compliant Three.js module does appear.

…well?

I’d love to hear from others who have created larger projects with Three.js about their experiences, and views on this approach. Be sure to check out the code on github as well as the live example

Intro to (images in) Go – filters

This post is part of a series. For a listing of all the posts, as well as instructions on running the code, see here.

Recently I came across a most agreeable app, Instagram, that lets you add filters and what-not to your photos, and I thought it would be remiss not to try something similar in Go. And while we’re at it, why not introduce the concept of Interfaces.

Goat

Let me introduce you to a sweet goat.

Sweet goat

Personally, I like this picture as it is, but I’m told to that to appeal to Generation Z, we need to apply a filter before it is deemed worthy for wider circulation. A blur filter seems the obvious choice.

Blur

At a high level, blurring an image consists of, for each pixel p:

  1. Retrieving the neighbouring pixels in the vicinity of p based on some criteria, e.g. pixels no more than 5 pixels away from p
  2. Combining the values from the neighbouring set of pixels, assigning a weight to each pixel based on some function, e.g. the further away we are from p, the lower the weight
  3. Normalising our value, by diving by the sum of the weights used in the previous step
  4. Assigning the normalised value to the corresponding pixel in the blurred image

For now, let’s not worry about the weighting function, and just assign each neighbouring pixel the same weight – also known as Box Blur. This will allow us to focus on the underlying algorithm more easily.

Box Blur

We’ll want to extend the Canvas type with two new methods, Blur and BlurPixel. The first will actually perform the blurring on the image, while the second is used as a helper to calculate the blurred value for a single pixel.

Blur is pretty straightforward, it creates a copy of the canvas, then fills it in, pixel by pixel, by applying the BlurPixel function to each pixel in the original canvas:

func (c Canvas) Blur(radius int) {
  clone := c.Clone()
  size := c.Bounds().Size()
  for x := 0; x < size.X; x++ {
    for y := 0; y < size.Y; y++ {
      color := c.BlurPixel(x, y, radius)
      clone.Set(x, y, color)
    }
  }
  copy(c.Pix, clone.Pix)
}

BlurPixel is more interesting:

func (c Canvas) BlurPixel(x int, y int, radius int) color.Color {
  weightSum := float64(0)
  size := c.Bounds().Size()
  outR, outG, outB := float64(0), float64(0), float64(0)
  for i := x - radius; i < x+radius+1; i++ {
    for j := y - radius; j < y+radius+1; j++ {
      r, g, b, _ := c.At(i, j).RGBA()
      outR += float64(r)
      outG += float64(g)
      outB += float64(b)
      weightSum += 1.0
    }
  }
  // Need to divide by 0xFF as the RGBA() function returns color values as uint32
  // and we need uint8
  return color.RGBA{
    uint8(outR / (weightSum * 0xFF)),
    uint8(outG / (weightSum * 0xFF)),
    uint8(outB / (weightSum * 0xFF)),
    255}
}

This is more or less steps 2. and 3. that are listed above. Note that some edge case handling has been omitted for clarity. To see the function in full check out canvas.go

Applying this to our charming, yet long-suffering goat, we get:

Box blurred goat

One thing to note is that for a given radius, we need to retrieve radius * radius pixels when running BlurPixel, and as such the running time gets pretty slow for large values of radius. Anything under 10 should easily be fine though.

For an example of how to load in an image and apply the Blur function to, see the blur.go example on github.

Interfaces and Weighting functions

It’s now time to add in a weighting function, to allow us to perform different types of blur effects. Given that the rest of of the blurring algorithm stays the same, it seems natural to pass the weighting type as a parameter in the BlurPixel method. To do this, we’ll define an Interface for what we expect our weighting type to do, and then our BlurPixel method will know what methods it can call on the type. Here goes:

type WeightFunction interface {
  Weight(x int, y int) float64
}

And the accompanying Box Blur implementation of this interface:

type WeightFunctionBox struct{}

func (w WeightFunctionBox) Weight(x int, y int) float64 { return 1.0 }

To clarify, the x and y parameters passed to the Weight function are relative to the pixel being processed. So with this in hand we can modify our BlurPixel function to:

func (c Canvas) BlurPixel(x int, y int, radius int, weight WeightFunction) color.Color {
  weightSum := float64(0)
  size := c.Bounds().Size()
  outR, outG, outB := float64(0), float64(0), float64(0)
  for i := x - radius; i < x+radius+1; i++ {
    for j := y - radius; j < y+radius+1; j++ {
      weight := weight.Weight(i-x, j-y)
      r, g, b, _ := c.At(i, j).RGBA()
      outR += float64(r) * weight
      outG += float64(g) * weight
      outB += float64(b) * weight
      weightSum += weight
    }
  }
  // Rest of function...

An important thing to note is that when defining our WeightFunctionBox type, nowhere did we explicitly state that we were implementing the WeightFunction interface. This is because in Go interfaces are satisfied implicitly, that is: any object which implements the methods of an interface, implements the interface. This puts Go somewhere between Java (where you have to explicitly implement an interface) and JavaScript (where you can pass whatever the hell you like around as there are no interfaces, but things will go wrong if your mystery object doesn’t implement a method that you expect it to).

To see how this all fits together into a working example, see the blur.go and canvas.go files on github.

More weighting functions

If we pipe through the weight variable through to the Blur method, we can easily apply different types of blur to a Canvas, e.g.

canvas.Blur(5, new(WeightFunctionBox))

We can now have some fun experimenting with different weighting functions. Here are a couple of examples, along with the results:

func (w WeightFunctionDist) Weight(x int, y int) float64 {
  d := math.Hypot(float64(x), float64(y))
  return 1 / (1 + d)
}

Dist blurred goat

func (w WeightFunctionMotion) Weight(x int, y int) float64 {
  if y != 0 {
    return 0
  }
  if x < 0 {
    return 0
  }
  return 1 / (1 + float64(x))
}

Motion blurred goat

type WeightFunctionDouble struct{
  split int
}

func (w WeightFunctionDouble) Weight(x int, y int) float64 {
  if y == 0 && (x == w.split || x == -w.split) {
    return 1.0
  } else {
    return 0
  }
}

Double blurred goat

Intro to (images in) Go – drawing

This post is part of a series. For a listing of all the posts, as well as instructions on running the code, see here.

In the previous post we looked at how to create a Canvas type onto which we could draw a gradient.

While gradients are all fun and games, to really start drawing we need to be able to draw lines onto our canvas. To do this we’ll need some way of representing points on the canvas. The image type in Go comes with a Point type, however this takes it’s coordinates as integers and to represent lines exactly we’ll want to work with floating point types.

Vector type

Defining a Vector type is pretty straightforward:

type Vector struct {
  X, Y float64
}

We’ll also want some utility methods to allow us to add or subtract vectors, get their length, and rotate and scale them. Here is how we’d add the Rotate function (the rest can be seen in the code example on github):

func (v *Vector) Rotate(angle float64) {
  cos, sin := math.Cos(angle), math.Sin(angle)
  v.X, v.Y = v.X*cos+v.Y*sin, v.Y*cos-v.X*sin
}

Given that you code is growing a bit, to keep things tidy we’ll define the Vector type in its own file, vector.go, rather than including it directly in our programs. We’ll also do the same for the Canvas. As the file is part of the same package if we use go build to run it we’ll just pick up the method definitions. However when using go run it is necessary to specify both files e.g. go run lines.go canvas.go vector.go.

Full vector.go source on github

Drawing lines

Ok great, so we have ourselves a vector type, let’s use it to draw a line. To do this we’ll create a function that takes a start vector and an end vector and draws the line pixel by pixel between them. For now we won’t worrying about antialiasing and just round to the nearest pixel each time we draw.

Instead we’ll draw the line using the following process:

  1. Get the vector delta = end - start, that represents the line
  2. Normalize this vector to unit length
  3. Draw a pixel at the start point and then move along the line, by the displacement given by our normalized delta vector.
  4. Draw another pixel and move along again, repeating this until we get to end

Whenever we draw a pixel we will be snapping our precise floating point position to the nearest pixel, and this will lead to antialiasing. In code the above becomes:

func (c Canvas) DrawLine(color color.RGBA, from Vector, to Vector) {
  delta := to.Sub(from)
  length := delta.Length()
  x_step, y_step := delta.X/length, delta.Y/length
  limit := int(length + 0.5)
  for i := 0; i < limit; i++ {
    x := from.X + float64(i)*x_step
    y := from.Y + float64(i)*y_step
    c.Set(int(x), int(y), color)
  }
}

Now we can draw things like this:

Lines

Full lines.go source on github

Drawing a spiral

Drawing a spiral is pretty straightforward now, especially as our Vector type support scaling and rotating. The process is:

  1. Start with a vector v, e.g. {0, 1} and a position p, e.g. {0, 0}
  2. Draw v onto the canvas, at position p
  3. Displace p by v
  4. Rotate v and scale it down
  5. Repeat from step 2. until v becomes sufficiently small

So, in Go-speak:

func (c Canvas) DrawSpiral(color color.RGBA, from Vector) {
  dir := Vector{0, 5}
  last := from
  for i := 0; i < 10000; i++ {
    next := last.Add(dir)
    c.DrawLine(color, last, next)
    dir.Rotate(0.03)
    dir.Scale(0.999)
    last = next
  }
}

Great, now all that remains is to create an 12 foot poster from our “spiral-art” attach it to the ceiling, and lie on the floor forever more.

Spirals

Full spirals.go source on github

Intro to (images in) Go – basics

This post is the first in a series. For a listing of all the posts, as well as instructions on running the code, see here. It is meant as an introduction to Go, by way of a bit of simple graphics processing. If you haven’t come across Go before, I’d encourage you to head over to http://golang.org to check it out, in particular going through the excellent online tutorial. At the very least you should be familiar with how to run a simple Go program, see here for details.

Anyway, here’s a preview of the beauty that we will soon bestow upon the world:

Spiral preview

Such artwork is best digested in stages, and as such we’ll be looking at:

  • Writing out an image to a file
  • Drawing gradients
  • Creating our own Canvas type which extends image.RGBA
  • Creating a Vector type to draw on the Canvas (Drawing)
  • Some simple line and spiral drawing on the Canvas (Drawing)

Writing an image to a file

Go comes with the image package which makes it easy to write out in a variety of formats. Here’s how to create a blank PNG and write it out to a file:

width, height := 128, 128
m := image.NewRGBA(image.Rect(0, 0, width, height))
out_filename := "blank.png"
out_file, err := os.Create(out_filename)
if err != nil {
  log.Fatal(err)
}
defer out_file.Close()
log.Print("Saving image to: ", out_filename)
png.Encode(out_file, m)

Full blank.go source on github

Adding some color

Now the above is hardly interesting, so let’s actually draw something. The image.RGBA struct we created above is little more than a 2D array of pixels, so to create an image we’ll iterate over them, and set the color depending the position – creating a gradient effect:

func drawGradient(m image.RGBA) {
  size := m.Bounds().Size()
  for x := 0; x < size.X; x++ {
    for y := 0; y < size.Y; y++ {
      color := color.RGBA{
        uint8(255 * x / size.X),
        uint8(255 * y / size.Y),
        55,
        255}
      m.Set(x, y, color)
    }
  }
}

Resulting in:

Gradient preview

Full gradient.go source on github

Creating a Canvas

Wouldn’t it be much nicer if we could just call drawGradient directly on the RGBA instance, rather than passing? Perhaps not, but we’re going to anyway.

Because the RGBA type comes from an external package, we cannot declare methods on it. Instead, we’ll create a new type Canvas, and embed the image.RGBA type inside it. This is done by having the image.RGBA type as an anonymous field when defining the struct, like so:

type Canvas struct {
  image.RGBA
}

What is happening here is pretty neat. By declaring our Canvas type in this way we will be able to access the embedded RGBA instance on a Canvas instance as we’d expect, at canvas.RGBA. However, all the methods that are declared on the RGBA type are now callable on our new Canvas type, and will automatically get passed through to the embedded RGBA type. This is very important, as we are now free to pass the Canvas instance around, as if it were of RGBA type, for example when we pass it to the png.Encode function.

To initialize our new type, we need to first create an instance of it and then initialize the embedded RGBA object.

func NewCanvas(r image.Rectangle) *Canvas {
  canvas := new(Canvas)
  canvas.RGBA = *image.NewRGBA(r)
  return canvas
}

At this point the code should still work with the drawGradient method as long as we change the type of the parameter to Canvas. However, we want to go one step further and make DrawGradient a method on the Canvas type itself:

func (c Canvas)DrawGradient() {
  size := c.Bounds().Size()
  // Rest of function...
}

And we’re done! Now we can call canvas.DrawGradient directly.

Full canvas.go source on github

Be sure to check out Drawing, where we’ll draw lines onto the canvas, as promised…

Intro to (images in) Go

This series of posts is meant as an introduction to Go, by way of a bit of simple graphics processing. If you haven’t come across Go before, I’d encourage you to head over to http://golang.org to check it out, in particular going through the excellent online tutorial. At the very least you should be familiar with how to run a simple Go program, see here for details.

Preview

Here are some of the things we’ll be making…
Montage

Posts

The posts are meant to be read in order, although if you have an understanding of Go you should be able to jump in at any point.

Running the code

First make sure you can run the example code here. Then to run an example use go run:

go run blank.go

Please note that if an example has dependencies in other files, and most do: depending on canvas.go and vector.go, you will need to pass these dependencies to go run:

go run lines.go canvas.go vector.go

Currently it is not possible to use go build or go install as this leads to errors, due to multiple files defining the main() function. This will be fixed in the future, for now please use go run.

Suggestions?

If there’s any post/topic that you’d like to see, please leave a comment below.