# pheelicks

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: 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++ { 