Gem 'oekaki' で落書きです。
oekaki | RubyGems.org | your community gem host
GTK+でお絵かきしてみた(Ruby) - Camera Obscura
スターを描いてみました。
require 'oekaki'
Oekaki.app do
draw do
color(0, 0, 0)
rectangle(true, 0, 0, 300, 300)
color(0xdc00, 0xdc00, 0xdc00)
arc(true, 0, 0, 300, 300, 0, 64 * 360)
color(0x6b00, 0x8e00, 0x2300)
star(true, 150, 150, 150, 0)
end
end
メソッド Tool#star(fill, x1, y1, x2, y2, color = nil) を新たに書きました。fill は ture で塗りつぶし、false で輪郭のみ描画します。(x1, y1) はスターの中心、(x2, y2) は(とがった)頂点のひとつの座標です。
こんなのも。
require 'oekaki'
Oekaki.app width: 400, height: 400 do
draw do
color(0, 0, 0)
rectangle(true, 0, 0, 400, 400)
color(0, 65535, 0)
po = Vector[0, 50]
θ = PI / 15
a = Matrix[[cos(θ), -sin(θ)], [sin(θ), cos(θ)]]
for y in 0..3
for x in 0..3
x1 = x * 100 + 50
y1 = y * 100 + 50
star(false, x1, y1, x1 + po[0], y1 - po[1])
po = a * po
end
end
end
end
Gem の内部で require 'matrix', include Math をしているので、それらのクラスとモジュールがそのまま使えます。
Gem 'oekaki' に加えたコードはだいたいこんな感じです。
require 'matrix'
include Math
module Oekaki
class Tool
def star(fill, x1, y1, x2, y2, color = nil)
set_color(color)
Star.new(fill, x1, y1, x2, y2, @color).draw
end
end
class Star < Tool
def initialize(fill, x1, y1, x2, y2, color)
@fill = fill
@o = []; @a = []; @b = []
@o[0], @o[1] = x1, y1
@a[0] = Vector[x2 - x1, y1 - y2]
θ = PI / 5
rt1 = Matrix[[cos(θ), -sin(θ)], [sin(θ), cos(θ)]]
rt2 = rt1 * rt1
1.upto(4) {|i| @a[i] = rt2 * @a[i - 1]}
t = cos(2 * θ) / cos(θ)
@b[0] = rt1 * @a[0] * t
1.upto(4) {|i| @b[i] = rt2 * @b[i - 1]}
super()
@color = color
end
def draw_triangle(n)
ar = [@a[n].to_w(@o), @b[n].to_w(@o), @b[(n - 1) % 5].to_w(@o)]
polygon(@fill, ar)
end
private :draw_triangle
def draw
if @fill
5.times {|i| draw_triangle(i)}
ar = []
5.times {|i| ar << @b[i].to_w(@o)}
polygon(@fill, ar)
else
ar = []
5.times {|i| ar << @a[i].to_w(@o); ar << @b[i].to_w(@o)}
polygon(@fill, ar)
end
end
end
end
class Vector
def to_w(o)
v = self
[o[0] + v[0], o[1] - v[1]]
end
end
スターのそれぞれの頂点は、頂点ベクトルに回転行列(変数 rt2)を順に掛けて求めています。Ruby では標準添付ライブラリの 'matrix' で行列やベクトルの計算が簡単に行なえます。
一番苦心したのがじつは色の取り扱いです。Tool#star メソッドの中で Starクラスのインスタンスを新たに作っているので、Tool#color を Tool#star に対して使うとき、Starクラスは Toolクラスを継承しているものの、Toolクラスのインスタンス変数の内容が Star.new で上書きされてしまいます。なので、少しトリッキーなことをしています。
「Gem 'oekaki'」タグを作りました。