====== グラフの描画 ======
Curses を使ってグラフを描画する。
プログラムの実行時に "warning: rb_safe_level will be removed in Ruby 3.0" と表示される場合は、次のように ruby にオプション "-W0" を付けて実行するとよい。
% ruby -W0 プログラム
===== 関数のグラフ =====
''func(x)'' の関数のグラフを描く。
#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-
# Curses で関数のグラフを描画する
# 作者:山本裕樹
require "curses"
# 関数
def func(x)
return 0.001 * x * (x - 25) * (x + 25)
end
# Curses の初期化
Curses.init_screen
begin
# 色の使用開始
Curses.start_color
# グラフ用のカラーペア番号を用意
Curses.init_pair(1, Curses::COLOR_RED, Curses::COLOR_BLACK)
# 原点の座標
ox = Curses.cols / 2
oy = Curses.lines / 2
# x軸の描画
cy = oy
0.upto(Curses.cols - 1) do |cx|
Curses.setpos(cy, cx)
Curses.addch("-")
end
# y軸の描画
cx = ox
0.upto(Curses.lines - 1) do |cy|
Curses.setpos(cy, cx)
Curses.addch("|")
end
# 原点の描画
Curses.setpos(oy, ox)
Curses.addch("+")
# 色の指定
Curses.attrset(Curses.color_pair(1))
# グラフの描画
0.upto(Curses.cols - 1) do |cx|
# 関数に与える x の値
x = cx - ox
# 関数
y = func(x)
# Curses の y座標への変換
cy = oy - y.round * 0.5
# 仮想端末画面の範囲内なら描画
if (cy >= 0 && cy <= Curses.lines - 1)
Curses.setpos(cy, cx)
Curses.addch("*")
end
end
# 画面表示を更新
Curses.refresh
# 標準入力から1文字だけ読み込む(Enter キー不要)
Curses.getch
ensure
# Curses の終了処理
Curses.close_screen
end
===== sin関数のグラフ =====
#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-
# Curses で sin関数 y=a*sin(k*x) のグラフを描画する
# 作者:山本裕樹
require "curses"
# 使い方(コマンドライン引数がなければ表示する)
if ARGV.length < 2
puts "使い方: singraph.rb a k"
puts "sin関数 y=a*sin(k*x) のグラフを描画する"
puts ""
puts "例:"
puts "\tsingraph.rb 20 0.2"
exit
end
# sin関数のパラメータ
a = ARGV[0].to_f
omega = ARGV[1].to_f
# Curses の初期化
Curses.init_screen
begin
# 色の使用開始
Curses.start_color
# カラーペア番号を用意(7色)
Curses.init_pair(1, Curses::COLOR_BLUE, Curses::COLOR_BLACK)
Curses.init_pair(2, Curses::COLOR_CYAN, Curses::COLOR_BLACK)
Curses.init_pair(3, Curses::COLOR_GREEN, Curses::COLOR_BLACK)
Curses.init_pair(4, Curses::COLOR_MAGENTA, Curses::COLOR_BLACK)
Curses.init_pair(5, Curses::COLOR_RED, Curses::COLOR_BLACK)
Curses.init_pair(6, Curses::COLOR_WHITE, Curses::COLOR_BLACK)
Curses.init_pair(7, Curses::COLOR_YELLOW, Curses::COLOR_BLACK)
# 原点の座標
ox = Curses.cols / 2
oy = Curses.lines / 2
# x軸の描画
cy = oy
0.upto(Curses.cols - 1) do |cx|
Curses.setpos(cy, cx)
Curses.addch("-")
end
# y軸の描画
cx = ox
0.upto(Curses.lines - 1) do |cy|
Curses.setpos(cy, cx)
Curses.addch("|")
end
# 原点の描画
Curses.setpos(oy, ox)
Curses.addch("+")
# グラフの描画
0.upto(Curses.cols - 1) do |cx|
# sin関数に与える x の値
x = cx - ox
# sin関数
y = a * Math.sin(omega * x)
# Curses の y座標への変換
cy = oy - y.round * 0.5
# 仮想端末画面の範囲内なら描画
if (cy >= 0 && cy <= Curses.lines - 1)
# ランダムに色の指定
Curses.attrset(Curses.color_pair(rand(1..7)))
# カーソルを座標 (cx,cy) に移動
Curses.setpos(cy, cx)
# カーソルの位置に文字を挿入
Curses.addch("*")
# 画面表示を更新
Curses.refresh
# 0.2秒停止
sleep(0.2)
end
end
# 標準入力から1文字だけ読み込む(Enter キー不要)
Curses.getch
ensure
# Curses の終了処理
Curses.close_screen
end