Edited at

「プログラムでシダを描画する」をGoで描画する

More than 5 years have passed since last update.

「プログラムでシダを描画する」記事たちに触発されて、Goで書いてみました。

ファイル「shida.png」に出力した結果

shida.png

ソースコード


  • 変数については、見やすさを重視して型を表記しました。

  • 変数 N は、オリジナルを踏襲して大文字のままにしています。

  • 乱数は rand.Float64() としました。


shida.go

package main

import (
"image"
"image/color"
"image/draw"
"image/png"
"log"
"math/rand"
"os"
"time"
)

var (
N int = 20
xm float64 = 0.0
ym float64 = 0.5
h float64 = 0.6
)

var (
width int = 500
height int = 500
filename string = "shida.png"
)

var (
bgcolor color.Color = color.RGBA{255, 255, 255, 255}
linecolor color.Color = color.RGBA{0, 128, 0, 255}
)

func W1x(x, y float64) float64 {
return 0.836*x + 0.044*y
}

func W1y(x, y float64) float64 {
return -0.044*x + 0.836*y + 0.169
}

func W2x(x, y float64) float64 {
return -0.141*x + 0.302*y
}

func W2y(x, y float64) float64 {
return 0.302*x + 0.141*y + 0.127
}

func W3x(x, y float64) float64 {
return 0.141*x - 0.302*y
}

func W3y(x, y float64) float64 {
return 0.302*x + 0.141*y + 0.169
}

func W4x(x, y float64) float64 {
return 0
}

func W4y(x, y float64) float64 {
return 0.175337 * y
}

func f(m *image.RGBA, k int, x, y float64) {
if 0 < k {
f(m, k-1, W1x(x, y), W1y(x, y))
if rand.Float64() < 0.3 {
f(m, k-1, W2x(x, y), W2y(x, y))
}
if rand.Float64() < 0.3 {
f(m, k-1, W2x(x, y), W2y(x, y))
}
if rand.Float64() < 0.3 {
f(m, k-1, W3x(x, y), W3y(x, y))
}
if rand.Float64() < 0.3 {
f(m, k-1, W4x(x, y), W4y(x, y))
}
} else {
var s float64 = 490.0
m.Set(int(x*s+float64(width)*0.5), int(float64(height)-y*s), linecolor)
}
}

func main() {
rand.Seed(time.Now().Unix())

m := image.NewRGBA(image.Rect(0, 0, width, height))
draw.Draw(m, m.Bounds(), &image.Uniform{bgcolor}, image.ZP, draw.Src)

f(m, N, 0, 0)

file, err := os.Create(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()

err = png.Encode(file, m)
if err != nil {
log.Fatal(err)
}
}


pngファイルを作成する際に参照したサイト