算額(その612)
高山忠直編: 算法評論
国立国会図書館 デジタルコレクション
https://dl.ndl.go.jp/pid/3508431/1/9
鈎股弦(直角三角形)内に長方形と中鈎(直角の頂点とから斜辺におろした垂線)と 2 個の等円を入れる。長方形の長辺と短辺が 40 寸,20 寸であるとき,等円の直径を求めよ。
長方形の長辺と短辺を「長」,「平」
直角三角形の直角を挟む二辺を「鈎」,「股」
中鈎と斜辺の交点座標を (x2, y2)
中鉤と長方形の長辺の交点座標を (x, 20)
等円の半径と中心座標を r, (r, a), (b, 20 + r)
とおき,以下の連立方程式を解き,r, x, 鈎, 股, x2, y2 を求める。
なお,等円の半径 r を求めるだけであれば,eq1, eq2 のみの二元連立方程式を解くだけでよい。
include("julia-source.txt");
using SymPy
@syms 長::positive, 平::positive,
鈎::positive, 股::positive, x::positive, y::positive, r::positive,
x2::positive, y2::positive, a::positive, b::positive
eq1 = sqrt(x^2 + 平^2) - (長 - x)
eq2 = 平 + x - sqrt(x^2 + 平^2) - 2r
eq3 = x/平 - 鈎/股
eq4 = 長*平 + 長*(鈎 - 平)/2 + 平*(股 - 長)/2 - 鈎*股/2
eq5 = x2^2 + y2^2 + (鈎 -y2)^2 + x2^2 - 鈎^2
eq6 = x2^2 + y2^2 + (股 - x2)^2 + y2^2 - 股^2;
res = solve([eq1, eq2, eq3, eq4, eq5, eq6], (r, x, 鈎, 股, x2, y2))
1-element Vector{NTuple{6, Sym}}:
((-平^2 + 長*(2*平 + 長) - sqrt(4*平^2*長^2 + (平^2 - 長^2)^2))/(4*長), (-平^2 + 長^2)/(2*長), (平^2 + 長^2)/(2*平), -長*(平^2 + 長^2)/(平^2 - 長^2), 長*(-平^2 + 長^2)/(平^2 + 長^2), 2*平*長^2/(平^2 + 長^2))
長,平が 40, 20 のとき,等円の半径は 5 である。
半径 = (-平^2 + 長*(2*平 + 長) - sqrt(4*平^2*長^2 + (平^2 - 長^2)^2))/(4*長)
半径(長 => 40, 平 => 20)
5
半径の式中の sqrt の中は平方になるので sqrt を剥ぎ取ることができる。
sqrt(4*平^2*長^2 + (平^2 - 長^2)^2) |> factor |> println
平^2 + 長^2
2倍して直径を求める式を得る。
2(-平^2 + 長*(2*平 + 長) - (平^2 + 長^2))/(4*長) |> simplify |> println
平*(-平 + 長)/長
カッコの中を「長」で割ると,平*(1 - 平/長) となり,術の「平以長除之得數以減一個余剰平得等径合問」に一致する。
長,平が 40, 20 のとき,等円の直径は 10 である。
直径 = 平*(1 - 平/長)
直径(長 => 40, 平 => 20)
10
「平」と「長」を未知数のままにしておいても構わないが,煩雑なので数値解を求めると,
(r, x, 鈎, 股, x2, y2) = (5, 15, 50, 200/3, 24, 32)
となる。このパラメータを既知として,更に図を描くために,等円の中心座標 (r, a), (b, 20 + r) の a, b を求める。
@syms 鈎::positive, 股::positive, x::positive, y::positive, r::positive,
x2::positive, y2::positive, a::positive, b::positive
(r, x, 鈎, 股, x2, y2) = (5, 15, 50, 200/3, 24, 32)
eq7 = distance(0, 0, x2, y2, r, a) - r^2
eq8 = distance(0, 0, x2, y2, b, 20 + r) - r^2
solve([eq7, eq8], (a, b))
2-element Vector{Tuple{Sym, Sym}}:
(15, 25/2)
(15, 25)
2 番目のものが適解である。すなわち等円の中心座標は (5, 15), (25, 25) である
function draw(more=false)
pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
(r, x, 鈎, 股, x2, y2) = (5, 15, 50, 200/3, 24, 32)
(a, b) = (15, 25)
@printf("等円の直径 = %g; r = %g; x = %g; 鈎 = %g; 股 = %g; x2 = %g; y2 = %g; a = %g; b = %g\n",
2r, r, x, 鈎, 股, x2, y2, a, b)
plot([0, 股, 0, 0], [0, 0, 鈎, 0], color=:black, lw=0.5)
rect(0, 0, 40, 20, :blue)
segment(0, 0, x2, y2, :green)
circle(r, a, r)
circle(b, 20 + r, r)
if more
delta = (fontheight = (ylims()[2]- ylims()[1]) / 500 * 10 * 2) /3 # size[2] * fontsize * 2
hline!([0], color=:black, lw=0.5)
vline!([0], color=:black, lw=0.5)
point(x, 20, "(x,20)", :black)
point(x2, y2, " (x2,y2)", :black, :left, :vcenter)
point(股, 0, "股", :black, :left, :bottom, delta=delta/2)
point(0, 鈎, " 鈎", :black, :left, :bottom, delta=delta/2)
point(r, a, "(r,a)", :red, :center, delta=-delta/2)
point(b, 20 + r, "(b,20+r)", :red, :center, delta=-delta/2)
end
end;