裏 RjpWiki

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

算額(その142)

2023年02月25日 | Julia

算額(その142)

三重県四日市市 神明神社 寛政2年

三重県に現存する算額の研究
https://mie-u.repo.nii.ac.jp/?action=repository_uri&item_id=7216&file_id=17&file_no=1

第3問 直角三角形の中に 5 個の円がある。乾円,坤円の直径が与えられているとき,鉤の長さを求めよ。

乾円と坤円の半径を 8, 5 とする。下図のように記号を定め,式を立て,解く。solve() ではなく,nlsolve() による。

using SymPy

@syms r1, r2, r3, x2, x3, r4, r5, x4, x5, x, y;
r4 = 8
r5 = 5
eq1 = (x2 - r1)^2 + (r1 - r2)^2 - (r1 + r2)^2  # 日月
eq2 = (x3 - x2)^2 + (r2 - r3)^2 - (r2 + r3)^2  # 月星
eq3 = (x4 - r1)^2 + (r1 - r4)^2 - (r1 + r4)^2  # 日乾
eq4 = (x2 - x4)^2 + (r2 - r4)^2 - (r2 + r4)^2  # 月乾
eq5 = (x5 - x2)^2 + (r2 - r5)^2 - (r2 + r5)^2  # 月坤
eq6 = (x3 - x5)^2 + (r3 - r5)^2 - (r3 + r5)^2  # 星坤
eq7 = r1*(x + y + sqrt(x^2 + y^2)) - x*y  # 直角三角形の面積
eq8 = r1/(x - r1) - r2/(x - x2)  # 半径の関係(三角形の相似)
eq9 = r1/(x - r1) - r3/(x - x3); # 半径の関係(三角形の相似)

# res = solve([eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8, eq9])

println(eq1, ",")
println(eq2, ",")
println(eq3, ",")
println(eq4, ",")
println(eq5, ",")
println(eq6, ",")
println(eq7, ",")
println(eq8, ",")
println(eq9, ",")

   (-r1 + x2)^2 + (r1 - r2)^2 - (r1 + r2)^2,
   (r2 - r3)^2 - (r2 + r3)^2 + (-x2 + x3)^2,
   (-r1 + x4)^2 + (r1 - 8)^2 - (r1 + 8)^2,
   (r2 - 8)^2 - (r2 + 8)^2 + (x2 - x4)^2,
   (r2 - 5)^2 - (r2 + 5)^2 + (-x2 + x5)^2,
   (r3 - 5)^2 - (r3 + 5)^2 + (x3 - x5)^2,
   r1*(x + y + sqrt(x^2 + y^2)) - x*y,
   r1/(-r1 + x) - r2/(x - x2),
   r1/(-r1 + x) - r3/(x - x3),

using NLsolve

function nls(func, params...; ini = [0.0])
   if typeof(ini) <: Number
       r = nlsolve((vout, vin) -> vout[1] = func(vin[1], params..., [ini]))#, ftol=1e-14)
       v = r.zero[1]
   else
       r = nlsolve((vout, vin)->vout .= func(vin, params...), ini)#, ftol=1e-14)
       v = r.zero
   end
   return v, r.f_converged
end;

function H(u)
   (r1, r2, r3, x2, x3, x4, x5, x, y) = u
   return [
       (-r1 + x2)^2 + (r1 - r2)^2 - (r1 + r2)^2,
       (r2 - r3)^2 - (r2 + r3)^2 + (-x2 + x3)^2,
       (-r1 + x4)^2 + (r1 - 8)^2 - (r1 + 8)^2,
       (r2 - 8)^2 - (r2 + 8)^2 + (x2 - x4)^2,
       (r2 - 5)^2 - (r2 + 5)^2 + (-x2 + x5)^2,
       (r3 - 5)^2 - (r3 + 5)^2 + (x3 - x5)^2,
       r1*(x + y + sqrt(x^2 + y^2)) - x*y,
       r1/(-r1 + x) - r2/(x - x2),
       r1/(-r1 + x) - r3/(x - x3),
   ]
end;

iniv = [40.0, 25, 18, 101, 145, 72, 125, 230, 95]
res = nls(H, ini=iniv)
println(res)


   ([41.038577025077615, 25.64911064067352, 16.030694150420956, 105.92626469082875, 146.4810694819232, 77.27715405015523, 128.57537533150227, 214.0724108004141, 107.59571957603235], true)

勾は 107.59571957603235 であることが分かった。

引用文献に乾円と坤円の直径をm, n としたときに勾の長さを得る式が記載されている。

f(m, n) = 2m*sqrt(m)*(sqrt(m) + sqrt(n))^2/sqrt(n)/(2*sqrt(m*n) - m + n)
f(2*8, 2*5)

   107.59571957603244

m,n が整数値のとき,勾が整数になるのは (4, 1), (147, 27), (525, 189), (1134, 224) などとその整数倍のときである。

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=0.5)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r1, r2, r3, x2, x3, x4, x5, x, y) = res[1]
   @printf("勾: %.5f\n", y)  
   plot([0, x, 0, 0], [0, 0, y, 0], color=:black, lw=0.5)
   circle(r1, r1, r1)
   circle(x2, r2, r2, :blue)
   circle(x3, r3, r3, :magenta)
   circle(x4, r4, r4, :orange)
   circle(x5, r5, r5, :green)
   if more == true
       point(r1, r1, "日:(r1,r1)", :red, :center, :bottom)
       point(x2, r2, "月:(x2,r2)", :blue, :center, :bottom)
       point(x3, r3, "星:(x3,r3)", :magenta, :center, :bottom)
       point(x4, r4, "乾:(x4,r4)", :orange, :center, :bottom)
       point(x5, r5, "坤:(x5,r5)", :green, :center, :bottom)
       point(0, y, " y", :black, :left, :bottom)
       point(x, 0, " x", :black, :left, :bottom)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

draw(false)

   勾: 107.59572

 

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

なんで,エラーになるの?

2023年02月24日 | Julia

今日,別のプログラムを書いていて,初期値設定のときにエラー発生。なんで??

以下はなんの問題もないですね。

julia> x = [1, -2, 3 + 3]

3-element Vector{Int64}:

  1

-2

  6

しかし,以下はエラーになりました。

julia> x = [1, -2, 3 +3]

ERROR: syntax: missing separator in array expression

Stacktrace:

[1] top-level scope

   @ none:1

まあ,「それはエラーだよねえ」とも思いますが。どうも,しっくり来ません。か???

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

算額(その141)

2023年02月24日 | Julia

算額(その141)

福島県田村郡三春町御木沢 厳島神社 明治18年(1885)1月
http://www.wasan.jp/fukusima/miharuitukusima5.html

半円の中に大中小の正方形が入っている。それぞれの正方形の一辺の長さを求めよ。

半円の半径を1,大中小の正方形の一辺の長さを a, b, c とおく。方程式を立て,解く。

using SymPy

@syms a::positive, b::positive, c::positive;
eq2 = (1 - 2a)/a - c/(b - c);  # 直角三角形が相似であることから
eq3 = (1 - b)/(a + b) - (2a - b)/b;  # 直角三角形が相似であることから
eq5 = (a + b)^2 + b^2 - 1;  # 右の中正方形の右上隅が円周上にあることから

res = solve([eq2, eq3, eq5], (a, b, c))

   1-element Vector{Tuple{Sym, Sym, Sym}}:
    (-2^(2/3)/5 + 1/5 + 2*2^(1/3)/5, -2/5 + 2^(1/3)/5 + 2*2^(2/3)/5, -4/5 + 3*2^(2/3)/10 + 2*2^(1/3)/5)

(-2^(2/3)/5 + 1/5 + 2*2^(1/3)/5, b-2/5 + 2^(1/3)/5 + 2*2^(2/3)/5, -4/5 + 3*2^(2/3)/10 + 2*2^(1/3)/5)

   (0.3864882095643094, b + 0.486944630766254, 0.18018873554840903)

正方形の一辺は,大: 0.77298,  中: 0.48694,  小: 0.18019 である。
算額では,中の一辺が与えられたとき小の一辺はいくつになるかとあるので,中の一辺の 0.18018873554840903/0.4869446307662544 = 0.3700394750525633 倍が,小の一辺である。
算額の答えは「2.5 を解立法し(3乗根を取り),1を引いたものを中の一辺に掛ける」と読める。2.5^(1/3) - 1 = 0.35720880829745316 なので,あまりよい近似ではない。

using Plots
using Printf

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, color=color, linewidth=0.5, seriestype=:shape, fillcolor=color)
   else
       plot!(ox .+ x, oy .+ y, color=color, linewidth=0.5)
   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 filledsquare(x1, y1, x2, y2, color=:black)
   plot!([x1, x2, x2, x1, x1], [y1, y1, y2, y2, y1], seriestype=:shape, fillcolor=color, color=color, lw=0.25)
end

function draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (a, b, c) = res[1]
   @printf("大: %.5f,  中: %.5f,  小: %.5f\n", 2a, b, c)  
   plot()
   circle(0, 0, 1, :blue, beginangle=0, endangle=180, fill=true)
   plot!([a + b, 0, -a - b, a + b], [b, 1, b, b], seriestype=:shape, fillcolor=:snow2, color=:snow2, lw=0.25)
   filledsquare(-a, 0, a, 2a, :red)
   filledsquare(a, 0, a + b, b, :navajowhite) 
   filledsquare(-a, 0, -a - b, b, :navajowhite) 
   filledsquare(a, b, a + c, b + c, :white)
   filledsquare(-a, b, -a - c, b + c, :white)
   segment(0, 1, a + b, b)
   segment(0, 1, -a - b, b)
   segment(-1, 0, 1, 0, :black)
   if more == true
       point(a, 0, "a")
       point(0, 2a, "2a ", :black, :right)
       point(a + c, b + c, "((a+c,b+c) ", :black, :right, :bottom)
       point(a + b, 0, "a+b")
       point(a + b, b, "(a+b,b) ", :black, :right)
       point(0, a, "大", :black, :right)
       point(a + b/2, b/2, "中", :black, :right)
       point(a + c/2, b + c/2, "小", :black, :right)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5, ylims=(-0.075, 1))
   else
       plot!(showaxis=false)
   end
end;

draw(false)

   大: 0.77298,  中: 0.48694,  小: 0.18019

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

算額(その140)

2023年02月24日 | Julia

算額(その140)

福島県白河市明神 境明神 万延元年(1860)9月
http://www.wasan.jp/fukusima/sakai1.html

長方形の中に,半円 2 個,天円 4 個,地円 2 個,人円 2 個が入っている。人円の径が 1 寸のとき,天円の径はいくらか。

半円,天円,地円,人円の半径 をそれぞれ r0, r1, r2, r3 = 1 とおく。天円,地円の中心の x 座標を x1, x2 とおく。方程式を立て,解く。

using SymPy

@syms r0::positive, r1::positive, r2::positive, r3::positive, x1::positive, x2::positive;
r3 = 1
eq1 = x2^2 + r3^2 - (r2 + r3)^2  # 地円と人円が外接する
eq2 = x2^2 + (2r3 + r0)^2 - (r0 + r2)^2  # 半円と地円が外接する
eq3 = (x1 - x2)^2 + r1^2 - (r1 + r2)^2  # 天円と地円が外接する
eq4 = x1^2 + (2r3 + r0 - r1)^2 - (r0 + r1)^2  # 半円と天円が外接する
eq5 = 2r3 + r0 - 2r1;  # 半径の関係

res = solve([eq1, eq2, eq3, eq4, eq5], (r0, r1, r2, x1, x2))

   1-element Vector{NTuple{5, Sym}}:
    (6, 4, 14/5, 2*sqrt(21), 4*sqrt(21)/5)

天円の半径は 4,元の単位では天円の直径は 4 寸
ちなみに半円の直径は 6 寸,地円の直径は 14/5 = 2寸8分。

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360, lw=0.5, linestyle=:solid)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=lw, linestyle=linestyle)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r0, r1, r2, x1, x2) = res[1]
   @printf("半円の半径 = %.3f\n", r0)
   @printf("天円の半径 = %.3f\n", r1)
   @printf("地円の半径 = %.3f\n", r2)
   plot([x1 + r1, x1 + r1, -x1 - r1, -x1 - r1, x1 + r1], [-2r1, 2r1, 2r1, -2r1, -2r1])
   circle(0, 2r3 + r0, r0, beginangle=180, endangle=360)
   circle(0, -2r3 - r0, r0, beginangle=0, endangle=180)
   circle(x1, r1, r1, :blue)
   circle(x1, -r1, r1, :blue)
   circle(-x1, r1, r1, :blue)
   circle(-x1, -r1, r1, :blue)
   circle(x2, 0, r2, :green)
   circle(-x2, 0, r2, :green)
   circle(0, r3, r3, :orange)
   circle(0, -r3, r3, :orange)
   if more == true
       point(0, 2r3 + r0, "2r3+r0 ", :red, :right)
       point(0, r3, "r3", :orange, :right)
       point(x2, 0, "x2", :green, :center)
       point(x2+r1, 0, "x2+r2 ", :green, :right)
       point(x1, 0, "x1", :blue, :center)
       point(x1, r1, "(x1,r1)", :blue, :center)
       point(x1 + r1, 0, "x1+r1", :blue, :right)
       point(x1 + r1, 2r1, "(x1+r1,2r1) ", :blue, :right)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

draw(false)

   半円の半径 = 6.000
   天円の半径 = 4.000
   地円の半径 = 2.800

 

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

算額(その139)

2023年02月24日 | Julia

算額(その139)

大阪府茨木市 井於神社 弘化3年(1846)
http://www.wasan.jp/osaka/iyo.html

鉤,股,弦がそれぞれ 3寸1分,3寸6分,4寸8分である三角形が2本の斜線で区切られ,径の同じ円が 2 個入っている。円の径を求めよ。

鉤股弦とはいっているが,直角三角形ではない。鉤と股をそのままの数値として受け入れれば,弦は 4.750789408087881 寸でなければならない。

鉤 = 31, 股 = 36 円の半径を r,それぞれの中心座標を (r, y), (x, r) とおき,直線までの距離に関する方程式を立て,解く。



solve() では解けないので,nlsolve() で数値解を求める。

using SymPy

function distance(x1, y1, x2, y2, x0, y0)
   l = sympy.Line(sympy.Point(x1, y1), sympy.Point(x2, y2))
   l.distance(sympy.Point(x0, y0))^2  # 二乗距離を返す!!
end;

@syms r::positive, x::positive, y::positive, x0::positive, y0::positive;
eq1 = distance(0, 31, x0, y0, r, y) - r^2  # 円1の中心から BD への距離
eq2 = distance(0, 31, x0, y0, x, r) - r^2  # 円2の中心から BD への距離
eq3 = distance(0, 31, 36,  0, x, r) - r^2  # 円2の中心から AB への距離
eq4 = distance(0,  0, x0, y0, r, y) - r^2  # 円1の中心から OC への距離
eq5 = distance(0,  0, x0, y0, x, r) - r^2; # 円2の中心から OC への距離

# res = solve([eq1, eq2, eq3, eq4, eq5], (r, x, y, x0, y0))

println(eq1, ",")
println(eq2, ",")
println(eq3, ",")
println(eq4, ",")
println(eq5, ",")


   -r^2 + (r - x0*(r*x0 + y*y0 - 31*y - 31*y0 + 961)/(x0^2 + y0^2 - 62*y0 + 961))^2 + (y - (r*x0*y0 - 31*r*x0 + 31*x0^2 + y*y0^2 - 62*y*y0 + 961*y)/(x0^2 + y0^2 - 62*y0 + 961))^2,
   -r^2 + (r - (r*y0^2 - 62*r*y0 + 961*r + x*x0*y0 - 31*x*x0 + 31*x0^2)/(x0^2 + y0^2 - 62*y0 + 961))^2 + (x - x0*(r*y0 - 31*r + x*x0 - 31*y0 + 961)/(x0^2 + y0^2 - 62*y0 + 961))^2,
   -r^2 + (1116*r/2257 + 961*x/2257 - 34596/2257)^2 + (1296*r/2257 + 1116*x/2257 - 40176/2257)^2,
   -r^2 + (r - x0*(r*x0 + y*y0)/(x0^2 + y0^2))^2 + (y - y0*(r*x0 + y*y0)/(x0^2 + y0^2))^2,
   -r^2 + (r - y0*(r*y0 + x*x0)/(x0^2 + y0^2))^2 + (x - x0*(r*y0 + x*x0)/(x0^2 + y0^2))^2,

using NLsolve

function nls(func, params...; ini = [0.0])
   if typeof(ini) <: Number
       r = nlsolve((vout, vin) -> vout[1] = func(vin[1], params..., [ini]))#, ftol=1e-14)
       v = r.zero[1]
   else
       r = nlsolve((vout, vin)->vout .= func(vin, params...), ini)#, ftol=1e-14)
       v = r.zero
   end
   return v, r.f_converged
end;

function H(u)
   (r, x, y, x0, y0) = u
   return [
       -r^2 + (r - x0*(r*x0 + y*y0 - 31*y - 31*y0 + 961)/(x0^2 + y0^2 - 62*y0 + 961))^2 + (y - (r*x0*y0 - 31*r*x0 + 31*x0^2 + y*y0^2 - 62*y*y0 + 961*y)/(x0^2 + y0^2 - 62*y0 + 961))^2,
       -r^2 + (r - (r*y0^2 - 62*r*y0 + 961*r + x*x0*y0 - 31*x*x0 + 31*x0^2)/(x0^2 + y0^2 - 62*y0 + 961))^2 + (x - x0*(r*y0 - 31*r + x*x0 - 31*y0 + 961)/(x0^2 + y0^2 - 62*y0 + 961))^2,
       -r^2 + (1116*r/2257 + 961*x/2257 - 34596/2257)^2 + (1296*r/2257 + 1116*x/2257 - 40176/2257)^2,
       -r^2 + (r - x0*(r*x0 + y*y0)/(x0^2 + y0^2))^2 + (y - y0*(r*x0 + y*y0)/(x0^2 + y0^2))^2,
       -r^2 + (r - y0*(r*y0 + x*x0)/(x0^2 + y0^2))^2 + (x - x0*(r*y0 + x*x0)/(x0^2 + y0^2))^2,
   ]
end;

iniv = [5.0, 20, 10, 12, 10]
res = nls(H, ini=iniv)
println(res)

   ([5.6146321148429355, 20.875286969374045, 9.74605295956063, 13.244959542108463, 7.680342537201841], true)

直径は 2 × 5.6146321148429355 ≒ 11寸2分2厘9毛である。算額では 9分4厘5毛になっている。

~井於神社奉納「算額」について~ http://io-jinja.org/sangakusetumei.html に引用されている,「算術稽古大全」宅間流五世松岡能一,文化5年(1808) に以下が示されているとあるが,これはまた以上の 2 通りの解とも違う。

(鉤, 股, 弦) = (3.1, 3.6, 4.8)
天 = 鉤 + 股 + 弦
等円径 = (sqrt(2天 * 鉤) + 天) / 2(鉤*股)

   0.8935453733438091

弦に正しい(?)数値を代入しても異なる解になる。

(鉤, 股, 弦) = (3.1, 3.6, 4.750789408087881)
天 = 鉤 + 股 + 弦
等円径 = (sqrt(2天 * 鉤) + 天) / 2(鉤*股)

   0.8905302961492191

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360, lw=0.5, linestyle=:solid)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=lw, linestyle=linestyle)
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 intersection(x1, y1, x2, y2, x3, y3, x4, y4)
   denominator = (x1*y3 - x1*y4 - x2*y3 + x2*y4 - x3*y1 + x3*y2 + x4*y1 - x4*y2)
   X = (x1*x3*y2 - x1*x3*y4 - x1*x4*y2 + x1*x4*y3 - x2*x3*y1 + x2*x3*y4 + x2*x4*y1 - x2*x4*y3) / denominator
   Y = (x1*y2*y3 - x1*y2*y4 - x2*y1*y3 + x2*y1*y4 - x3*y1*y4 + x3*y2*y4 + x4*y1*y3 - x4*y2*y3) / denominator
   (X, Y)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r, x, y, x0, y0) = res[1]
   @printf("円の直径 = %.3f\n", 2r)
   plot([0, 36, 0, 0], [0, 0, 31, 0])
   circle(r, y, r)
   circle(x, r, r)
   (X1, Y1) = intersection(0, 0, x0, y0, 0, 31, 36, 0)
   segment(0, 0, X1, Y1)
   (X2, Y2) = intersection(0, 31, x0, y0, 0, 0, 36, 0)
   segment(0, 31, X2, Y2)
   if more == true
       point(r, y, "円1(r,y;r)", :red, :center, :top)
       point(x, r, "円2(x,r;r)", :red, :center, :top)
       point(x0, y0, "(x0,y0)", :red)
       point(0, 0, "O ", :blue, :right, :bottom)
       point(36, 0, " A", :blue, :left, :bottom)
       point(0, 31, " B", :blue, :left, :bottom)
       point(X1, Y1, " C", :blue, :left, :bottom)
       point(X2, Y2, "D  ", :blue, :right, :bottom)
       hline!([0], color=:black, lw=0.5, xlims=(-2, 38))
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

draw(false)

   円の直径 = 11.229

 

 

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

算額(その138)

2023年02月23日 | Julia

算額(その138)

兵庫県西宮市社家町 西宮えびす神社 天保13年(1842) 
http://www.wasan.jp/hyogo/nisinomiya.html

径が 10 寸の外円の中に,大円 2 個と,小円 3 円が入っている。小円の径を求めよ。

図のように,外円の半径を 1,大円と小円の半径を r1, r2 とし,方程式を解く。

using SymPy

@syms r1::positive, r2::positive;
eq1 = 2r1 - r2 - 1;  # 外円,大円,小円の半径の関係
eq2 = (1 - r2)^2 + (1 - r1)^2 - (r1 + r2)^2;  # 上の大円と右の小円が外接している

res = solve([eq1, eq2], (r1, r2))

   1-element Vector{Tuple{Sym, Sym}}:
    (-1/2 + sqrt(5)/2, -2 + sqrt(5))

(res[1][1].evalf(), res[1][2].evalf())

   (0.618033988749895, 0.236067977499790)

元の問題では外円の直径が 10 寸である。小円は外円の 0.236067977499790 倍。すなわち,小円の径は約 2寸3分6厘 である

図に描いたとき,真ん中の小円が両脇の小円に比べてやや小さく見えるのは,錯視の効果である。

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360, lw=0.5, linestyle=:solid)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=lw, linestyle=linestyle)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r1, r2) = res[1]
   println("大円の半径 = $r1 = $(r1.evalf())")
   println("小円の半径 = $r2 = $(r2.evalf())")
   plot()
   circle(0, 0, 1)
   circle(0, 1 - r1, r1, :green)
   circle(0, r1 - 1, r1, :green)
   circle(0, 0, r2, :blue)
   circle(1 - r2, 0, r2, :blue)
   circle(r2 - 1, 0, r2, :blue)
   if more == true
       point(0, 1 - r1, "1-r1 ", :green)
       point(1 - r2, 0, "1-r2 ", :blue)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

draw(false)

   大円の半径 = -1/2 + sqrt(5)/2 = 0.618033988749895
   小円の半径 = -2 + sqrt(5) = 0.236067977499790

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

算額(その137)

2023年02月23日 | Julia

算額(その137)

千葉県千葉市中央区 延命寺 嘉永5(1852)年 
http://www.wasan.jp/chiba/enmeiji.html

外円の中に,上円,中円,下円が入っている。上円と下円の径が与えられたとき,外円の径はいかほどか。

外円,上円,中円,下円の半径を r0, r1, r2, r3,中円の中心の座標を (x1, y2) として,図のように記号を定め方程式を解く。

using SymPy

@syms r0::positive, r1::positive, r2::positive, y2::negative, r3::positive;
eq1 = r2^2 + (r0 - r1 - y2)^2 - (r1 + r2)^2;  # 上円と中円が外接する
eq2 = r2^2 + (y2 - r3 + r0)^2 - (r2 + r3)^2;  # 中円と下円が外接する
eq3 = r2^2 + y2^2 - (r0 - r2)^2;              # 外円に中円が内接する

res = solve([eq2, eq3, eq1], (r0, r2, y2))

   2-element Vector{Tuple{Sym, Sym, Sym}}:
    ((-r1^3 - 3*r1^2*r3 + r1^2*sqrt(r1^2 + 14*r1*r3 + r3^2) - 3*r1*r3^2 - 4*r1*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) - r3^3 + r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2))/(-r1^2 + 10*r1*r3 + r1*sqrt(r1^2 + 14*r1*r3 + r3^2) - r3^2 + r3*sqrt(r1^2 + 14*r1*r3 + r3^2)), 4*r1*r3*(r1^3 - 33*r1^2*r3 - r1^2*sqrt(r1^2 + 14*r1*r3 + r3^2) - 33*r1*r3^2 - 14*r1*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^3 - r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1^4 - 12*r1^3*r3 - r1^3*sqrt(r1^2 + 14*r1*r3 + r3^2) + 22*r1^2*r3^2 + r1^2*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) - 12*r1*r3^3 + r1*r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^4 - r3^3*sqrt(r1^2 + 14*r1*r3 + r3^2)), (-r1^2 + 10*r1*r3 + r1*sqrt(r1^2 + 14*r1*r3 + r3^2) - r3^2 + r3*sqrt(r1^2 + 14*r1*r3 + r3^2))/(2*r1 - 2*r3))
    ((r1^3 + 3*r1^2*r3 + r1^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + 3*r1*r3^2 - 4*r1*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^3 + r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1^2 - 10*r1*r3 + r1*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^2 + r3*sqrt(r1^2 + 14*r1*r3 + r3^2)), 4*r1*r3*(r1^3 - 33*r1^2*r3 + r1^2*sqrt(r1^2 + 14*r1*r3 + r3^2) - 33*r1*r3^2 + 14*r1*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^3 + r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1^4 - 12*r1^3*r3 + r1^3*sqrt(r1^2 + 14*r1*r3 + r3^2) + 22*r1^2*r3^2 - r1^2*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) - 12*r1*r3^3 - r1*r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^4 + r3^3*sqrt(r1^2 + 14*r1*r3 + r3^2)), (-r1^2 + 10*r1*r3 - r1*sqrt(r1^2 + 14*r1*r3 + r3^2) - r3^2 - r3*sqrt(r1^2 + 14*r1*r3 + r3^2))/(2*r1 - 2*r3))

最初の解は不適切解である。

2番めの解の r0 もかなり複雑な式になり,simplify() でも簡単にできない。簡約化は,このページの最後に示す。
r0 = (r1^3 + 3*r1^2*r3 + r1^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + 3*r1*r3^2 - 4*r1*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^3 + r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1^2 - 10*r1*r3 + r1*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^2 + r3*sqrt(r1^2 + 14*r1*r3 + r3^2))

sqrt(r1^2 + 14*r1*r3 + r3^2) が何回も出てくるので,term = sqrt(r1^2 + 14*r1*r3 + r3^2) とすると,若干短くはなる。
r0 = (r1^3 + 3*r1^2*r3 + r1^2*term + 3*r1*r3^2 - 4*r1*r3*term + r3^3 + r3^2*term)/(r1^2 - 10*r1*r3 + r1*term + r3^2 + r3*term)

「算額の意義」には,計算過程抜きで,上円と下円の直径を与えて外円の直径を求める式が書かれている。

記号を会わせると以下のようになる。
A = r3 / r1, B = (A + 1) / 2 とすると
r0 = (√(B^2 + 3A) + B) × r1

この r0 を求める式を A, B を用いずに書き下すと
r1/2 + r3/2 + sqrt(r1^2 + 14*r1*r3 + r3^2)/2
となり,sqrt(r1^2 + 14*r1*r3 + r3^2) が現れるので,SymPy による長い式も簡単になることと思われる。このページの最後に示す。

SymPy による r0 を求める式による解と両方を求める関数を書いて,正しいことを確認すると,両者は同じ答えを返すことが分かった。

いずれにしろ,外円の直径を求める場合に,中円の直径は不要であるということは特筆しておくべきことであろう。

function getr0(r1, r3)
   A = r3 / r1
   B = (A + 1) / 2
   result1 = (sqrt(B^2 + 3A) + B) * r1
   result2 = (r1^3 + 3*r1^2*r3 + r1^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + 3*r1*r3^2 - 4*r1*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^3 + r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1^2 - 10*r1*r3 + r1*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^2 + r3*sqrt(r1^2 + 14*r1*r3 + r3^2))
   term = sqrt(r1^2 + 14*r1*r3 + r3^2)
   result3 = (r1^3 + 3*r1^2*r3 + r1^2*term + 3*r1*r3^2 - 4*r1*r3*term + r3^3 + r3^2*term)/(r1^2 - 10*r1*r3 + r1*term + r3^2 + r3*term)
   return (result1, result2, result3)
end;
getr0(10, 5) |> println
getr0(40, 23) |> println
getr0(123.456, 78.9) |> println

   (21.86140661634507, 21.861406616345057, 21.861406616345057)
   (92.75561198780075, 92.7556119878007, 92.7556119878007)
   (299.8209532704345, 299.82095327043413, 299.82095327043413)

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360, lw=0.5, linestyle=:solid)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=lw, linestyle=linestyle)
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 draw(r1, r3, more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   term = sqrt(r1^2 + 14*r1*r3 + r3^2)
   r0 = (r1^3 + 3*r1^2*r3 + r1^2*term + 3*r1*r3^2 - 4*r1*r3*term + r3^3 + r3^2*term)/(r1^2 - 10*r1*r3 + r1*term + r3^2 + r3*term)
   r2 = 4*r1*r3*(r1^3 - 33*r1^2*r3 + r1^2*term - 33*r1*r3^2 + 14*r1*r3*term + r3^3 + r3^2*term)/(r1^4 - 12*r1^3*r3 + r1^3*term + 22*r1^2*r3^2 - r1^2*r3*term - 12*r1*r3^3 - r1*r3^2*term + r3^4 + r3^3*term)
   y2 =(-r1^2 + 10*r1*r3 - r1*term - r3^2 - r3*term)/(2*r1 - 2*r3)
   # 簡約化
   # r0 = r1/2 + r3/2 + sqrt(r1^2 + 14*r1*r3 + r3^2)/2
   # r2 = 4*r1*r3*(2*r1 + 2*r3 - sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1 - r3)^2
   println("外円の半径 = $r0")
   println("中円の半径 = $r2")
   println("中円の中心座標 = ($r2, $y2)")
   plot()
   circle(0, 0, r0)
   circle(r2, y2, r2, :orange)
   circle(-r2, y2, r2, :orange)
   circle(0, r0 - r1, r1)
   circle(0, r3 - r0, r3, :blue)
   if more == true
       point(0, r0 - r1, "r0-r1 ", :red, :right)
       point(r2, y2, "(r2,y2;r2)", :orange, :center, :top)
       point(0, r3 - r0, "r3-r0", :blue, :right)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

draw(60, 20, false)

   外円の半径 = 112.1110255092798
   中円の半径 = 47.33384694432096
   中円の中心座標 = (47.33384694432096, -44.222051018559554)

上円,下円の半径を変えてみる。

draw(23.5, 30.9, false)

   外円の半径 = 81.22119954240218
   中円の半径 = 40.184945549364414
   中円の中心座標 = (40.184945549364414, 8.315304744143447)

-----

SymPy により得られた r0 を簡約化する。つまり,分母を有理化する。有理化は自動的には行われず,途中でも単に simplify では式が簡約化されず expand, factor, simplify を適用順も考慮して組み合わせて式変形を行う。

r0 = (r1^3 + 3*r1^2*r3 + r1^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + 3*r1*r3^2 - 4*r1*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^3 + r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1^2 - 10*r1*r3 + r1*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^2 + r3*sqrt(r1^2 + 14*r1*r3 + r3^2));

r0 を簡約化する。

まず,分母について整理する。

d = denominator(r0);
d |> println

   r1^2 - 10*r1*r3 + r1*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^2 + r3*sqrt(r1^2 + 14*r1*r3 + r3^2)

sqrt(r1^2 + 14*r1*r3 + r3^2) の項の符号を反転させたものを掛ける。

d1 = (r1^2 - 10*r1*r3 + r1*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^2 + r3*sqrt(r1^2 + 14*r1*r3 + r3^2)) *
    (r1^2 - 10*r1*r3 - r1*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^2 - r3*sqrt(r1^2 + 14*r1*r3 + r3^2));

簡約化と因子分解を行う。

d2 = d1 |> simplify |> factor;
d2 |> println

   -36*r1*r3*(r1 - r3)^2

次に分母にかけたものと同じものを分子にも掛ける。

n1 = numerator(r0) * ((r1^2 - 10*r1*r3 + r3^2) - (r1 + r3) * sqrt(r1^2 + 14*r1*r3 + r3^2));

一度展開してから因子分解する。

n2 = n1 |> expand |> factor;
n2 |> println

   -18*r1*r3*(r1 - r3)^2*(r1 + r3 + sqrt(r1^2 + 14*r1*r3 + r3^2))

r0 は n2/d2 である。

res = n2/d2;
println(res)

   r1/2 + r3/2 + sqrt(r1^2 + 14*r1*r3 + r3^2)/2

これが簡約化された式で,http://www.wasan.jp/chiba/enmeiji.html に示されたものと同じである。

式変形に間違いがないか確認する。

res(r1 => 30, r3 => 10).evalf()

   56.0555127546399

r0(r1 => 30, r3 => 10).evalf()

   56.0555127546399

同様に,r2 も簡約化する。

r2 = 4*r1*r3*(r1^3 - 33*r1^2*r3 + r1^2*sqrt(r1^2 + 14*r1*r3 + r3^2) - 33*r1*r3^2 + 14*r1*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^3 + r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1^4 - 12*r1^3*r3 + r1^3*sqrt(r1^2 + 14*r1*r3 + r3^2) + 22*r1^2*r3^2 - r1^2*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) - 12*r1*r3^3 - r1*r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^4 + r3^3*sqrt(r1^2 + 14*r1*r3 + r3^2));

d1 = denominator(r2);
d1 |> println

   r1^4 - 12*r1^3*r3 + r1^3*sqrt(r1^2 + 14*r1*r3 + r3^2) + 22*r1^2*r3^2 - r1^2*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) - 12*r1*r3^3 - r1*r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^4 + r3^3*sqrt(r1^2 + 14*r1*r3 + r3^2)

分母の有理化(sqrt(r1^2 + 14*r1*r3 + r3^2) の項の符号を反転させたものを掛ける)

d2 = (r1^4 - 12*r1^3*r3 + r1^3*sqrt(r1^2 + 14*r1*r3 + r3^2) + 22*r1^2*r3^2 - r1^2*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) - 12*r1*r3^3 - r1*r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^4 + r3^3*sqrt(r1^2 + 14*r1*r3 + r3^2)) *
(r1^4 - 12*r1^3*r3 - r1^3*sqrt(r1^2 + 14*r1*r3 + r3^2) + 22*r1^2*r3^2 + r1^2*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) - 12*r1*r3^3 + r1*r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^4 - r3^3*sqrt(r1^2 + 14*r1*r3 + r3^2));

d3 = d2 |>simplify |> factor;
d3 |> println

   -36*r1*r3*(r1 - r3)^6

分子にも sqrt(r1^2 + 14*r1*r3 + r3^2 の項の符号を反転させたものを掛ける

n1 = numerator(r2) * (r1^4 - 12*r1^3*r3 - r1^3*sqrt(r1^2 + 14*r1*r3 + r3^2) + 22*r1^2*r3^2 + r1^2*r3*sqrt(r1^2 + 14*r1*r3 + r3^2) - 12*r1*r3^3 + r1*r3^2*sqrt(r1^2 + 14*r1*r3 + r3^2) + r3^4 - r3^3*sqrt(r1^2 + 14*r1*r3 + r3^2));

n2 = n1 |> expand |> factor
n2 |>  println

   -144*r1^2*r3^2*(r1 - r3)^4*(2*r1 + 2*r3 - sqrt(r1^2 + 14*r1*r3 + r3^2))

res = n2 / d3 |> factor;
res |> println

   4*r1*r3*(2*r1 + 2*r3 - sqrt(r1^2 + 14*r1*r3 + r3^2))/(r1 - r3)^2

式変換が正しく行われたことを確認する

res(r1 => 30, r3 => 10).evalf()

   23.6669234721606

r2(r1 => 30, r3 => 10).evalf()

   23.6669234721606

 

 

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

算額(その136)

2023年02月22日 | Julia

算額(その136)

岐阜県郡上市 郡上八幡神社(小野天満宮)
https://toyo.repo.nii.ac.jp/index.php?action=pages_view_main&active_action=repository_action_common_download&item_id=2533&item_no=1&attribute_id=18&file_no=1&page_id=13&block_id=17

外円の中に,甲円,乙円,丙円,丁円が入っている。乙円,丁円の径がそれぞれ 9寸9分,2寸9分7厘のとき,外円の径はいかほどか。

乙円,丁円の半径をそれぞれ 990,297 とし,図のように記号を定め方程式を解く。

using SymPy

@syms r0, r1, x1::positive, y1::positive, r2::positive, r3, x3::positive, y3::negative, r3::positive, r4, x4, y4;
r3 = 990
r4 = 297
y1 = x1 / sqrt(Sym(3))
y3 = x3*sqrt(Sym(3))
y4 = x4*sqrt(Sym(3))
eq0 = r2 + 2r1 - r0 |> expand
eq1 = x1^2 + y1^2 - (r1 + r2)^2 |> expand
eq2 = x4^2 + y4^2 - (r2 + r4)^2 |> expand
eq3 = x3^2 + y3^2 - (r0 - r3)^2 |> expand
eq4 = x1^2 + y1^2 - (r0 - r1)^2 |> expand
eq5 = (x3 - x1)^2 + (y3 - y1)^2 - (r3 + r1)^2 |> expand
eq6 = (x1 - x4)^2 + (y1 - y4)^2 - (r1 + r4)^2 |> expand;

# res = solve([eq1, eq2, eq3, eq4, eq5, eq6], (r0, r1, x1, r2, x3, x4))

solve() では解が求まらないので,nlsolve() により数値解を求める。

println(eq1, ",")
println(eq2, ",")
println(eq3, ",")
println(eq4, ",")
println(eq5, ",")
println(eq6, ",")

   -r1^2 - 2*r1*r2 - r2^2 + 4*x1^2/3,
   -r2^2 - 594*r2 + 4*x4^2 - 88209,
   -r0^2 + 1980*r0 + 4*x3^2 - 980100,
   -r0^2 + 2*r0*r1 - r1^2 + 4*x1^2/3,
   -r1^2 - 1980*r1 + 4*x1^2/3 - 4*x1*x3 + 4*x3^2 - 980100,
   -r1^2 - 594*r1 + 4*x1^2/3 - 4*x1*x4 + 4*x4^2 - 88209,

using NLsolve

function nls(func, params...; ini = [0.0])
if typeof(ini) <: Number
r = nlsolve((vout, vin) -> vout[1] = func(vin[1], params..., [ini]))#, ftol=1e-14)
v = r.zero[1]
else
r = nlsolve((vout, vin)->vout .= func(vin, params...), ini)#, ftol=1e-14)
v = r.zero
end
return v, r.f_converged
end;

function H(u)
(r0, r1, x1, r2, x3, x4) = u
return [
       -r1^2 - 2*r1*r2 - r2^2 + 4*x1^2/3,
       -r2^2 - 594*r2 + 4*x4^2 - 88209,
       -r0^2 + 1980*r0 + 4*x3^2 - 980100,
       -r0^2 + 2*r0*r1 - r1^2 + 4*x1^2/3,
       -r1^2 - 1980*r1 + 4*x1^2/3 - 4*x1*x3 + 4*x3^2 - 980100,
       -r1^2 - 594*r1 + 4*x1^2/3 - 4*x1*x4 + 4*x4^2 - 88209,    
   ]
end;

iniv = [10000.0, 4000, 6000, 2000, 5000, 1500]
res = nls(H, ini=iniv)
println(res)

   ([10032.79204966505, 3808.477217382768, 5390.414765908734, 2415.8376148995144, 4521.396024832525, 1356.418807449757], true)

外円の半径 = 10032.79204966505
甲円の半径 = 3808.477217382768, x 座標 = 5390.414765908734
乙円の半径 = 2415.8376148995144
丙円の中心の x 座標 = 4521.396024832525
丁円の中心の x 座標 = 1356.418807449757

元の単位でいえば,外円の直径は 100寸3分3厘

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360, lw=0.5, linestyle=:solid)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=lw, linestyle=linestyle)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r0, r1, x1, r2, x3, x4) = res[1]
   r3 = 990
   r4 = 297
   y1 = x1 / sqrt(3)
   y3 = x3 * sqrt(3)
   y4 = x4 * sqrt(3)
   plot()
   circle(0, 0, r0, :black)
   circle(x1, y1, r1, :orange)
   circle(x1, -y1, r1, :orange)
   circle(-x1, y1, r1, :orange)
   circle(-x1, -y1, r1, :orange)
   circle(0, r0 - r1, r1, :orange)
   circle(0, r1 - r0, r1, :orange)
   circle(0, 0, r2, :blue)
   circle(x3, y3, r3, :green)
   circle(x3, -y3, r3, :green)
   circle(-x3, y3, r3, :green)
   circle(-x3, -y3, r3, :green)
   circle(r0 - r3, 0, r3, :green)
   circle(r3 - r0, 0, r3, :green)
   circle(x4, y4, r4)
   circle(x4, -y4, r4)
   circle(-x4, y4, r4)
   circle(-x4, -y4, r4)
   circle(r2 + r4, 0, r4)
   circle(-r2 - r4, 0, r4)
   if more == true
       point(x1, y1, "甲:(x1,y1;r1)", :orange, :center)
       point(0, 0, "乙:(0,0;r2)", :blue, :center)
       point(x3, y3, " 丙:(x3,y3;r3)", :green)
       point(x4, y4, " 丁:(x4,y4;r4)", :red)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

 

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

年々暑くなっている?

2023年02月20日 | 統計学

市井の人:「近頃,夏,暑くなっているよねえ。」

知った風の人:「東京都の夏の平均気温は100年で2.4℃上昇している。」

市井の人,あんた,年齢いくつ?物心ついてから三十年として,0.72 ℃くらいしか上がっていない。あんた,そんなに敏感なの?

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

算額(その135)

2023年02月19日 | Julia

算額(その135)

岐阜県大垣市西外側町 大垣八幡神社 天保年間
http://www.wasan.jp/gifu/ogakihatiman.html

外円に等弧を描き,天円 3 個,地円 1 個,人円 2 個が入っている。天径が与えられたとき,人径を求めよ。

他の問題に準じ,外円の半径を 1 とする。図のように記号を定め方程式を解く。

外円の中心座標と半径    (0, 0), 1
右の天円の中心座標と半径  (x1, y1), r1
地円の中心座標と半径    (0, r2-1), r2
右の人円の中心座標と半径  (x3, y3), r3
円の一部が等弧になる円の半径は外円と同じ 1 とし,中心座標を (√3/3, 1), (-√3/3, 1) とする。
この 2 つの円と外円の中心は,正三角形を構成する(正三角形である必要性はない。中心座標が異なっても,それぞれの円が互いに接することには変わりない)。

using SymPy

@syms x0, y0, r0, x1::positive, y1::positive, r1::positive, r2::positive, x3::positive, y3::negative, r3::positive;

y0 = 1
x0 = y0 / sqrt(Sym(3))
eq1 = x0^2 + (y0 - 1 + r1)^2 - (1 - r1)^2
eq2 = x0^2 + (y0 - r2 + 1)^2 - (1 + r2)^2
eq3 = (x0 - x1)^2 + (y0 - y1)^2 - (1 - r1)^2
eq4 = (x0 - x3)^2 + (y0 - y3)^2 - (1 + r3)^2
eq5 = x3^2 + (y3 - r2 + 1)^2 - (r2 + r3)^2
eq6 = (x1 + x0)^2 + (y0 - y1)^2 - (1 + r1)^2
eq7 = x1^2 + y1^2 - (1 - r1)^2
eq8 = x3^2 + y3^2 - (1 - r3)^2;

res = solve([eq1, eq2, eq4, eq5, eq6, eq7, eq8], (r1, x1, y1, r2, r3, x3, y3))

   1-element Vector{NTuple{7, Sym}}:
    (1/3, sqrt(3)/3, 1/3, 5/9, 5/17 - 5*sqrt(2)/102, 5*sqrt(3)/102 + 55*sqrt(6)/204, 1/34 - 35*sqrt(2)/204)

天円 半径 1/3, 中心 (√3/3, 1/3)
地円 半径 5/9
人円 半径 (60 - 10*√2)/204, 中心 ((10√3 + 55*√6)/204, (6 - 35*√2)/204)

人円の直径は,天円の径の (60 - 10*√2)/68 倍である。

@syms x, y
eq11 = x^2 + y^2 - 1
eq12 = (x - x0)^2 + (y - y0)^2 - 1
res2 = solve([eq11, eq12], (x, y))
(xs, ys) = res2[1]
(xe, ye) = res2[2]
θs = float((asin(ys-y0) * 180 / pi).evalf())
θe = float((asin(ye-y0) * 180 / pi).evalf());

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360, lw=0.5, linestyle=:solid)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=lw, linestyle=linestyle)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r1, x1, y1, r2, r3, x3, y3) = res[1] # [1.949028691169056, 0.6774004450055521, 0.5770838618531914, 0.11011396993484983, 0.8155454510489388, 0.8056721998501019, 0.3178625307754063, 0.1338912989224465]
   r0 = 1
   y0 = 1
   x0 = y0 / sqrt(Sym(3))
   @printf("天円の半径 = %.5f,  地円の半径 = %.5f,  人円の半径 = %.5f\n", r1, r2, r3)
   plot()
   circle(0, 0, 1, :green)
   circle(0, r2 - 1, r2, :blue)
   circle(0, 1 - r1, r1)
   circle(x1, y1, r1)
   circle(-x1, y1, r1)
   circle(x3, y3, r3, :orange)
   circle(-x3, y3, r3, :orange)
   if more == true
       @printf("r1 = %.5f;  x1 = %.5f;  y1 = %.5f\nr2 = %.5f\nr3 = %.5f;  x3 = %.5f;  y3 = %.5f\n\n", r1, x1, y1, r2, r3, x3, y3) 
       #thetas = 180 - round(Int, float(θs))
       #thetae = 360 + round(Int, float(θe))
       circle(x0, y0, r0, :magenta, lw=0.5, linestyle=:dash)
       #thetas = 180 - round(Int, float(θe))
       #thetae = 360 + round(Int, float(θs))
       circle(-x0, y0, r0, :magenta, lw=0.5, linestyle=:dash)
       point(x0, y0, " (x0,y0;1)", :magenta)
       point(-x0, y0, "(-x0,y0;1) ", :magenta, :right)
       point(0, 1 - r1, "天:1-r1 ", :red, :right)
       point(0, r2 - 1, "地:r2-1 ", :blue, :right)
       point(x1, y1, "(x1,y1;r1)", :red, :top)
       point(x3, y3, "人:(x3,y3;r3)", :orange, :top)
       point(0, 0, "", :green)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
   thetas = 180 - round(Int, θs)
   thetae = 360 + round(Int, θe)
   circle(x0, y0, r0, :green, beginangle=thetas, endangle=thetae, lw=0.5)
   thetas = 180 - round(Int, θe)
   thetae = 360 + round(Int, θs)
   circle(-x0, y0, r0, :green, beginangle=thetas, endangle=thetae, lw=0.5)
end;

   天円の半径 = 0.33333,  地円の半径 = 0.55556,  人円の半径 = 0.22479
   r1 = 0.33333;  x1 = 0.57735;  y1 = 0.33333
   r2 = 0.55556
   r3 = 0.22479;  x3 = 0.74531;  y3 = -0.21322

 

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

算額(その134)

2023年02月18日 | Julia

算額(その134)

福島県田村郡三春町上舞木 直毘神社 明治28年(1895)4月
http://www.wasan.jp/fukusima/naobi.html

円の中に甲円,乙円,丙円が入っている。甲円の直径を与えて外円,乙円,丙円の直径を求めよ。

他の場合に準じ,外円の半径を 1 とする。

図のように記号を定め,方程式を立て,解く。
右下にある甲円の中心座標,半径を (x1, y1), r1
右上にある乙円の中心座標,半径を (x2, y2), r2
右下にある丙円の中心座標,半径を (x3, y3), r3

using SymPy

@syms r0::positive, r1::positive, x1::positive, y1::negative, r2::positive, r3::positive

r0 = 1
x2 = 2r2 * cos(PI/6)
y2 = 2r2 * sin(PI/6)
x3 = (1 - r3) * cos(PI/6)
y3 = (r3 - 1) * sin(PI/6)
x1 = (1 - r1) * cos(PI/6)
y1 = (r1 - 1) * sin(PI/6)
eq1 = 2r3 - 1 - r2  # 半径間の関連
eq2 = x1^2 + (1 - r3 - y1)^2 - (r1 + r3)^2  # 甲円と丙円が外接
eq3 = x2^2 + (1 - r3 - y2)^2 - (r3 - r2)^2;  # 乙円が丙円に内接

res = solve([eq2, eq3, eq1], (r1, r2, r3))

   1-element Vector{Tuple{Sym, Sym, Sym}}:
    (1/3, 1/5, 3/5)

外円の径は,甲円の径の 3 倍である。乙円,丙円の径はそれぞれ甲円の径の 0.6 倍,1.8 倍である。

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=0.5)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r1, r2, r3) = res[1]
   r0 = 1
   x2 = 2r2 * cos(PI/6)
   y2 = 2r2 * sin(PI/6)
   x3 = (r0 - r3) * cos(PI/6)
   y3 = (r3 - r0) * sin(PI/6)
   x1 = (r0 - r1) * cos(PI/6)
   y1 = (r1 - r0) * sin(PI/6)
   @printf("外円の半径 = %.3f,  甲円の半径 = %.3f,  乙円の半径 = %.3f,  丙円の半径 = %.3f\n", r0, r1, r2, r3)
   @printf("x2 = %.3f,  y2 = %.3f,  x3 = %.3f,  y3 = %.3f\n", x2, y2, x3, y3)
   plot()
   circle(0, 0, r0, :black)
   circle(0, r0 - r1, r1, :green)
   circle(x1, y1, r1, :green)
   circle(-x1, y1, r1, :green)
   circle(x2, y2, r2, :blue)
   circle(-x2, y2, r2, :blue)
   circle(0, -2r2, r2, :blue)
   circle(0, 0, r2, :blue)
   circle(0, r0 - r3, r3)
   circle(x3, y3, r3)
   circle(-x3, y3, r3)
   if more == true
       point(x2, y2, "乙(x2,y2,r2)")
       point(x1, y1, "甲(x1,y1,r1)", :green, :center)
       point(x3, y3, "丙(x3,y3,r3)", :red)
       point(0, r0 - r3, "r0-r3 ", :red, :right)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

   外円の半径 = 1.000,  甲円の半径 = 0.333,  乙円の半径 = 0.200,  丙円の半径 = 0.600
   x2 = 0.346,  y2 = 0.200,  x3 = 0.346,  y3 = -0.200

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

算額(その133)

2023年02月14日 | Julia

算額(その133)

岐阜県大垣市西外側町 大垣八幡神社 天保年間
http://www.wasan.jp/gifu/ogakihatiman.html

圭の中に甲円,乙円,丙円があり,甲円と乙円と別の丙円が外円の中にある。それぞれの円の径を求めよ。

圭とは二等辺三角形である。最初正三角形だと勝手に解釈して解を求めようとしたが,求まらなかった。算額の問を読み返して,「圭」であることがわかった。

底辺の長さを 2 とする
圭の高さを y とする
図のように,記号を定め,方程式を解く
外円の中心座標と半径    (0, r0), r0
甲円の中心座標と半径       (0, 2r2+r1), r1
乙円の中心座標と半径       (0, r2), r2
右上の丙円の中心座標と半径  (x3, y3), r3
右下の丙円の中心座標と半径  (x4, r3), r3

using SymPy

function distance(x1, y1, x2, y2, x0, y0)
   p1, p2 = sympy.Point(x1, y1), sympy.Point(x2, y2)
   l = sympy.Line(p1, p2)
   l.distance(sympy.Point(x0, y0))^2  # 二乗距離を返す!!
end;

@syms y::positive, r0::positive, r1::positive, r2::positive, r3::positive, x3::positive, y3::positive, x4::positive;

eq1 = r2*(1 - x4) - r3  # r2 と r3 の比
eq2 = r1/r2 - (y - 2r2 - r1)/(y - r2)
eq3 = distance(1, 0, 0, y, x3, y3) - r3^2
eq4 = x3^2 + (y3 - r0)^2 - (r0 - r3)^2  # 外丙1
eq5 = x4^2 + (r0 - r3)^2 - (r0 + r3)^2  # 外丙2
eq6 = r1 + r2 - r0  # 外円の半径
eq7 = (y - r2)^2 - r2^2 * (y^2 + 1)  # r2 と底辺の比
eq8 = r2*(sqrt(y^2 + 1) + 1) - y;  # 面積

# res = solve([eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8], (r0, r1, r3, x3, y3, x4, y, r2))

nlsolve() で解を求める。

println(simplify(eq1), ",")
println(simplify(eq2), ",")
println(simplify(eq3), ",")
println(simplify(eq4), ",")
println(simplify(eq5), ",")
println(simplify(eq6), ",")
println(simplify(eq7), ",")
println(simplify(eq8), ",")

   -r2*x4 + r2 - r3,
   (r1*y + 2*r2^2 - r2*y)/(r2*(-r2 + y)),
   (-r3^2*y^2 - r3^2 + x3^2*y^2 - 2*x3*y^2 + 2*x3*y*y3 + y^2 - 2*y*y3 + y3^2)/(y^2 + 1),
   x3^2 - (r0 - r3)^2 + (r0 - y3)^2,
   -4*r0*r3 + x4^2,
   -r0 + r1 + r2,
   y*(-r2^2*y - 2*r2 + y),
   r2*(sqrt(y^2 + 1) + 1) - y,

using NLsolve

function nls(func, params...; ini = [0.0])
if typeof(ini) <: Number
r = nlsolve((vout, vin) -> vout[1] = func(vin[1], params..., [ini]), ftol=1e-14)
v = r.zero[1]
else
r = nlsolve((vout, vin)->vout .= func(vin, params...), ini, ftol=1e-14)
v = r.zero
end
return v, r.f_converged
end;

function H(u)
(r0, r1, r3, x3, y3, x4, y, r2) = u
return [
   -r2*x4 + r2 - r3,
   (r1*y + 2*r2^2 - r2*y)/(r2*(-r2 + y)),
   (-r3^2*y^2 - r3^2 + x3^2*y^2 - 2*x3*y^2 + 2*x3*y*y3 + y^2 - 2*y*y3 + y3^2)/(y^2 + 1),
   x3^2 - (r0 - r3)^2 + (r0 - y3)^2,
   -4*r0*r3 + x4^2,
   -r0 + r1 + r2,
   y*(-r2^2*y - 2*r2 + y),
   r2*(sqrt(y^2 + 1) + 1) - y,
   ]
end;

iniv = [0.8, 0.3, 0.16, 0.55, 1.11, 0.72, 1.81, 0.62]
res = nls(H, ini=iniv)
println(res)

([0.8304913036228202, 0.2235659941776492, 0.16186914316948992, 0.619774964637473,
1.0813589712444132, 0.7332964359033489, 1.921739300833543, 0.606925309445171], true)
   外円の半径 = 0.830,  甲円の半径 = 0.224,  乙円の半径 = 0.607,  丙円の半径 = 0.162
   圭の高さ = 1.922,  x3 = 0.620,  y3 = 1.081,  x4 = 0.733
 

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=0.5)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r0, r1, r3, x3, y3, x4, y, r2) = res[1]
   @printf("外円の半径 = %.3f,  甲円の半径 = %.3f,  乙円の半径 = %.3f,  丙円の半径 = %.3f\n", r0, r1, r2, r3)
   @printf("圭の高さ = %.3f,  x3 = %.3f,  y3 = %.3f,  x4 = %.3f\n", y, x3, y3, x4)
   plot([1, 0, -1, 1], [0, y, 0, 0], color=:black, lw=0.5)
   circle(0, r2, r2)
   circle(0, r0, r0, :green)
   circle(0, 2r2+r1, r1, :blue)
   circle(x4, r3, r3, :magenta)
   circle(-x4, r3, r3, :magenta)
   circle(x3, y3, r3, :magenta)
   circle(-x3, y3, r3, :magenta)
   if more == true
       point(0, y, " y", :black, :left, :bottom)
       point(0, r0, "外:(0,r0,r0)", :green)
       point(0, 2r2+r1, "甲:(0,2r2+r1,r1)", :blue, :center, :top)
       point(0, r2, "乙:(0,r2,r2)", :red)
       point(x3, y3, "丙1:(x3,y3,r3)", :magenta, :center, :top)
       point(x4, r3, "丙2:(x4,r3,r3)", :magenta, :center, :top)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

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

算額(その132)

2023年02月14日 | Julia

算額(その132)

岐阜県大垣市西外側町 大垣八幡神社 天保年間
http://www.wasan.jp/gifu/ogakihatiman.html

外円の中に 2 個の甲円,1 個の乙円と 4 個の丙円が入っている。両脇の半円の直径は 2 つの甲円の中心間の距離に等しい。甲円,乙円,丙円の径を求めよ。

外円,甲円,乙円,丙円の半径をそれぞれ 1,r1, r2, r4 として,方程式を解く。

using SymPy

@syms r1::positive, r2::positive, r4::positive, x4::positive, y4::positive;

eq1 = (r1 + 2r2)^2 + (r1 + r2)^2 - (2r1 + r2)^2  # 甲円と半円が接する
eq2 = 2r1 + r2 - 1  # 外円の半径との関係
eq3 = x4^2 + (1 - r1 - y4)^2 - (r1 + r4)^2;  # 甲円と丙円が接する
eq4 = (r1 + 2r2 - x4)^2 + y4^2 - (r4 + r1 + r2)^2  # 半円と丙円が接する
eq5 = x4^2 + y4^2 - (r2 + r4)^2;  # 乙円と丙円が接する

res = solve([eq1, eq2, eq3, eq4, eq5], (r1, r2, r4, x4, y4))

   1-element Vector{NTuple{5, Sym}}:
    (2/5, 1/5, 6/115, 4/23, 21/115)

算額では「乙円の径を知って丙円の径を求めよ」とある。乙円の径を a とすれば,丙円の径は 6/115 × 5a = 6a / 23 である。

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=0.5)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r1, r2, r4, x4, y4) = float.(res[1])
   @printf("甲円の半径 = %.5f,  乙円の半径 = %.5f,  丙円の半径 = %.5f\n", r1, r2, r4)
   @printf("丙円の中心座標 = (%.5f, %.5f)\n", x4, y4)
   plot()
   θ = asin((r1 + r2) / (2r1 + r2))*180.0/pi
   (ba, ea) = round.(Int, [θ, 180 - θ])
   circle(0, 0, 1, :black, beginangle=ba, endangle=ea)
   circle(0, 0, 1, :black, beginangle=180+ba, endangle=180+ea)
   circle(0, 1 - r1, r1)
   circle(0, r1 - 1, r1)
   circle(0, 0, r2, :blue)
   circle(x4, y4, r4, :orange)
   circle(x4, -y4, r4, :orange)
   circle(-x4, y4, r4, :orange)
   circle(-x4, -y4, r4, :orange)
   circle(r1 + 2r2, 0, r1 + r2, :green, beginangle=90, endangle=270)
   circle(-r1 - 2r2, 0, r1 + r2, :green, beginangle=270, endangle=450)
   if more == true
       point(0, 1-r1, "甲:(0,1-r1) ", :red, :right)
       point(0, 0, "乙:(0,0,r2) ", :blue, :right)
       point(r1 + r2, 0, "(r1+2r2,0,r1+r2)", :green, :center, :bottom)
       point(x4, y4, "  (x4,y4,r4)", :orange, :left)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

   甲円の半径 = 0.40000,  乙円の半径 = 0.20000,  丙円の半径 = 0.05217
   右上の丙円の中心座標 = (0.17391, 0.18261)

 

 

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

算額(その131)

2023年02月13日 | Julia

算額(その131)

新潟県長岡市与板町本与板 与板八幡宮 文化5年(1808)
http://www.wasan.jp/niigata/yoitahatiman3.html

短辺(平)の長さが 595 寸の長方形の中に,甲円,乙円,丙円,丁円,戊円が入っている。甲円の径はいかほどか。

長辺(長)の長さを w, 甲円,乙円,丙円,丁円,戊円の半径を r1, r2, r3, r4, r5,戊円の中心の x 座標を x5 として以下のように記号を定め,方程式を立てて,解く。

using SymPy

@syms r1::positive, r2::positive, r3::positive, r4::positive, r5::positive, x5::positive, w::positive;

eq1 = (w - r1 - r2)^2 + (595 - r1 - r2)^2 - (r1 + r2)^2
eq2 = (w - r1 - r3)^2 + (r1 - r3)^2 - (r1 + r3)^2
eq3 = (r4 - r1)^2 + (595 - r1 - r4)^2 - (r1 + r4)^2
eq4 = (w - r1 - x5)^2 + (595 - r1 - r5)^2 - (r1 + r5)^2
eq5 = (r2 - r3)^2 + (r2 - 595 + r3)^2 - (r2 + r3)^2
eq6 = (r2 - x5)^2 + (r2 - r5)^2 - (r2 + r5)^2
eq7 = (x5 - w + r4)^2 + (r4 - r5)^2 - (r4 + r5)^2;

# res = solve([eq1, eq2, eq3, eq4, eq5, eq6, eq7], (r1, r2, r3, r4, r5, x5, w))

これも solve() では解けないので,nlsolve() で解く。

println(eq1, ",")
println(eq2, ",")
println(eq3, ",")
println(eq4, ",")
println(eq5, ",")
println(eq6, ",")
println(eq7, ",")


   -(r1 + r2)^2 + (-r1 - r2 + 595)^2 + (-r1 - r2 + w)^2,
   (r1 - r3)^2 - (r1 + r3)^2 + (-r1 - r3 + w)^2,
   (-r1 + r4)^2 - (r1 + r4)^2 + (-r1 - r4 + 595)^2,
   -(r1 + r5)^2 + (-r1 - r5 + 595)^2 + (-r1 + w - x5)^2,
   (r2 - r3)^2 - (r2 + r3)^2 + (r2 + r3 - 595)^2,
   (r2 - r5)^2 - (r2 + r5)^2 + (r2 - x5)^2,
   (r4 - r5)^2 - (r4 + r5)^2 + (r4 - w + x5)^2,

using NLsolve

function nls(func, params...; ini = [0.0])
if typeof(ini) <: Number
r = nlsolve((vout, vin) -> vout[1] = func(vin[1], params..., [ini]), ftol=1e-14)
v = r.zero[1]
else
r = nlsolve((vout, vin)->vout .= func(vin, params...), ini, ftol=1e-14)
v = r.zero
end
return v, r.f_converged
end;

function H(u)
(r1, r2, r3, r4, r5, x5, w) = u
return [
   -(r1 + r2)^2 + (-r1 - r2 + 595)^2 + (-r1 - r2 + w)^2,
   (r1 - r3)^2 - (r1 + r3)^2 + (-r1 - r3 + w)^2,
   (-r1 + r4)^2 - (r1 + r4)^2 + (-r1 - r4 + 595)^2,
   -(r1 + r5)^2 + (-r1 - r5 + 595)^2 + (-r1 + w - x5)^2,
   (r2 - r3)^2 - (r2 + r3)^2 + (r2 + r3 - 595)^2,
   (r2 - r5)^2 - (r2 + r5)^2 + (r2 - x5)^2,
   (r4 - r5)^2 - (r4 + r5)^2 + (r4 - w + x5)^2,
   ]
end;

iniv = [200.0, 165, 135, 95, 90, 400, 700]

res = nls(H, ini=iniv)
println(res)

   ([213.00034502265584, 164.1726947717987, 134.08788967981687, 96.00257736188509, 88.286549252726, 404.9567532384933, 685.0868546118494], false)

甲円の半径 = 213.000,  乙円の半径 = 164.173,  丙円の半径 = 134.088,  丁円の半径 = 96.003,  戊円の半径 = 88.287
長 = 685.087,  x = 404.957
となるので,算額の問である「甲円の径]は 213*2 = 426寸である。

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=0.5)
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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r1, r2, r3, r4, r5, x5, w) = res[1]
   @printf("甲円の半径 = %.3f,  乙円の半径 = %.3f,  丙円の半径 = %.3f,  丁円の半径 = %.3f,  戊円の半径 = %.3f\n", r1, r2, r3, r4, r5)
   @printf("長 = %.3f,  x = %.3f\n", w, x5)
   plot([0, w, w, 0, 0], [0, 0, 595, 595, 0])
   circle(w - r1, 595 - r1, r1)
   circle(r2, r2, r2)
   circle(r3, 595 - r3, r3)
   circle(w - r4, r4, r4)
   circle(x5, r5, r5)
   if more == true
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

   甲円の半径 = 213.000,  乙円の半径 = 164.173,  丙円の半径 = 134.088,  丁円の半径 = 96.003,  戊円の半径 = 88.287
   長 = 685.087,  x = 404.957

 

 

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

算額(その130)

2023年02月13日 | Julia

算額(その130)

算額(その51)と上下反転しているが同じである。51では未知数を絞り,代数解を求めている。

群馬県桐生市梅田町 日枝神社 明治12年(1879)10月
http://www.wasan.jp/gunma/hieda.html

円内に4種類の円が入っている。甲円の径が与えられたとき,外円の径を求めよ。

外円の半径を 1 とし,図形が点対称なので -30度〜90度の範囲に限定する。また以下のように記号を定め,方程式を立てて,解く。
甲円の中心座標,半径 0, 1-r1, r1
乙円の中心座標,半径 x2, y2, r2
丙円の中心座標,半径 x3, y3, r3
丁円の中心座標,半径 0, 0, r4

using SymPy

@syms r1::positive, x2::positive, y2::positive, r2::positive, x3::positive, y3::positive, r3::positive, r4::positive;

eq1 = x2^2 + (1 - r1 - y2)^2 - (r1 + r2)^2  # 甲乙
eq2 = x3^2 + (1 - r1 - y3)^2 - (r1 + r3)^2  # 甲丙
eq3 = (x2 - x3)^2 + (y2 - y3)^2 - (r2 + r3)^2  # 乙丙
eq4 = x3^2 + y3^2 - (r3 + r4)^2  # 丙丁
eq5 = x2^2 + y2^2 - ( 1 - r2)^2  # 外乙 (内接)
eq6 = r4 + 2r1 - 1  # 半径の関係
eq7 = r4 + 2r3 + 2r2 - 1  # 半径の関係
eq8 = y3/x3 - y2/x2;  # 乙円,丙円,丁円の中心が一直線上にある

# res = solve([eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8], (r1, x2, y2, r2, x3, y3, r3, r4))

solve() では解けないので,nlsolve() を用いる。

using NLsolve

function nls(func, params...; ini = [0.0])
if typeof(ini) <: Number
r = nlsolve((vout, vin) -> vout[1] = func(vin[1], params..., [ini]), ftol=1e-14)
v = r.zero[1]
else
r = nlsolve((vout, vin)->vout .= func(vin, params...), ini, ftol=1e-14)
v = r.zero
end
return v, r.f_converged
end;

function H(u)
(r1, x2, y2, r2, x3, y3, r3, r4) = u
return [
   x2^2 - (r1 + r2)^2 + (-r1 - y2 + 1)^2,
   x3^2 - (r1 + r3)^2 + (-r1 - y3 + 1)^2,
   -(r2 + r3)^2 + (x2 - x3)^2 + (y2 - y3)^2,
   x3^2 + y3^2 - (r3 + r4)^2,
   x2^2 + y2^2 - (1 - r2)^2,
   2*r1 + r4 - 1,
   2*r2 + 2*r3 + r4 - 1,
   y3/x3 - y2/x2,    
   ]
end;

iniv = [0.40, 0.6, 0.36, 0.27, 0.28, 0.16, 0.12, 0.20]

res = nls(H, ini=iniv)
println(res)

   ([0.39728455784707767, 0.6275824608249739, 0.36622451524418415, 0.27337758037549836, 0.28444851157211404, 0.16598937154089602, 0.12390697747157697, 0.20543088430584824], true)

外円の径は,甲円の径の 1/0.39728455784707767 ≒ 2.5 倍である(正確には 1/(-7/9 + 4*sqrt(7)/9) = 2.511857892036909)。

using Plots
using Printf

function circle(ox, oy, r, color=:red; beginangle=0, endangle=360)
   θ = beginangle:0.1:endangle
   x = r.*cosd.(θ)
   y = r.*sind.(θ)
   plot!(ox .+ x, oy .+ y, color=color, linewidth=0.5)
end;

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, color=color, linewidth=0.5, seriestype=:shape, fillcolor=color)
  else
      plot!(ox .+ x, oy .+ y, color=color, linewidth=0.5)
  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 draw(more)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r1, x2, y2, r2, x3, y3, r3, r4) = res[1]
   @printf("甲円の半径 = %.3f,  乙円の半径 = %.3f,  丙円の半径 = %.3f, 丁円の半径 = %.3f\n", r1, r2, r3, r4)
   plot()
   circle(0, 0, 1, :black)
   circle(0, 1 - r1, r1)
   circle((1 - r1)√3/2, -(1 - r1)/2, r1)
   circle(-(1 - r1)√3/2, -(1 - r1)/2, r1)
   circle(x2, y2, r2, :blue)
   circle(-x2, y2, r2, :blue)
   circle(0, r2 - 1, r2, :blue)
   circle(x3, y3, r3, :green)
   circle(-x3, y3, r3, :green)
   circle(0, -r4 - r3, r3, :green)
   circle(0, 0, r4)
   if more == true
       point(0, 1-r1, "甲:(0,1-r1,r1)", :red)
       point(x2, y2, "乙:(x2,y2,r2)", :blue)
       point(x3, y3, "丙:(x3,y3,r3)", :green, :left, :bottom)
       point(0, 0, "丁:(0,0,r4)", :green, :left, :bottom)
       hline!([0], color=:black, lw=0.5)
       vline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

   甲円の半径 = 0.397,  乙円の半径 = 0.273,  丙円の半径 = 0.124, 丁円の半径 = 0.205

 

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

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

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