高校入試平面図形 相似「2024神奈川県の平面図形の難問」をsympyとFreeCADとChatGPTでやってみたい。

　以下長文です。サラサラっと。
# 最初に
**・ver0.3 (私の別々解)こちらも基本のような気がします。試験時間内は厳しいです。** 　
・**私の解答の方法は、中学生の学習指導要領の範囲外を含みます。** 
・私はできなかかった方法も、そのまま表示しています。

**パイソニスタの方へ**
・(参考図なしで、)平面図形の問題が成り立つなら、ChatGPTへGO。
　出題者も、点検されているかも。
・ChatGPT-3.5先生の、どこが間違っているのかわかりませんでした。ページ最後です。
　**アキラメマシタ。** アドバイスいただけると幸いです。
・今後、以下のような書き方をしないよう気をつけます。

# オリジナル
### PDF
**＜令和６年度神奈川県公立高校入試＞ 数学 問３（ウ）**
https://www.toshin.com/koukou_nyushi/files/2024/sugaku_q/kanagawa_sugaku_q.pdf#page=6
＜2024年全国公立高校入試解答速報｜大学受験の予備校・塾 東進
https://www.toshin.com/koukou_nyushi/

# youtube
#### 大ヒーント
三角形オールスター?
数学を数楽に 様より抜粋 
＞直角二等三角形
＞補助線をひっぱりたくなりませんか。
＞注目して...
＞こことここの比は...等しいです。
＞台形の高さに注目しました。平行ですから...
＞知っていれば...`
＞公立の入試の難しさ
＞私立の入試の難しさ


####  数学を数楽に 様
youtube (14:21) 

https://youtu.be/TqOnJX1oUoI

# sympyで(オリジナル 様の方法で) 本解、別解
・ver0.1　(本解) オリジナル様の「角度に注目して」 45°,補助線２本
・なるべく? Triangleの座標を使わないようしたつもりです。Triangleのkeywordのsssです。
・5個の三角形をイメージして下さい。
　△ABC,△BEC正三角形,△CEF,△AEF,△BE*の直角二等辺三角形
```python
# ver0.1  
from sympy import *
var('DE,HC',real=True,positive=True)
AB=24;BC=12
CA=sqrt(AB**2-BC**2)
CE=BC

trABC=Triangle(sss=(AB,BC   ,CA))
trDBC=Triangle(sss=(12,12   ,12))
trDCE=Triangle(sas=(12,90-60,12))
BCD=list(trDBC.angles.values())[0]             ;print("# ∠BCD=",BCD)
DCA=pi/2-BCD                                   ;print("# ∠DCA=",DCA)
# 
trDCG=Triangle(sss=(12,DE/2 ,HC))
trECG=Triangle(sss=(CE,DE/2 ,HC))              ;print("# △DCG≡△ECG",trDCG==trECG)
DEC=(pi-DCA)/2                                 ;print("# ∠DEC=",DEC)
BAC=list(trABC.angles.values())[1]             ;print("# ∠BAC=",BAC)
ADE=DEC-BAC                                    ;print("# ∠ADE=",ADE)
print()
BDI=pi-pi/2-ADE                                ;print("# ∠BDI=",BDI)
IBD=pi-pi/2-BDI                                ;print("# ∠IBD=",IBD)
BD =AB/2
trBDI=Triangle(asa=(BDI*180/pi,BD,IBD*180/pi)) ;print("#    GH=",trBDI.vertices[0].distance(trBDI.vertices[2]).simplify().simplify())
# ∠BCD= pi/3
# ∠DCA= pi/6
# △DCG≡△ECG True
# ∠DEC= 5*pi/12
# ∠BAC= pi/6
# ∠ADE= pi/4

# ∠BDI= pi/4
# ∠IBD= pi/4
#    GH= 6*sqrt(2)
```
・ver0.2 (別解) オリジナル様の「準有名角」
　△ECFの30°,75°,75°をイメージして下さい。sasの角度の単位は、degreeです。
```python
# ver0.2
from sympy import *
var('DE,HC,GH',real=True,positive=True)
AB=24;BC=12
CA=sqrt(AB**2-BC**2)
CE=BC
# 
trABC=Triangle(sss=(AB,BC   ,CA))
trDBC=Triangle(sss=(12,12   ,12))
trDCE=Triangle(sas=(12,90-60,12))
BCD=list(trDBC.angles.values())[0]             ;print("# ∠BCD=",BCD)
DCA=pi/2-BCD                                   ;print("# ∠DCA=",DCA)
# 
trDCG=Triangle(sss=(12,DE/2 ,HC))
trECG=Triangle(sss=(CE,DE/2 ,HC))              ;print("# △DCG≡△ECG",trDCG==trECG)
ECG  =pi-pi/2-(pi-DCA)/2                       ;print("# ∠ECG=",ECG,float(ECG*180/pi))
GC   =CE*cos(ECG)                              ;print("#    GC=",GC)
AE   =CA-BC
EF   =AE
CF   =CA-AE-EF
GH   =solve(  Eq( CE/EF,GC/GH),GH)[0]          ;print("#    GH=",GH)
# ∠BCD= pi/3
# ∠DCA= pi/6
# △DCG≡△ECG True
# ∠ECG= pi/12 15.0
#    GC= 3*sqrt(2) + 3*sqrt(6)
#    GH= 6*sqrt(2)
```

# ver0.3 (私の別々解)sympyで(三平方の定理で) 
**・ver0.3 (私の別々解)こちらも基本のような気がします。試験時間内は厳しいです。** 　
・「三平方の定理2回と、相似の組み合わせ」でした。
　オリジナル様のコメントにあったかも。他サイトを探しています。 
・ Rational(1,2)は1/2,.simplify()は簡略化の意味です。
・△FG*と△HD＊の相似です。Fからの離れ、Dからの離れ。
```python
# ver0.３
from sympy import *
AB=24  ;BC=12 ;CA=sqrt(AB**2-BC**2) 
dx=BC*Rational(1,2)        ;dy=CA*Rational(1,2)               #;print("# D ",dx,",",dy)
ex=BC                      ;ey=BC                             #;print("# E ",ex,",",ey)
fx=BC                      ;fy=CA-(CA-BC)*2                   #;print("# F ",fx,",",fy)
gx=(dx+ex)*Rational(1,2)   ;gy=(dy+ey)*Rational(1,2)          #;print("# G ",gx,",",gy)
hx=fx-(ex-gx)*fy/ey        ;hy=(fy-(ey-gy)*fy/ey).simplify()  #;print("# H ",hx,",",hy,float(hy))
GH=sqrt((gx-hx)**2+(gy-hy)**2).simplify()                      ;print("# GH",GH)
# GH 6*sqrt(2)
```
# sympyで(以下、いつもの方法で)
・ver0.4　「面積で」
　youtubeオリジナル様内に、私のコメントがあります。
・△AEFの面積から、高さの計算です。
```python
# ver0.4
from sympy import *
h=6*(12*sqrt(3)-12) / sqrt(6**2+(12-12*sqrt(3)/2)**2)
print("#",h,float(h))
print("#",sqrtdenest(h).simplify())
# (-72 + 72*sqrt(3))/sqrt((12 - 6*sqrt(3))**2 + 36) 8.48528137423857
# 6*sqrt(2)
```
・ver0.5 「相似are_similar関数とsolve関数の組み合わせは、できませんでした。 」
```python
# # ver0.5  「are_similarで、できませんでした。」
# from sympy import *
# var('CF',real=True,positive=True)
# AB=24;BC=12
# B,C,A=map(Point,[(0,0),(BC,0),(BC,sqrt(AB**2-BC**2))])
# D=A.midpoint(B)
# E=Point(BC,BC)
# F=Point(BC,CF)
# # 
# sol=solve   (Eq(are_similar(Triangle(A,D,E),Triangle(A,B,F))                            ,True),CF)                 ;print("# ",sol)
# sol=solveset(Eq(are_similar(Triangle(A,D,E),Triangle(A,B,F))                            ,True),CF,Interval(0,BC))  ;print("# ",sol)
# sol=solve   (Eq(are_similar(Triangle( sss=(A.distance(D),D.distance(E),E.distance(A) )),
#                             Triangle( sss=(A.distance(B),B.distance(F),F.distance(A) ))),True),CF)                 ;print("# ",sol)
# sol=solveset(Eq(are_similar(Triangle( sss=(A.distance(D),D.distance(E),E.distance(A) )),
#                             Triangle( sss=(A.distance(B),B.distance(F),F.distance(A) ))),True),CF,Interval(0,BC))  ;print("# ",sol)
# print()
```
・ver0.6　「ベクトルの成分表示」 **これが一番わかりやすいです。** 
　solve関数を使っているのが見えないので。
・媒介変数✕単位ベクトル でもいいですが、そこまでしなくても。
　２点を通る２直線同士の交点計算。これは、そのまま作図に使えます。
```python
# ver0.6
from sympy import *
AB=24;BC=12
B,C,A=map(Point,[(0,0),(BC,0),(BC,sqrt(AB**2-BC**2))])
D=A.midpoint(B)
CE=BC 
E=Point(C.x,CE)                                 # ;print("# E ",E)
G=D.midpoint(E)                                 # ;print("# G ",G)
H=Line(B,B+(E-D)).intersection(Line(C,G))[0]    # ;print("# H ",H)  
print("# ",G.distance(H).simplify())
#  6*sqrt(2)
```
・ver0.7　「問題文の最初に、値の設定がない。」
・問題文の最終行で「AB=24cm,BC=12cmのとき、...」出題者の趣旨。
　出題者は、mathematicaまたはAIで、確認、点検されてますでしょうか？
・sympyの良さでしょうか？後半にsubs？
```python
# ver0.7
from sympy import *
# AB=24;BC=12
var('AB,BC',real=True,positive=True)
B,C,A=map(Point,[(0,0),(BC,0),(BC,sqrt(AB**2-BC**2))])
D=A.midpoint(B)
CE=BC 
E=Point(C.x,CE)                                 # ;print("# E ",E)
G=D.midpoint(E)                                 # ;print("# G ",G)
H=Line(B,B+(E-D)).intersection(Line(C,G))[0]    # ;print("# H ",H)  
print("# ",G.distance(H).simplify())
rep={AB:24,BC:12}           
print("# ",G.distance(H).simplify().subs(rep))
print("# ",G.distance(H).subs(rep).simplify())
#  sqrt(BC**2*(BC - sqrt(AB**2 - BC**2))**2 + (AB**2 - 3*BC**2 + BC*sqrt(AB**2 - BC**2))**2)/(4*BC)
#  sqrt(144*(12 - 12*sqrt(3))**2 + (144 + 144*sqrt(3))**2)/48
#  6*sqrt(2)
A=A.subs(rep).simplify()
B=B.subs(rep).simplify()
C=C.subs(rep).simplify()
D=D.subs(rep).simplify()
E=E.subs(rep).simplify()
F=F.subs(rep).simplify()
G=G.subs(rep).simplify()
H=H.subs(rep).simplify()
```
・ver0.8　expr 参照あり
```python
# ver0.8
from sympy import *
# AB=24;BC=12
var('AB,BC',real=True,positive=True)
B,C,A=map(Point,[(0,0),(BC,0),(BC,sqrt(AB**2-BC**2))])
D=A.midpoint(B)
CE=BC 
E=Point(C.x,CE)                                 # ;print("# E ",E)
G=D.midpoint(E)                                 # ;print("# G ",G)
H=Line(B,B+(E-D)).intersection(Line(C,G))[0]    # ;print("# H ",H)  
# 
F=Line(B,B+(E-D)).intersection(Line(C,A))[0]    # ;print("# F ",F)  
rep={AB:24,BC:12}
A, B, C, D, E, F, G, H = [expr.subs(rep).simplify() for expr in [A, B, C, D, E, F, G, H]]
print("# ",G.distance(H).simplify())
#  6*sqrt(2)
```


# FreeCADのマクロで作図
・作図にGが抜けていました。申し訳ありません。
・計算部分は、ver0.6をコピー貼り付けです。
・ver0.6で、Fの座標計算が不要でした。作図のためFの座標計算を追加しました。
```python
import FreeCAD
import Part
import DraftTools
import Draft
import Mesh
############################################################################
# 計算
# ver0.6
from sympy import *
AB=24;BC=12
B,C,A=map(Point,[(0,0),(BC,0),(BC,sqrt(AB**2-BC**2))])
D=A.midpoint(B)
CE=BC 
E=Point(C.x,CE)                                 # ;print("# E ",E)
G=D.midpoint(E)                                 # ;print("# G ",G)
H=Line(B,B+(E-D)).intersection(Line(C,G))[0]    # ;print("# H ",H)  
print("# ",G.distance(H).simplify())
#  6*sqrt(2)
############################################################################
# 作図用
F=Line(B,B+(E-D)).intersection(Line(C,A))[0]    # ;print("# F ",F)  
############################################################################
# 3D作図 z=0 XY平面に作図しました。
############################################################################
def myXYZ2Txt_2D(A):
    return '(' + str(A.x) + ',' + str(A.y) +  ')'
    # return ""
def myTxtXYZ_2D(A,myWedgei):
    P5x=float(A.x)
    P5y=float(A.y)
    P5z=0.0
    p5 = FreeCAD.Vector(P5x, P5y, P5z)
    myText = Draft.makeText(myWedgei, p5)
    myText.Label = myWedgei
    FreeCADGui.ActiveDocument.ActiveObject.FontSize = '1.5 mm'
    return
def myTxtXYZ_S_2D(*xy_tx):
    for i in range(1,int(len(xy_tx)/2)+1):
        myTxtXYZ_2D(xy_tx[2*i-2],xy_tx[2*i-1]+myXYZ2Txt_2D(xy_tx[2*i-2]) )
    return
def myLine_2D(A,B):
    Ax,Ay,Az=float(A.x),float(A.y),0.0
    Bx,By,Bz=float(B.x),float(B.y),0.0
    pl = FreeCAD.Placement()
    pl.Rotation.Q = (0.4247081540122249, 0.17592004639554645, 0.33985110062924484, 0.8204732460821097)
    pl.Base = FreeCAD.Vector(-3.9166066876399563, -2.1670824762243774, 1.7495260956243028)
    points = [FreeCAD.Vector(Ax,Ay,Az), FreeCAD.Vector(Bx,By,Bz)]
    line = Draft.make_wire(points, placement=pl, closed=False, face=True, support=None)
    Draft.autogroup(line)
    return
def myLine_S_2D(*args):
    for i in range(1,len(args)):
        myLine_2D(args[i-1],args[i])
    return
def myLine_C_2D(*args):
    for i in range(1,len(args)):
        myLine_2D(args[i-1],args[i])
    myLine_2D(args[i],args[0])
    return
#######################################################################################
myLine_C_2D  (A,B,C)
myLine_S_2D  (D,E)
myLine_S_2D  (B,F)
myLine_S_2D  (G,C)
myTxtXYZ_S_2D(A,"A",B,"B",C,"C")
myTxtXYZ_S_2D(D,"D",E,"E",F,"F",H,"H")
#######################################################################################
doc = App.activeDocument()
App.ActiveDocument.addObject("App::Origin", "Origin")
App.ActiveDocument.getObject('Origin').Visibility = True
App.ActiveDocument.recompute()
Gui.activeDocument().activeView().viewAxonometric()
Gui.SendMsgToActiveView("ViewFit")
```
・問題文は2次元ですが、３次元FreeCADのマクロで、XY平面上に作図しました。
・isometric方向です。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/9f2e0dc8-5280-f80e-c216-f990e5256fb7.png)

・上空からです。拡大図
・Originは、マウス操作で非表示です。
・寸法、角度表示,勉強中です。文字の移動も。


![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/b32f682b-c394-1dde-3d1e-80fb3dfa4ac4.png)

# 大本命？？？　ChatGPT-3.1先生より。　私の理解不足で、できませんでした。
```
　三角形ABCは∠ABC=90°の直角
三角形であり、点Dは辺ABの中点である。
　また、2点E,Fは辺AC上の点で、BC=CEであり、
BF//DEである。
　さらに、点Gは線分DEの中点であり、点Hは線分BF
と線分CGとの交点である。
　AB=24cm,BC=12cmのとき、線分GHの長さは?
sympyのソースコードをお願いします。
```
・最終行を追加しました。
　以下回答省略。**全体の連立方程式です。** 時間によって変わるかも。
　エラーがでます。「本当ですか。」と質問すると、修正があります。**アキラメマシタ。**
　TypeError: list indices must be integers or slices, not Symbol
・??? 二等分線と平行線の条件 ??? (参照:加比の理)　???
```python
from sympy import symbols, solve, Eq

# 変数の定義
AB = 24
BC = 12

# 辺の長さ
AB_length = AB
BC_length = BC
AC_length = symbols('AC')

# 三角形の条件
eq1 = Eq(AB_length**2 + BC_length**2, AC_length**2)  # ピタゴラスの定理

# 点Eの位置
CE_length = BC_length
AE_length = symbols('AE')
eq2 = Eq(AE_length + CE_length, AC_length)  # AC = AE + CE

# 二等分線と平行線の条件
DE_length = symbols('DE')
BF_length = symbols('BF')
eq3 = Eq(BF_length / DE_length, BC_length / DE_length)  # BC/DE = BF/DE

# GがDEの中点である条件
DG_length = symbols('DG')
eq4 = Eq(DG_length, DE_length / 2)  # DG = DE/2

# HがBFとCGの交点である条件
GH_length = symbols('GH')
CG_length = symbols('CG')
eq5 = Eq(BF_length / GH_length, DE_length / (DE_length + CG_length))  # BF/GH = DE/(DE+CG)

# 方程式の解を求める
solutions = solve((eq1, eq2, eq3, eq4, eq5), (AC_length, AE_length, DE_length, BF_length, CG_length, GH_length))

# 線分GHの長さを取得
GH_length = solutions[GH_length]
print("線分GHの長さ:", GH_length.evalf())
```
# 参照 subsの使い方をChatGPT-3.5先生に聞きました。
You
from sympy import *
var('AB,BC',real=True,positive=True)
rep={AB:24,BC:12}           
A=A.subs(rep).simplify()
B=B.subs(rep).simplify()
C=C.subs(rep).simplify()
D=D.subs(rep).simplify()
E=E.subs(rep).simplify()
F=F.subs(rep).simplify()
G=G.subs(rep).simplify()
H=H.subs(rep).simplify()
代入の箇所を1行にする方法を教えて下さい。

ChatGPT
以下のように、代入を1行にまとめることができます。
A, B, C, D, E, F, G, H = symbols('A B C D E F G H')
AB, BC = symbols('AB BC', real=True, positive=True)
values = {AB: 24, BC: 12}
A, B, C, D, E, F, G, H = [expr.subs(values).simplify() for expr in [A, B, C, D, E, F, G, H]]
**この方法では、各変数に対して subs と simplify を1行で適用しています。**

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。

https://qiita.com/mrrclb48z/items/61a30b880eaabf44ea04

・sympy.simplify.sqrtdenest.sqrtdenest(expr, max_iter=3)
https://docs.sympy.org/latest/modules/simplify/simplify.html#sympy.simplify.sqrtdenest.sqrtdenest
・class sympy.geometry.polygon.Triangle(*args, **kwargs)
　keyword: asa, sas, or sss to specify sides/angles of the triangle
https://docs.sympy.org/latest/modules/geometry/polygons.html#sympy.geometry.polygon.Triangle
・使ってみたかった中点。(a+b)/2,a+(b-a)/2と同じです。
The midpoint between self and point p. 
https://docs.sympy.org/latest/modules/geometry/points.html#sympy.geometry.point.Point.midpoint`

https://qiita.com/mrrclb48z/items/0563f66fa0a1ffa06da5

・コメントオフになっていました。こちらもおすすめです。
学習塾ステップ（STEP）【公式チャンネル】様
・∠ECFの30°を**残り角**と表現されていました。

https://youtu.be/G2iW4YtYfPc