#==========
Julia の修行をするときに,いろいろなプログラムを書き換えるのは有効な方法だ。
以下のプログラムを Julia に翻訳してみる。
プロット関数群
http://aoki2.si.gunma-u.ac.jp/R/plot.html
ファイル名: plotter.jl 関数名: plot*
翻訳するときに書いたメモ
なかなか楽しかった。色々拡張した。
前に NHK でやっていた,家紋を描くシリーズを見ていたので,ちょっとやってみた。
==========#
using Plots
# 開始
function plotbegin(; w = 600, h = 600)
pyplot()
plt = plot(xlabel="", ylabel="", grid=false, showaxis=false,
aspect_ratio=1, size=(w, h), label="")
end
# 終了
function plotend()
plot!()
end
# (x1, y1) - (x2, y2) の線分
function plotline(x1, y1, x2, y2; col=:black, lty=:solid, lwd=1)
plot!([x1, x2], [y1, y2], linecolor=col, linestyle=lty, linewidth=lwd, label="")
end
# (x1, y) - (x2, y) の水平線分
function plothline(x1, x2, y; col=:black, lty=:solid, lwd=1)
plot!([x1, x2], [y, y], linecolor=col, linestyle=lty, linewidth=lwd, label="")
end
# (x, y1) - (x, y2) の垂直線分
function plotvline(x, y1, y2; col=:black, lty=:solid, lwd=1)
plot!([x, x], [y1, y2], linecolor=col, linestyle=lty, linewidth=lwd, label="")
end
# (x1, y1), (x2, y2) を対角座標とする矩形
function plotbox(x1, y1, x2, y2; col=:black, lty=:solid, lwd=1, fcol="")
if fcol == ""
plot!([x1, x2, x2, x1, x1], [y1, y1, y2, y2, y1], linecolor=col,
linestyle=lty, linewidth=lwd, label="")
else
plot!([x1, x2, x2, x1, x1], [y1, y1, y2, y2, y1], linecolor=col,
linestyle=lty, seriestype=:shape, linewidth=lwd, fillcolor=fcol,
label="")
end
end
# (ox, oy) を原点とする半径 r の円(円弧)。fcol を指定すると塗りつぶし。
function plotcircle(ox, oy, r; startangle=0, endangle=360,
col=:black, lty=:solid, lwd=1, fcol="")
plotellipse(ox, oy, r, r, φ=0, startangle=startangle,
endangle=endangle, col=col, lty=lty, lwd=lwd, fcol=fcol)
end
# 度をラジアンに変換する
radian(degree) = degree / 180 * π
# (ox, oy) を中心,ra, rb を半径とする楕円(楕円弧)。fcol を指定すると塗りつぶし。
function plotellipse(ox, oy, ra, rb; φ=0, startangle=0, endangle=360,
length=100, col=:black, lty=:solid, lwd=1, fcol="")
θ = vcat(range(radian(startangle), radian(endangle),
length=length), radian(endangle))
if φ == 0
if fcol == ""
plot!(ra .* cos.(θ) .+ ox, rb .* sin.(θ) .+ oy,
linecolor=col, linestyle=lty, linewidth=lwd, label="")
else
plot!(ra .* cos.(θ) .+ ox, rb .* sin.(θ) .+ oy,
linecolor=col, linestyle=lty, linewidth=lwd,
seriestype=:shape, fillcolor=fcol, label="")
end
else
x = ra .* cos.(θ)
y = rb .* sin.(θ)
φ = radian(φ)
cosine = cos(φ)
sine = sin(φ)
if fcol == ""
plot!(cosine .* x .- sine .* y .+ ox,
sine .* x .+ cosine .* y .+ oy,
linecolor=col, linestyle=lty, linewidth=lwd, label="")
else
plot!(cosine .* x .- sine .* y .+ ox,
sine .* x .+ cosine .* y .+ oy,
linecolor=col, linestyle=lty, linewidth=lwd,
seriestype=:shape, fillcolor=fcol, label="")
end
end
end
# 任意の多角形。fcol を指定すると塗りつぶし。
function plotpolygon(x, y; col=:black, lty=:solid, lwd=1, fcol="")
x = vcat(x, x[1])
y = vcat(y, y[1])
if fcol == ""
plot!(x, y, linecolor=col, linestyle=lty, linewidth=lwd, label="")
else
plot!(x, y, linecolor=col, linestyle=lty, linewidth=lwd,
seriestype=:shape, fillcolor=fcol, label="")
end
end
# (x1, y1) を描き始め,一辺の長さ l の正 n 多角形。fcol を指定すると塗りつぶし。
function plotpolygon1(x1, y1, l, n; col=:black, lty=:solid, lwd=1, fcol="")
θ = range(0, 2π, length=n+1)
x = fill(float(x1), n+1)
y = fill(float(y1), n+1)
for i = 2:n
x[i] = x[i-1]+l*cos(θ[i])
y[i] = y[i-1]+l*sin(θ[i])
end
if fcol == ""
plot!(x, y, linecolor=col, linestyle=lty, linewidth=lwd, label="")
else
plot!(x, y, linecolor=col, linestyle=lty,
seriestype=:shape, fillcolor=fcol, linewidth=lwd, label="")
end
end
# (ox, oy) を中心,r を半径とする円に内接する正 n 多角形。fcol を指定すると塗りつぶし。
function plotpolygon2(ox, oy, r, n; φ=90, col=:black, lty=:solid, lwd=1, fcol="")
θ = range(0, 2π, length=n+1) .+ radian(φ)
if fcol == ""
plot!(r .* cos.(θ) .+ ox, r .* sin.(θ) .+ oy,
linecolor=col, linestyle=lty, linewidth=lwd, label="")
else
plot!(r .* cos.(θ) .+ ox, r .* sin.(θ) .+ oy,
linecolor=col, linestyle=lty, linewidth=lwd,
seriestype=:shape, fillcolor=fcol, label="")
end
end
# (x1,y1) - (x2, y2) の矩形範囲に格子を描く。間隔は wx, wy。
function plotgrid(x1, y1, x2, y2, wx; wy=wx, col=:gray, lty=:dot, lwd=1)
X1 = min(x1, x2)
X2 = max(x1, x2)
Y1 = min(y1, y2)
Y2 = max(y1, y2)
for i = 0:fld(abs(X2-X1), wx)
plot!([X1+wx*i, X1+wx*i], [Y1, Y2], linecolor=col,
linestyle=lty, linewidth=lwd, label="")
end
for i = 0:fld(abs(y2-y1), wy)
plot!([X1, X2], [Y1+wy*i, Y1+wy*i], linecolor=col,
linestyle=lty, linewidth=lwd, label="")
end
end
# ネフロイド
plotbegin()
t = 0:3:360
l = 130
ox = l .* cos.(radian.(t))
oy = l .* sin.(radian.(t))
for i = 1:length(t)
plotcircle(ox[i]+250, oy[i]+250, abs(ox[i]),
startangle=0, endangle=360, col="blue")
end
plotend()
# カージオイド
plotbegin()
t = 0:5:360
l = 100
ox = l .* cos.(radian.(t))
oy = l .* sin.(radian.(t))
for i = 1:length(t)
plotcircle(ox[i]+320, oy[i]+250,
sqrt((ox[i]-ox[1])^2+(oy[i]-oy[1])^2),
startangle=0, endangle=360, col="blue")
end
plotend()
# 多角形1
using FixedPointNumbers, ColorTypes # for RGB
plotbegin();
for i = 30:-1:3
plotpolygon1(0, 0, 70, i, fcol=RGB((70-i)/70, 0, 0))
end
plotend()
# 多角形2
plotbegin();
for i = 30:-1:3
plotpolygon2(0, 0, 70, i, fcol=RGB(0, (30-i)/30, 0))
end
plotend()
plotbegin(h=300)
plotpolygon2(0, 0, 90, 3, φ = 90, fcol=:black)
plotpolygon2(0, 0, 90, 3, φ = 30, fcol=:black)
for θ = 0:30:330
plotline(0, 0, 100*cos(radian(θ)), 100*sin(radian(θ)), col=:white, lwd=2)
end
newx = 200
plotcircle(newx, 0, 90, fcol=:black)
plotcircle(newx, 0, 82, fcol=:white)
plotpolygon2(newx, 0, 78, 3, φ = 90, fcol=:black)
plotpolygon2(newx, 0, 78, 3, φ = 30, fcol=:black)
for θ = 0:30:330
plotline(newx, 0, newx+81*cos(radian(θ)), 81*sin(radian(θ)), col=:white, lwd=2)
end
plotend()