cairo と Ruby で遊んでみる(2)
水平投射です。
require 'bundler/setup' require 'cairo' require './gifanime' include Math W = 600; H = 300 V0 = 10.0; A = 0.75; G = 5.0 v = lambda {|n| - A ** n * sqrt(2 * G * H)} t = lambda do |n| if n.zero? sqrt(2 * H / G) else ar = [1] n.times {|i| ar << 2 * A ** (i + 1)} sqrt(2 * H / G) * ar.inject(:+) end end y = lambda do |n, t1| if n.zero? H - G * t1 ** 2 / 2 else t2 = t1 - t.call(n - 1) - v.call(n) * t2 - G * t2 ** 2 / 2 end end x = lambda {|t1| V0 * t1} num = lambda do |tm| 1000.times {|i| return i if tm <= t.call(i)} end #main Dir.chdir("picture") Surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, W, H) C = Cairo::Context.new(Surface) C.set_source_rgb(0, 0, 0) C.rectangle(0, 0, W, H) C.fill C.set_source_rgb(1, 0, 0) for i in 0..W tm = i / V0 x1 = x.call(tm) y1 = H - y.call(num[tm], tm) C.arc(x1, y1, 2, 0, 2 * PI) C.stroke Surface.write_to_png("%04d.png" % i) end gifanime(3)
V0 は初速度、A は反発係数、G は重力加速度。