RosettaCodeData/Task/Brownian-tree/Go/brownian-tree-2.go
Ingy döt Net b83f433714 tasks a-s
2013-04-10 23:57:08 -07:00

79 lines
2 KiB
Go

package main
// Files required to build supporting package raster are found in:
// * Bitmap
// * Grayscale image
// * Write a PPM file
import (
"fmt"
"math/rand"
"raster"
)
const w = 400 // image width
const h = 300 // image height
const n = 15000 // number of particles to add
const frost = 65535 // white
var g *raster.Grmap
func main() {
g = raster.NewGrmap(w, h)
// off center seed position makes pleasingly asymetrical tree
g.SetPx(w/3, h/3, frost)
var x, y int
generate:
for a := 0; a < n; {
// generate random position for new particle
x, y = rand.Intn(w), rand.Intn(h)
switch p, ok := g.GetPx(x, y); p {
case frost:
// position is already set. find a nearby free position.
for p == frost {
x += rand.Intn(3) - 1
y += rand.Intn(3) - 1
p, ok = g.GetPx(x, y)
// execpt if we run out of bounds, consider the particle lost.
if !ok {
continue generate
}
}
default:
// else particle is in free space. let it wander
// until it touches tree
for !hasNeighbor(x, y) {
x += rand.Intn(3) - 1
y += rand.Intn(3) - 1
// but again, if it wanders out of bounds consider it lost.
_, ok = g.GetPx(x, y)
if !ok {
continue generate
}
}
}
// x, y now specify a free position toucing the tree.
g.SetPx(x, y, frost)
a++
// progress indicator
if a%100 == 0 {
fmt.Println(a, "of", n)
}
}
g.Bitmap().WritePpmFile("tree.ppm")
}
var n8 = [][]int{
{-1, -1}, {-1, 0}, {-1, 1},
{ 0, -1}, { 0, 1},
{ 1, -1}, { 1, 0}, { 1, 1}}
func hasNeighbor(x, y int) bool {
for _, n := range n8 {
if p, ok := g.GetPx(x+n[0], y+n[1]); ok && p == frost {
return true
}
}
return false
}