裏 RjpWiki

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

算額(その637)

2024年01月13日 | Julia

算額(その637)

長野県上田市別所温泉 北向観音堂 文政11年(1828)
中村信弥「改訂増補 長野県の算額」

http://www.wasan.jp/zoho/zoho.html

2つの楕円が交差する中に等円が 4 個入っている。楕円の長径(差渡し)が 4 寸 9 分のとき,等円の直径が最大になるときの楕円の短径(差渡し)はいかほどか。

内接円の中心間の距離(eq1),楕円と円が共通接点を持つ(eq2, eq3),短径と円の中心の関係(eq4) があるが,eq1 〜 eq4 を一度に解くことができない。
それは,等円の半径は楕円の短径に依存するということが理由である。
そこで,例えば eq2, eq3, eq4 を連立させて r, x, y を求める。それぞれの式には b が含まれる。つまり,r, x, y は b により決定されるということである。

include("julia-source.txt");
# julia-source.txt ソース https://blog.goo.ne.jp/r-de-r/e/ad3a427b84bb416c4f5b73089ae813cf

using SymPy

@syms a::positive, b::positive, r::positive,
     x0::positive, x::positive, y::positive

a = 49//20
xx = sqrt((a^2 - b^2)*(b^2 - r^2))/b
eq1 = -b^2/a^2*x/y - (-(x - xx)/y)
eq2 = x^2/a^2 + y^2/b^2 - 1
eq3 = (x - xx)^2 + y^2 - r^2
eq4 = b + r - xx;

res = solve([eq2, eq3, eq4], (r, x, y))

   2-element Vector{Tuple{Sym, Sym, Sym}}:
    (-800*b^3/2401 + b, -sqrt(49 - sqrt(2401 - 1600*b^2))*sqrt(sqrt(2401 - 1600*b^2) + 49)/20, b*sqrt(2401 - 1600*b^2)/49)
    (-800*b^3/2401 + b, sqrt(49 - sqrt(2401 - 1600*b^2))*sqrt(sqrt(2401 - 1600*b^2) + 49)/20, b*sqrt(2401 - 1600*b^2)/49)

2 組の解が得られる。本質的にはどちらでもよいが,当初の予想と同じ符号になる 2 番目のものを適解とする。
r として得られた解をプロットしてみると,b = 1 近辺で最大値になることがわかる。

r = res[2][1]
pyplot(size=(400, 200), grid=false, aspectratio=:none, label="", fontfamily="IPAMincho")
plot(r, xlims=(0.95, 1.05), xlab="b", ylab="r")

r が最大になるのは b = 49*sqrt(6)/120 = 1.00020831163646 のときである。

b0 = solve(diff(res[1][1], b))[1]
(b0, b0.evalf()) |> println

   (49*sqrt(6)/120, 1.00020831163646)

b = 49*sqrt(6)/120 = 1.00020831163646 のときの r, x, y は以下の通りである。

r0 = res[2][1](b => b0)
x0 = res[2][2](b => b0)
y0 = res[2][3](b => b0)
(r0, x0, y0) |> println
(r0.evalf(), x0.evalf(), y0.evalf()) |> println

   (49*sqrt(6)/180, sqrt(49 - 49*sqrt(3)/3)*sqrt(49*sqrt(3)/3 + 49)/20, 49*sqrt(2)/120)
   (0.666805541090976, 2.00041662327293, 0.577470537969014)

その他のパラメータは以下の通り。

   a = 2.45;  b = 1.00021;  r = 0.666806;  xx = 2.00042;  x = 2.00042;  y = 0.577471

function draw(more=false)
   pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   a = 4.9/2
   b = 1.00020831163646
   (r, x, y) = (0.666805541090976, 2.00041662327293, 0.577470537969014)
   xx = sqrt((a^2 - b^2)*(b^2 - r^2))/b  # 1.67
   @printf("a = %g;  b = %g;  r = %g;  xx = %g;  x = %g;  y = %g\n", a, b, r, x0, x, y)
   plot()
   ellipse(0, 0, a, b, color=:red)
   ellipse(0, 0, b, a, color=:red)
   circle42(0, xx, r, :blue)
   if more
       delta = (fontheight = (ylims()[2]- ylims()[1]) / 500 * 10 * 2) /3  # size[2] * fontsize * 2
       vline!([0], color=:black, lw=0.5)
       hline!([0], color=:black, lw=0.5)
       point(xx, 0, "xx", :blue, :center, delta=-delta/2)
       point(x, y, "(x,y)", :blue, :left, :bottom, delta=delta/2)
       point(b, 0, "b  ", :red, :center, delta=-delta/2)
       point(a, 0, " a", :red, :center, delta=-delta/2)
   end
end;

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

算額(その636)

2024年01月13日 | Julia

算額(その636)

長野県北佐久郡軽井沢町峠 熊野神社 文政11年(1828)
中村信弥「改訂増補 長野県の算額」
http://www.wasan.jp/zoho/zoho.html

楕円内に大円 2 個,小円 7 個が入っている。楕円の長径(差渡し)が 95 寸のとき,小円の直径はいかほどか。



楕円の長径と短径(差渡し)を 2a, 2b; b = 3r2
大円の半径と中心座標を r1, (0, r2)
小円の半径と中心座標を r2, (r1 + r2, r2)
右上の小円と楕円との接点座標を (x, y)
とおき,以下の連立方程式を解く。

なお,a も未知数として解く(結果の式に a が含まれる)事もできるが,一般性を失わずに a = 1 としてとき,結果を定数倍する(この場合 95/2 倍)こともできる。特にこの問題では結果の式がかなり複雑になるので a = 1 として解くという方針で進める。

include("julia-source.txt");
# julia-source.txt ソース https://blog.goo.ne.jp/r-de-r/e/ad3a427b84bb416c4f5b73089ae813cf

using SymPy

@syms a::positive, b::positive, r1::positive, r2::positive,
     x::positive, y::positive

a = 1
b = 3r2
r1 = 2r2
x2 = 3r2
eq1 = -b^2/a^2*x/y - (-(x - x2)/(y - r2))
eq2 = x^2/a^2 + y^2/b^2 - 1
eq3 = (x - x2)^2 + (y - r2)^2 - r2^2;

res = solve([eq1, eq2, eq3], (r2, x, y))

   2-element Vector{Tuple{Sym, Sym, Sym}}:
    ((-5*sqrt(-37887 + 15468*sqrt(6))/8 - 3*sqrt(-25258 + 10312*sqrt(6))/4 + 9/8 + 4*sqrt(6)/3)/sqrt(-36 - sqrt(2)*sqrt(-12629 + 5156*sqrt(6)) + 79*sqrt(6)), (-2*sqrt(-37887 + 15468*sqrt(6))/5 - 2*sqrt(-25258 + 10312*sqrt(6))/5 + 2/5 + 22*sqrt(6)/5)/sqrt(-36 - sqrt(2)*sqrt(-12629 + 5156*sqrt(6)) + 79*sqrt(6)), sqrt(-27/800 - 3*sqrt(2)*sqrt(-12629 + 5156*sqrt(6))/3200 + 237*sqrt(6)/3200))
    ((3*sqrt(-25258 + 10312*sqrt(6))/4 + 5*sqrt(-37887 + 15468*sqrt(6))/8 + 9/8 + 4*sqrt(6)/3)/sqrt(-36 + sqrt(2)*sqrt(-12629 + 5156*sqrt(6)) + 79*sqrt(6)), (2/5 + 2*sqrt(-25258 + 10312*sqrt(6))/5 + 2*sqrt(-37887 + 15468*sqrt(6))/5 + 22*sqrt(6)/5)/sqrt(-36 + sqrt(2)*sqrt(-12629 + 5156*sqrt(6)) + 79*sqrt(6)), sqrt(-27/800 + 3*sqrt(2)*sqrt(-12629 + 5156*sqrt(6))/3200 + 237*sqrt(6)/3200))

2 組の解が得られるが,最初のものが適解である。

r2 の式はさほど長くはないが,短くすることはできる。多少の誤差は浮動小数点演算のせいである(多倍精度演算するとおなじになる)。

res[1][1] |> println

   (-5*sqrt(-37887 + 15468*sqrt(6))/8 - 3*sqrt(-25258 + 10312*sqrt(6))/4 + 9/8 + 4*sqrt(6)/3)/sqrt(-36 - sqrt(2)*sqrt(-12629 + 5156*sqrt(6)) + 79*sqrt(6))

term = sqrt(5156√big"6" - 12629)
e1 = (-5√3term/8 - 3√2term/4 + 9/8 + 4√6/3)/sqrt(-36 - √2term + 79√6)
e1

   0.2217968134779909378691753768002565302883462091899984084765888265892542449509785

res[1][1].evalf() |> println

   0.221796813477991

a = 95/2 のとき,結果をすべて a 倍する。
小円の直径 = 2*(95/2)*0.221796813477991 = 21.070697280409146

2*(95/2)*0.221796813477991

   21.070697280409146

その他のパラメータは以下の通りである。

a = 47.5;  b = 31.606;  r1 = 21.0707;  x2 = 10.5353;  x = 38.8437;  y = 18.191

function draw(more=false)
   pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r2, x, y) = 95//2 .* (
       (-5*sqrt(-37887 + 15468*sqrt(6))/8 - 3*sqrt(-25258 + 10312*sqrt(6))/4 + 9/8 + 4*sqrt(6)/3)/sqrt(-36 - sqrt(2)*sqrt(-12629 + 5156*sqrt(6)) + 79*sqrt(6)),
       (-2*sqrt(-37887 + 15468*sqrt(6))/5 - 2*sqrt(-25258 + 10312*sqrt(6))/5 + 2/5 + 22*sqrt(6)/5)/sqrt(-36 - sqrt(2)*sqrt(-12629 + 5156*sqrt(6)) + 79*sqrt(6)),
       sqrt(-27/800 - 3*sqrt(2)*sqrt(-12629 + 5156*sqrt(6))/3200 + 237*sqrt(6)/3200))
   a = 95/2
   b = 3r2
   r1 = 2r2
   x2 = 3r2
   @printf("小円の直径 = %.15g\n", 2r2)
   @printf("a = %g;  b = %g;  r1 = %g;  r2 = %g;  x2 = %g;  x = %g;  y = %g\n",
       a, b, r1, r2, x2, x, y)
   plot()
   ellipse(0, 0, a, b, color=:red)
   circle(0, b - 2r2, 2r2, :magenta)
   circle(0, 2r2 - b, 2r2, :magenta)
   circle(0, 2r2, r2, :blue)
   circle(0, -2r2, r2, :blue)
   circle(0, 0, r2, :blue)
   circle4(x2, r2, r2, :blue)
   if more
       delta = (fontheight = (ylims()[2]- ylims()[1]) / 500 * 10 * 2) /3  # size[2] * fontsize * 2
       vline!([0], color=:black, lw=0.5)
       hline!([0], color=:black, lw=0.5)
       point(x, y, "(x,y)", :red, :left, :bottom)
       point(3r2, r2, "(3r2,r2)", :blue, :center, delta=-delta/2)
       point(0, b, " b", :red, :left, :bottom, delta=delta/2)
       point(a, 0, "a ", :red, :right, :bottom, delta=delta/2)
   end
end;

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村