家紋シリーズ 片喰(1) 丸に角立て井筒に剣片喰
自由曲線をベジェ曲線で近似する
# ベジェ曲線
function bezier(P; points=50)
spline(P, size(P, 1) - 1; points)
end
function spline(P, n; points=50)
# p = size(P, 1) # Number of Control Ponits
# n = 3 # Degree of B-Spline
# n = p -1 # Bezier curve
p = size(P, 1)
m = p + n + 1 # Number of Knots in Knot Vector
# Define Knot Vector
u = OpenUniformKnotVector(m, n)
# t = 0:0.01:u[end]
# t = range()
t = range(u[1], stop=u[end], length=points)
# Calculate B-spline Curve
S = zeros(length(t), 2);
S[1, :] = P[1, :]
for i ∈ 2:length(t)
for j ∈ 1:p
b = BasisFunction(u, j, n, t[i])
S[i, :] += P[j, :] * b
end
end
S
end
# u : Knot Vector
# m : Number of Knots in Knot Vector
# n : Degree of B-Spline
function OpenUniformKnotVector(m, n)
u = zeros(1, m)
for i ∈ 1:m
if i < n+1
u[i] = 0
elseif i > m - (n + 1)
u[i] = m - 1 - 2 * n
else
u[i] = i - n - 1
end
end
u ./ u[end]
end
# u : Knot Vector
# j : j-th Control Ponit
# k : k-th Basis Function <-- n-th B-Spline
# t : Time
function BasisFunction(u, j, k, t)
w1, w2 = 0, 0
if k == 0
if u[j] < t <= u[j+1]
var = 1
else
var = 0
end
else
if u[j+k+1] != u[j+1]
w1 = BasisFunction(u, j+1, k-1, t) *
(u[j+k+1] - t)/(u[j+k+1]-u[j+1])
end
if u[j+k] != u[j]
w2 = BasisFunction(u, j, k-1, t) *
(t - u[j])/(u[j+k] - u[j])
end
var = w1 + w2
end
var
end
# plotter.jl を include
# https://blog.goo.ne.jp/r-de-r/e/bd71a52a09801335d56f7c47d879bfe3
include("plotter.jl")
function ken(θ, r, mirror=false)
t = [cosd(θ) sind(θ); -sind(θ) cosd(θ)]
xy1 = r .* [-0.5 38; -0.5 251]
xy2 = bezier(r .* [3 251; 25 232; 49 222; 77 219])
xy2 = bezier(r .* [0 251; 25 232; 49 222; 77 219])
xy3 = bezier(r .* [77 219; 53 180; 35 152; 21 117; 14 78; 10 60; 10 38])
xy = vcat(xy1, xy2, xy3)
if mirror
xy[:, 1] = -xy[:, 1]
end
xy = xy * t
plotpolygon(xy[:, 1], xy[:, 2], lwd=0, fcol=:black)
end
function katabami(θ, r, mirror=false)
t = [cosd(θ) sind(θ); -sind(θ) cosd(θ)]
xy1 = bezier(r .* [25 30; 26 67; 32 95; 42 131; 53 155; 66 176; 75 187; 90 198; 107 205; 125 205])
xy2 = bezier(r .* [125 205; 141 205; 159 201; 169 191; 183 176; 194 162; 197 141; 198 109])
xy3 = r .* [198 109; 39 21; 25 21]
xy = vcat(xy1, xy2, xy3)
if mirror
xy[:, 1] = -xy[:, 1]
end
xy = xy * t
plotpolygon(xy[:, 1], xy[:, 2], lwd=0, fcol=:black)
end
function igeta(r, θ)
t = [cosd(θ) sind(θ); -sind(θ) cosd(θ)]
xy = r .* [46 564; 116 494; -494 -116; -564 -46] * t
plotpolygon(xy[:, 1], xy[:, 2], lwd=0, fcol=:black)
end
function plotigeta(r)
for θ ∈ 0:90:270
igeta(r, θ)
end
end
function plotring(x, y, r1=1.0, r2=0.9; startθ=0, endθ=360, fcol=:black)
r1, r2 = max(r1, r2), min(r1, r2)
θ = startθ:endθ;
coordx = cosd.(θ);
coordy = sind.(θ);
plotpolygon(x .+ vcat(r1 .* coordx, r2 .* reverse(coordx)), y .+ vcat(r1 .* coordy, r2 .* reverse(coordy)), col=fcol, lwd=0, fcol=fcol)
end
# メインプログラム
function kenkatabami(; r=1, width=400, height=400)
plotbegin(w=width, h=height)
for θ ∈ [0, 120, 240]
ken(θ, r)
katabami(θ, r)
ken(θ, r, true)
katabami(θ, r, true)
end
for θ ∈ [30, 150, 270]
y, x = 70r .* sincosd(θ)
plotline(0, 0, x, y, lwd=2, col=:white)
plotcircle(x, y, 10r, lwd=0, col=:white, fcol=:white)
end
plotcircle(0, 0, 40r, lwd=0, col=:white, fcol=:white)
plotcircle(0, 0, 30r, lwd=0, col=:black, fcol=:black)
plotigeta(r)
plotring(0, 0, 700r, 580r)
plotend()
end
kenkatabami()