スパイログラフを描いてみる(Ruby)

スピログラフ デラックス 【日本正規品】

スピログラフ デラックス 【日本正規品】

「スパイログラフ」というのは商品名で、数学的には「内トロコイド」というものになります。2つの円を組み合わせて図形を描くもので、これで遊んでみたことのある方は少なくないのではないでしょうか。

こんなのです。クリックで拡大します。
20180304155739 20180304155736 20180304165253
 

Ruby で描いてみました。描画には自作の Gem 'oekaki' を使っています。
oekaki | RubyGems.org | your community gem host
GTK+でお絵かきしてみた(Ruby) - Camera Obscura
spirograph.rb

require 'oekaki'

Width, Height = 620, 620
R = 300

r1, r2, ratio = 16.0, 11.0, 0.8

Oekaki.app width: Width, height: Height, title: "spirograph" do
  w, h = Width / 2, Height / 2
  draw do
    clear(color(0x0bff * 0.3, 0xe0ff * 0.3, 0xe6ff * 0.3))
    circle(true, w, h, R, color(0xffff, 0xffff, 0xffff))
    color(0xffff, 0, 0xffff)
  end
  
  step = PI / 180 * 10
  rot = ->(θ) { Matrix[[cos(θ), -sin(θ)], [sin(θ), cos(θ)]] }
  r = r2 / r1
  v1 = Vector[R * (1 - r), 0]
  v2 = Vector[R * r * ratio, 0]
  
  position = ->(θ) { rot.(θ) * v1 + rot.(θ * (1 - 1 / r)) * v2 }
  
  e = Enumerator.new do |y|
    θ = 0
    a = position.(θ)
    loop do
      θ += step
      b = position.(θ)
      y << [a, b]
      a = b
    end
  end
  
  timer(10) do
    po = e.next
    line(w + po[0][0], h - po[0][1], w + po[1][0], h - po[1][1])
  end
end

パラメータ r1, r2, ratio を変えるといろいろな図形が描画されます。ただし r1 > r2, 0 < ratio < 1 にして下さい。