Skip to content

Instantly share code, notes, and snippets.

@takehiko
Created August 13, 2017 01:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takehiko/b78448877af62acba3b13ac1626b176a to your computer and use it in GitHub Desktop.
Save takehiko/b78448877af62acba3b13ac1626b176a to your computer and use it in GitHub Desktop.
Stackable Number Lines' Drawer for Multiple Numbers
#!/usr/bin/env ruby
# number-line-drawer.rb by takehikom
# ruby number-line-drawer.rb
# env FN=TakaoGothic.ttf ruby number-line-drawer.rb
# 要ImageMagick(convertおよびidentifyコマンドを使用)
$FN = ENV['FN'] # フォントのパス
$SPC = 20 # 数直線の目盛り幅
$MAX = 60 # 数直線の最大値
$NUMS = (2..9).to_a # 対象とする数(1桁限定)の配列
class NumberLineDrawer
def start
draw_line(bg: "none", fn: $FN)
stack_lines(bg: "\#f4fff4", fn: $FN)
stack_lines(bg: "\#f4fff4", fn: $FN, cm: true, out: "lines2.png")
end
def start2
draw_line(bg: "none", max: 50, fn: $FN)
stack_lines(bg: "\#f4fff4", fn: $FN, max: 50, nums: [2, 3, 4, 5])
end
# 数直線の画像を作成する
def draw_line(**param)
max = param[:max] || $MAX # 数直線の最大値
bg = param[:bg] || "none" # 背景色
spc = param[:spc] || $SPC # 数直線の目盛り幅
hgt = param[:hgt] || (spc * 0.7).to_i # 数直線の目盛り線の高さ
mgn = param[:mgn] || (spc * 0.5).to_i # 上下左右の余白幅
col = param[:col] || "black" # 数直線の色
sw = param[:sw] || 1 # 線幅
fout = param[:out] || "line.png" # 保存先ファイル名
if param[:fn]
flag_draw_text = true # 数の描画をする
fn = param[:fn] # フォントのパス
pt = param[:pt] || spc * 0.8 # フォントサイズ
fcol = param[:fcol] || col # 文字色
gap = param[:gap] || spc * 0.125 # 数直線目盛り上端との高さ
lh = mgn + pt + gap # 数直線目盛り上端のY座標
else
flag_draw_text = false # 数の描画をしない
lh = mgn # 数直線目盛り上端のY座標
end
# 画像サイズなど
width = spc * max + mgn * 2
height = lh + hgt + mgn
@command = "convert -size #{width}x#{height} xc:#{bg}"
# 数直線の描画
@command += " -stroke #{col} -strokewidth #{sw} -fill none"
x1 = mgn
x2 = spc * max + mgn
y = lh + hgt
@command += " -draw \"line #{x1},#{y} #{x2},#{y}"
0.upto(max) do |i|
x = spc * i + mgn
y1 = lh
y2 = y1 + hgt
@command += " line #{x},#{y1} #{x},#{y2}"
end
@command += "\""
# 数値の描画
if flag_draw_text
@command += " -font #{fn} -pointsize #{pt} -fill #{fcol} -stroke none"
@command += " -draw \""
0.upto(max) do |i|
x = spc * i + mgn - pt * (i < 10 ? 0.2 : 0.5)
y = lh - gap
@command += " text #{x},#{y} \'#{i}'"
end
@command += "\""
end
# 画像生成
@command += " -quality 92 #{fout}"
puts @command
system @command
end
# ラベル付きで複数の数直線を作成する
def stack_lines(**param)
fin = param[:in] || "line.png" # 数直線のファイル名
fout = param[:out] || "lines.png" # 保存先ファイル名
bg = param[:bg] || "white" # 背景色
max = param[:max] || $MAX # 数直線の最大値
spc = param[:spc] || $SPC # 数直線の目盛り幅
fn = param[:fn] # フォントのパス
pt = param[:pt] || $SPC # フォントサイズ
flag_english = param[:en] # 英語表記なら真
fcol = param[:fcol] || "black" # 文字色
mgn = param[:mgn] || 8 # 上下左右の余白幅
gx = param[:gx] || 5 # ラベルと数直線の余白
gy = param[:gy] || 1 # 数直線間の余白
nums = param[:nums] || $NUMS # 対象とする数(1桁限定)
flag_circle = param[:cm] || false # 倍数を○で囲むなら真
cmcol = param[:cmcol] || "gray20" # 丸囲みの色
cmsw = param[:cmsw] || 1 # 丸囲みの線幅
flag_incl_zero = param[:iz] # 0を倍数とするなら真
# 数直線画像から幅と高さを取得
raise if !test(?f, fin)
s = `identify #{fin}`
if / (\d+)x(\d+) / =~ s
finw, finh = $1.to_i, $2.to_i # 数直線画像の幅と高さ
else
raise
end
# 倍数ラベルの準備
if flag_english
label_pattern = "Multiples of %d "
label_width = pt * 7.5
else
label_pattern = "%dの倍数"
label_width = pt * 3.5
end
# 画像サイズなど
width = mgn + label_width + gx + finw + mgn
height = mgn + finh * nums.length + gy * (nums.length - 1) + mgn
@command = "convert -size #{width}x#{height} xc:#{bg}"
# 数直線画像の貼り付け
@command += " -gravity north-west -draw \""
nums.each_with_index do |n, i|
x = mgn + label_width + gx
y = mgn + (finh + gy) * i
@command += " image over #{x},#{y} 0,0 \'#{fin}\'"
end
@command += "\""
# 倍数ラベルの描画
@command += " -font #{fn} -pointsize #{pt} -fill #{fcol} -stroke none"
@command += " -draw \""
nums.each_with_index do |n, i|
x = mgn
y = mgn + (finh + gy) * i + finh * 0.3
label = label_pattern % n
@command += " text #{x},#{y} \'#{label}'"
end
@command += "\""
# 倍数を○で囲む
if flag_circle
@command += " -stroke #{cmcol} -strokewidth #{cmsw} -fill none"
@command += " -draw \""
nums.each_with_index do |n, i|
next if n <= 0
y = mgn + (finh + gy) * i + finh * 0.34
r = pt * 0.6
0.step(max, n) do |m|
next if !flag_incl_zero && m == 0
x = mgn + label_width + gx + spc * (m + 0.5)
@command += " circle #{x},#{y} #{x + r},#{y}"
end
end
@command += "\""
end
# 画像生成
@command += " -quality 92 #{fout}"
puts @command
system @command
end
end
if __FILE__ == $0
if $FN.nil?
nld = NumberLineDrawer.new
nld.draw_line(bg: "white")
exit
end
NumberLineDrawer.new.start
# NumberLineDrawer.new.start2
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment