Files
barnsley-fern-go/barnsley-fern.go
2025-03-30 00:20:11 +03:00

56 lines
1.4 KiB
Go

package main
import (
"image"
"math/rand"
"time"
)
func drawBarnsleyFern(img *image.RGBA, colorfunc colorFunc, dots int) {
var (
x, y, tmpx, tmpy, r, maxy, maxx, scale, yoffset, xoffset float64
)
maxy = float64(img.Bounds().Max.Y) // размер картинки по вертикали
maxx = float64(img.Bounds().Max.X) // размер картиники по горизонтали
scale = min(maxx, maxy)
yoffset = scale / 10 // отступы 10% сверху и снизу
scale = scale - yoffset*2 // масштаб самого папоротника
xoffset = (maxx - scale) / 2 // равные отступы по сторонам
x, y = 0.5, 0.0
for dots > 0 {
dots--
r = rand.Float64()
if r <= 0.01 {
// стебель
tmpx = 0.5
tmpy = 0.16 * y
} else if r <= 0.08 {
// самый большой правый листок
tmpx = 0.2*x - 0.26*y + 0.400
tmpy = 0.23*x + 0.22*y - 0.045
} else if r <= 0.15 {
// самый большой левый листок
tmpx = -0.15*x + 0.28*y + 0.575
tmpy = 0.26*x + 0.24*y - 0.086
} else {
// последующие листочки
tmpx = 0.85*x + 0.04*y + 0.075
tmpy = -0.04*x + 0.850*y + 0.180
}
// рисуем точку
x, y = tmpx, tmpy
color := colorfunc(x, y, time.Now())
img.Set(int(xoffset+x*scale), int(maxy-yoffset-y*scale), color)
}
}
func min(a, b float64) float64 {
if a > b {
a = b
}
return a
}