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) #gainsboro arc(true, 0, 0, 300, 300, 0, 64 * 360) color(0x6b00, 0x8e00, 0x2300) #olivedrab 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'」タグを作りました。