LoginSignup
5
5

More than 5 years have passed since last update.

「プログラムでシダを描画する」をGroovyでやってみた

Posted at

説明とか

恐らく震源地
プログラムでシダを描画する - 強火で進め
たぶんきっかけ
プログラムでシダを描画する
先達の皆様
「プログラムでシダを描画する」一覧

正直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")

fern.png

我ながら

drawer = clos の辺りがなんかキモいですorz

5
5
0

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
5
5