説明とか
恐らく震源地
プログラムでシダを描画する - 強火で進め
たぶんきっかけ
プログラムでシダを描画する
先達の皆様
「プログラムでシダを描画する」一覧
正直Groovy素人ですゆえ、ちっともGroovyらしくないかもしれませんがご容赦を。
# 実は最初Ruby+GDで組んでたけどもたもたしてたらRuby版が上がってたのでGroovyで書き直したというのは内緒だ
生やしてみる
drawfern.groovy
import java.awt.Color
import java.awt.image.BufferedImage
import java.io.File
import java.util.Random
import javax.imageio.ImageIO
class Fern {
def W1x = { x, y -> 0.836 * x + 0.044 * y }
def W1y = { x, y -> -0.044 * x + 0.836 * y + 0.169 }
def W2x = { x, y -> -0.141 * x + 0.302 * y }
def W2y = { x, y -> 0.302 * x + 0.141 * y + 0.127 }
def W3x = { x, y -> 0.141 * x - 0.302 * y }
def W3y = { x, y -> 0.302 * x + 0.141 * y + 0.169 }
def W4x = { x, y -> 0 }
def W4y = { x, y -> 0.175337 * y }
def drawer
def rnd
Fern() {
rnd = new Random()
}
def f(k, x, y) {
if (0 < k) {
f(k - 1, W1x(x, y), W1y(x, y))
if (rnd.nextDouble() < 0.3)
f(k - 1, W2x(x, y), W2y(x, y))
if (rnd.nextDouble() < 0.3)
f(k - 1, W3x(x, y), W3y(x, y))
if (rnd.nextDouble() < 0.3)
f(k - 1, W4x(x, y), W4y(x, y))
} else {
drawer(x, y)
}
}
def sprout(n, clos) {
drawer = clos
f(n, 0, 0)
}
}
class FernCanvas {
def width
def height
def allowed
def img
def fernColor = new Color(0.0F, 0.5F, 0.0F)
FernCanvas(size, padding) {
width = size
height = size
allowed = size - padding
img = new BufferedImage(
width, height, BufferedImage.TYPE_INT_RGB)
def g = null
try {
g = this.img.createGraphics()
g.setColor(Color.WHITE)
g.fillRect(0, 0, width, height)
} finally {
if (g != null) {
g.dispose()
}
}
}
def plot(x, y) {
def plotX = (int)( x * allowed + width * 0.5)
def plotY = (int)( height - y * allowed)
img.setRGB(plotX, plotY, fernColor.getRGB())
}
def save_png_to(fileName) {
ImageIO.write(img, "PNG", new File(fileName));
}
}
def N = 20
canvas = new FernCanvas(500, 10)
new Fern().sprout(N) { x, y ->
canvas.plot(x, y)
}
canvas.save_png_to("fern.png")
我ながら
drawer = clos の辺りがなんかキモいですorz