# Pretty Circles

The functions in this class require Underscore's library, and it should be loaded on the HTML page prior to including this module.

We can't pass an operator into Underscore's `reduce` function, so we simply create an `add` function:

```add = (x, y) -> x + y
```

The `sum` function use's Underscore's `reduce` function calling the `add` function on each element in our `lst`.

```sum = (lst) -> _.reduce(lst, add, 0)
```

A `roll` function takes `how_many` dice to roll, and also the number of `sides` those dice have. Basically, the range for the random numbers.

```roll = (how_many, sides) ->
dice = -> _.random(1,sides)
sum( _.times(how_many, dice) )
```

We now use the `roll` function to skew the results towards a particular `goal` within a `range`:

```goal_roll = (goal, range) ->
steep = 20             # Number of dice to roll
sides = (range + steep) / steep  # Number of sides on the dice
delta = goal - range / 2

results = roll(steep, sides) - steep + delta
console.log "Roll:", results, sides, goal, delta
if (results > range)
return results - range
else
return results
```

We now pick a random color (hue, actually) that clusters around a particular `goal` between 1 and 100:

```get_color = (goal) ->
hue = goal_roll(goal, 100) / 100
sat = _.random(.8, .9)
lit = _.random(.5, .6)
hslToRgb(hue, sat, lit)
```

Converts an HSL color value to RGB. Conversion formula adapted from http://en.wikipedia.org/wiki/HSL_color_space. Assumes h, s, and l are contained in the set [0, 1] and returns r, g, and b in the set [0, 255].

```hslToRgb = (h, s, l) ->
if (s == 0)
r = g = b = l   # achromatic
else
hue2rgb = (p, q, t) ->
if (t < 0) then t += 1
if (t > 1) then t -= 1

if (t < 1/6)
p + (q - p) * 6 * t
else if (t < 1/2)
q
else if (t < 2/3)
p + (q - p) * (2/3 - t) * 6
else
p

q = if l < 0.5 then l * (1 + s) else l + s - l * s
p = 2 * l - q

r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);

# return [r * 255, g * 255, b * 255];
"#" + dec2hex(r*255) + dec2hex(g*255) + dec2hex(b*255);
```

Since our RGB color values need to be 0 padded when they are converted to hex, we have this lovely little function:

```dec2hex = (v) ->
if (v < 16)
"0" + Math.floor(v).toString(16)
else
Math.floor(v).toString(16);
```

While the HTML5 canvas is nice, it good use a little helper function to draw a circle with a single command:

```disk = (canvas, color, x, y, radius) ->
canvas.fillStyle = color
canvas.beginPath()
canvas.arc(x, y, radius, 0, Math.PI*2, true)
canvas.closePath()
canvas.fill()
```

Now it is time to acquire a drawing canvas and go to work, but not until the HTML has been loaded with the `window.onload` event:

```window.onload = ->
drawingCanvas = document.getElementById('pretty-circles')

# Check the element is in the DOM and the browser supports canvas
if drawingCanvas.getContext

# Initaliaze a 2-dimensional drawing context
context = drawingCanvas.getContext('2d')
hue = _.random(1,100)

for x in [10..490] by 20
for y in [10..490] by 20
disk  context, get_color(hue), x, y, _.random(2,10)
```

Emacs 24.3.1 (Org mode 8.2.4)

Validate