裏 RjpWiki

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

楕円の接線

2023年03月22日 | Julia

楕円の接線

原点を中心とする長径 a,短径 b の楕円がある。y 軸上に中心を持つ円がこの楕円に外接し,さらに円の中心を通る楕円の接線の傾きが slope であるとき,円の半径はいかほどか。

using SymPy

@syms a, b, x1, y1, r, tanθ

eq1 = x1^2/a^2 + y1^2/b^2 - 1
eq2 = -b^2*x1 / (a^2*y1) + (r + b - y1)/x1  #
eq3 = (r + b - y1)/x1 + tanθ;

res = solve([eq1, eq2, eq3], (x1, y1, r))

   2-element Vector{Tuple{Sym, Sym, Sym}}:
    (-a^2*tanθ/sqrt(a^2*tanθ^2 + b^2), b^2/sqrt(a^2*tanθ^2 + b^2), -b + sqrt(a^2*tanθ^2 + b^2))
    (a^2*tanθ/sqrt(a^2*tanθ^2 + b^2), -b^2/sqrt(a^2*tanθ^2 + b^2), -b - sqrt(a^2*tanθ^2 + b^2))

res[1][3] |> println

   -b + sqrt(a^2*tanθ^2 + b^2)

以上の結果に基づき,以下の関数を定義する。

引数

 楕円の長径 a,短径 b,接線の傾き(符号に注意)
戻り値
 接点の座標 (x, y),楕円に外接する円の半径 r

func(a, b, tanθ) = (-a^2*tanθ/sqrt(a^2*tanθ^2 + b^2), b^2/sqrt(a^2*tanθ^2 + b^2), -b + sqrt(a^2*tanθ^2 + b^2));

使用例

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360, fill=false)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   if fill
       plot!(ox .+ x, oy .+ y, linecolor=color, linewidth=0.5, seriestype=:shape, fillcolor=color)
   else
       plot!(ox .+ x, oy .+ y, color=color, linewidth=0.25)
   end
end;

function point(x, y, string="", color=:green, position=:left, vertical=:top; mark=true)
   mark && scatter!([x], [y], color=color, markerstrokewidth=0)
   annotate!(x, y, text(string, 10, position, color, vertical))
end;

function segment(x1, y1, x2, y2, color=:black; linestyle=:solid, linewidth=0.5)
   plot!([x1, x2], [y1, y2], color=color, linestyle=linestyle, linewidth=linewidth)
end;

function ellipse(ox, oy, ra, rb; φ=0, beginangle=0, endangle=360,
                    color=:black, lty=:solid, lwd=0.5, fcolor="")
"""
(ox, oy) を中心,ra, rb を半径とする楕円(楕円弧)。
fcolor を指定すると塗りつぶし。
"""
   θ = beginangle:0.1:endangle
   if φ == 0
       if fcolor == ""
           plot!(ra .* cosd.(θ) .+ ox, rb .* sind.(θ) .+ oy,
                 linecolor=color, linestyle=lty, linewidth=lwd)
       else
           plot!(ra .* cosd.(θ) .+ ox, rb .* sind.(θ) .+ oy,
                 linecolor=color, linestyle=lty, linewidth=lwd,
                 seriestype=:shape, fillcolor=fcolor)
       end
   else
       x = ra .* cosd.(θ)
       y = rb .* sind.(θ)
       cosine = cosd(φ)
       sine = sind(φ)
       if fcolor == ""
           plot!(cosine .* x .- sine .* y .+ ox,
                 sine .* x .+ cosine .* y .+ oy,
                 linecolor=color, linestyle=lty, linewidth=lwd)
       else
           plot!(cosine .* x .- sine .* y .+ ox,
                 sine .* x .+ cosine .* y .+ oy,
                 linecolor=color, linestyle=lty, linewidth=lwd,
                 seriestype=:shape, fillcolor=fcolor)
       end
   end
end;

using Plots
using Printf

function draw(a, b, c, more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (x1, y1, r1) = func(a, b, c)
   println("x1 = $x1, y1 = $y1, r1 = $r1")
   println("slope = $(-(r1 + b - y1)/x1)")
   plot()
   circle(0, r1+b, r1)
   ellipse(0, 0, a, b)
   segment(0, r1+b, x1, y1)
   if more == true
       point(x1, y1, " (x1,y1)", :green, :left, :bottom)
       point(0, b, " b")
       point(a, 0, " a", :green, :left, :top)
       point(0, r1+b, " r1+b")
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
      plot!(showaxis=false)
   end
end;

function draw3(a, b, num=6)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (x, y, r) = func(a, b, -cot(pi/num))
   plot()
   circle(0, 0, r, :aquamarine3, fill=true)
   deg = 360/num
   for i = 1:num
       deg2 = i*deg
       ellipse((r + b)cosd(deg2 - 90), (r + b)sind(deg2 - 90), a, b, φ = deg2, color=:lightgoldenrod1, fcolor=:lightgoldenrod1)
   end
   plot!(showaxis=false)
end;

draw3(3, 2, 11)


コメント    この記事についてブログを書く
  • Twitterでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 算額(その174) | トップ | 算額(その175) »
最新の画像もっと見る

コメントを投稿

Julia」カテゴリの最新記事