Mae向きなブログ

Mae向きな日記のブログ版。ようやくこちらに移行してきました。

シェルピンスキー・ギャスケット

なぜか,シェルピンスキー・ギャスケットが気になったので書いてみました。グローバル変数が多くて,あんまりきれいではないですが載せておきます。
以下を参考にしました。

gasket.rb

# -*- coding: utf-8 -*-
require 'cairo'

def draw_line(x1, y1, x2, y2)
  $context.set_source_rgb(1, 0, 0)
  $context.move_to(x1, y1)
  $context.line_to(x2, y2)
  $context.stroke
end

def draw_polygon(x, y)
  draw_line(x[0], y[0], x[1], y[1])
  draw_line(x[1], y[1], x[2], y[2])
  draw_line(x[2], y[2], x[0], y[0])
end

def gasket_draw(times)
  width = $width - 50           # 三角形の底辺の長さを設定
  x_shift = -30                 
  y_shift = -30
  x = [x_shift, width + x_shift, width / 2 + x_shift]
  y = [width + y_shift, width + y_shift, y_shift]
  draw_polygon(x, y)            # 一番大きな三角形の描画
  draw_triangle(times - 1, x, y)# 三角形描画の呼び出し
end

def draw_triangle(times, x, y)
  return if times < 1
  # 各辺の中点を結んだ三角形の描画
  x1 = [(x[0] + x[1])/2, (x[1] + x[2]) / 2, (x[2] + x[0])/2]
  y1 = [(y[0] + y[1])/2, (y[1] + y[2])/2, (y[2] + y[0])/2]
  draw_polygon(x1, y1)
  # 真ん中以外の三角形に対して繰り返し三角形を描画
  x2 = [x1[0], x[1], x1[1]]
  y2 = [y1[0], y[1], y1[1]]
  draw_triangle(times - 1, x2, y2)

  x2 = [x1[2], x1[1], x[2]]
  y2 = [y1[2], y1[1], y[2]]
  draw_triangle(times - 1, x2, y2)

  x2 = [x[0], x1[0], x1[2]]
  y2 = [y[0], y1[0], y1[2]]
  draw_triangle(times - 1, x2, y2)
end

format = Cairo::FORMAT_ARGB32
$width = 400
$height = 400

$surface = Cairo::ImageSurface.new(format, $width, $height)
$context = Cairo::Context.new($surface)

$context.set_source_rgb(1, 1, 1)
$context.rectangle(0, 0, $width, $height)
$context.fill
$context.translate(40, 40)

gasket_draw(ARGV[0].to_i)

$surface.write_to_png("gasket.png")

実行結果

$ ruby gasket.rb 5 ; eog gasket.png &

久しぶりにcairoを使ってみました。過去には,cairoを使って

を作ってます。

ところで,Wikipediaのシェルピンスキーのギャスケットのページには,シェルピンスキーのギャスケットの一部にズームしていく様子を表すアニメーションがあります。これはほんとに面白い。