Created
August 13, 2017 01:02
-
-
Save takehiko/b78448877af62acba3b13ac1626b176a to your computer and use it in GitHub Desktop.
Stackable Number Lines' Drawer for Multiple Numbers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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