練習:グラフ描画クラス
グラフを書くとき、いちいち物理的な座標で描画すると面倒なので、論理座標で指定して、描くときに内部で物理座標に変換するような機能を持ったグラフ描画クラスを作ってみた。
新たな参考資料として、ここを見つけた。大いに役立った。感謝。
多少手直しが必要な部分もあるが、とりあえず使える、はず。
# graph.rb require "tk" class GraphScreen attr_accessor :x, :y attr_reader :canvas, :range SIZE = 600 ADJUSTER = 10 def initialize range = (-2.0..2.0) @x, @y = 0.0, 0.0 @min = first = range.first.to_f @max = last = range.last.to_f @range = (@min..@max) @rate = SIZE / (@max - @min) x_min, x_zero, x_max = absolute_x(@min), absolute_x(0), absolute_x(@max) y_min, y_zero, y_max = absolute_y(@min), absolute_y(0), absolute_y(@max) @canvas = TkCanvas.new do background "white" width SIZE + ADJUSTER * 2 height SIZE + ADJUSTER * 2 TkcLine.new(self, x_zero, y_min, x_zero, y_max) TkcLine.new(self, x_min, y_zero, x_max, y_zero) TkcText.new(self, x_zero + 30, y_min - 20) do |t| text first.to_s font TkFont.new(:size=>16) end TkcText.new(self, x_zero + 30, y_max + 20) do |t| text last.to_s font TkFont.new(:size=>16) end TkcText.new(self, x_min + 10, y_zero - 20) do |t| text first.to_s font TkFont.new(:size=>16) end TkcText.new(self, x_max - 10, y_zero - 20) do |t| text last.to_s font TkFont.new(:size=>16) end pack end end def absolute_x(x = @x) SIZE / 2 + x * @rate + ADJUSTER end def absolute_y(y = @y) SIZE / 2 + y * -@rate + ADJUSTER end def dot(x = @x, y = @y) line(x, y, x, y) end def line(x1, y1, x2 = @x, y2 = @y) cx1 = absolute_x(x1) cy1 = absolute_y(y1) cx2 = absolute_x(x2) cy2 = absolute_y(y2) if (cx2 - cx1) * (cy2 - cy1) == 0 then cx1 += 1 end TkcLine.new(@canvas, cx1, cy1, cx2, cy2).configure(:fill=>"red") self end def move(x = 0, y = 0) @x += x @y += y self end def loop(rate = 1) @range.step(0.005 * rate) do |x| y = yield(x) dot(x, y) end end end module GraphModule def to_radian(degree) degree * Math::PI / 180 end def sin(degree) Math.sin(to_radian(degree)) end def cos(degree) Math.cos(to_radian(degree)) end end