LoginSignup
33
30

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-05-23

「プログラムでシダを描画する」記事たちに触発されて、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ファイルを作成する際に参照したサイト

33
30
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
30