裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

家紋シリーズ 片喰(1) 丸に角立て井筒に剣片喰

2021年09月10日 | ブログラミング

家紋シリーズ 片喰(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()

 

 

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 家紋シリーズ 三つ兎 | トップ | 家紋シリーズ 片喰(2) 丸に... »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事