四面体「2023岐阜大学前期【1】」をsympyとFreeCADでやってみた。

FreeCADのマクロで作図しました。
(ワイヤーフレームです。ソリッドを勉強中。)

オリジナル 河合塾様

https://nyushi.sankei.com/honshi/23/gi1-21p.pdf

解答

https://kaisoku.kawai-juku.ac.jp/nyushi/honshi/23/gi1-21a.pdf

https://kamelink.com/exam/index.php?2023%C7%AF%B2%F2%C5%FA%C2%AE%CA%F3#o1a406b9

上と同じです。大学入試数学問題集成＞【1】テキスト

https://mathexamtest.web.fc2.com/2023/202310441/2023104410100mj.html

# sympyで(オリジナルのやり方)
河合塾様の方法を勉強中。

# sympyで(sympy的?安易なやり方)
①？？？？　TR12を使わない方法を教えて下さい。　？？？
②直角三角形を考えた方がよかったです。
```python
from sympy import *
from sympy.simplify.fu import TR12
s=Symbol('s',real=True,positive=True)
t=Symbol('t',real=True,positive=True)
var('x y z')
var('u v w')
#var('t')
def myMenseki3D(O,A,B):
    P=A-O
    Q=B-O
    return Rational(1, 2) * sqrt(P.distance(Point(0, 0, 0)) ** 2 * Q.distance(Point(0, 0, 0)) ** 2 \
                                 - P.dot(Q) ** 2).simplify()
def myABC(OQ, OA,OB,OC):
    return solve([
                  Eq(OQ.x,u*OA.x+v*OB.x+w*OC.x),
                  Eq(OQ.y,u*OA.y+v*OB.y+w*OC.y),
                  Eq(OQ.z,u*OA.z+v*OB.z+w*OC.z)
                 ],
                 [u,v,w])
def mySphereFormula(myP,myR):
    return ((x-myP.x)**2+(y-myP.y)**2+(z-myP.z)**2-myR**2).expand()
def myMenseki3D(O,A,B):
    P=A-O
    Q=B-O
    return Rational(1, 2) * sqrt(P.distance(Point(0, 0, 0)) ** 2 * Q.distance(Point(0, 0, 0)) ** 2 \
                                 - P.dot(Q) ** 2).simplify()
#
L=1
A=Point3D(0              ,0                      ,0)
B=Point3D(L              ,0                      ,0)
C=Point3D(L*Rational(1,2),L*Rational(1,2)*sqrt(3),0)
dum,Oxyz=solve([mySphereFormula(A,L),
                mySphereFormula(B,L),
                mySphereFormula(C,L)],[x,y,z]
              )
O=Point(Oxyz)
P=A+Rational(1,3)*(B-A)
Q=O+           s *(P-O)
G=Rational(1,3)*(A+B+C)
OQuvw=myABC(Q-O,A-O,B-O,C-O)
QGuvw=myABC(G-Q,A-O,B-O,C-O)
print("#(1)",OQuvw)
print("#(1)",QGuvw)
a=A-O
b=B-O
c=C-O
OQ=OQuvw[u]*a+OQuvw[v]*b+OQuvw[w]*c
QG=QGuvw[u]*a+QGuvw[v]*b+QGuvw[w]*c
ans=solve(OQ.dot(QG))[0]
print("#(2)",ans)
Q=Q.subs({s:ans})
print("#(3)",myMenseki3D(O,Q,G))
cosOGQ=(O-G).dot(Q-G)/(O.distance(G)*Q.distance(G))
cosOPG=(O-P).dot(G-P)/(O.distance(P)*G.distance(P))
print("#(4X)",tan(acos(cosOGQ)+acos(cosOPG)))
print("#(4) cosOGQ-cosOPG=",cosOGQ-cosOPG)
print("#(4)",TR12(tan(s+t)).subs({s:t}).subs({t:acos(cosOPG)}))
#(1) {u: 2*s/3, v: s/3, w: 0}
#(1) {u: 1/3 - 2*s/3, v: 1/3 - s/3, w: 1/3}
#(2) 6/7
#(3) sqrt(6)/21
#(4X) tan(2*acos(sqrt(7)/7))
#(4) cosOGQ-cosOPG= 0
#(4) -2*sqrt(6)/5
```
①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。
計算時間は約1分です。資源の無駄使い。ごめんなさい。

https://live.sympy.org/

# FreeCADのマクロで作図
```python
import FreeCAD
import Part
import Draft
import Mesh
#########################################################################################################
# 計算
from sympy import *
from sympy.simplify.fu import TR12
s=Symbol('s',real=True,positive=True)
t=Symbol('t',real=True,positive=True)
var('x y z')
var('u v w')
#var('t')
def myMenseki3D(O,A,B):
    P=A-O
    Q=B-O
    return Rational(1, 2) * sqrt(P.distance(Point(0, 0, 0)) ** 2 * Q.distance(Point(0, 0, 0)) ** 2 \
                                 - P.dot(Q) ** 2).simplify()
def myABC(OQ, OA,OB,OC):
    return solve([
                  Eq(OQ.x,u*OA.x+v*OB.x+w*OC.x),
                  Eq(OQ.y,u*OA.y+v*OB.y+w*OC.y),
                  Eq(OQ.z,u*OA.z+v*OB.z+w*OC.z)
                 ],
                 [u,v,w])
def mySphereFormula(myP,myR):
    return ((x-myP.x)**2+(y-myP.y)**2+(z-myP.z)**2-myR**2).expand()
def myMenseki3D(O,A,B):
    P=A-O
    Q=B-O
    return Rational(1, 2) * sqrt(P.distance(Point(0, 0, 0)) ** 2 * Q.distance(Point(0, 0, 0)) ** 2 \
                                 - P.dot(Q) ** 2).simplify()
#
L=1
A=Point3D(0              ,0                      ,0)
B=Point3D(L              ,0                      ,0)
C=Point3D(L*Rational(1,2),L*Rational(1,2)*sqrt(3),0)
dum,Oxyz=solve([mySphereFormula(A,L),
                mySphereFormula(B,L),
                mySphereFormula(C,L)],[x,y,z]
              )
O=Point(Oxyz)
P=A+Rational(1,3)*(B-A)
Q=O+           s *(P-O)
G=Rational(1,3)*(A+B+C)
OQuvw=myABC(Q-O,A-O,B-O,C-O)
QGuvw=myABC(G-Q,A-O,B-O,C-O)
print("#(1)",OQuvw)
print("#(1)",QGuvw)
a=A-O
b=B-O
c=C-O
OQ=OQuvw[u]*a+OQuvw[v]*b+OQuvw[w]*c
QG=QGuvw[u]*a+QGuvw[v]*b+QGuvw[w]*c
ans=solve(OQ.dot(QG))[0]
print("#(2)",ans)
Q=Q.subs({s:ans})
print("#(3)",myMenseki3D(O,Q,G))
cosOGQ=(O-G).dot(Q-G)/(O.distance(G)*Q.distance(G))
cosOPG=(O-P).dot(G-P)/(O.distance(P)*G.distance(P))
print("#(4X)",tan(acos(cosOGQ)+acos(cosOPG)))
print("#(4) cosOGQ-cosOPG=",cosOGQ-cosOPG)
print("#(4)",TR12(tan(s+t)).subs({s:t}).subs({t:acos(cosOPG)}))
##########################################################################################################
### 作図用
##########################################################################################################
### 3D作図
def myXYZ2Txt(A):
    return '(' + str(A.x) + ',' + str(A.y) + ',' + str(A.z) + ')'
def myTxtXYZ(A,myWedgei):
    P5x=float(A.x)
    P5y=float(A.y)
    P5z=float(A.z)
    p5 = FreeCAD.Vector(P5x, P5y, P5z)
    myText = Draft.makeText(myWedgei, p5)
    myText.Label = myWedgei
    #FreeCADGui.ActiveDocument.ActiveObject.FontSize = '0.5 mm'
    #FreeCADGui.ActiveDocument.ActiveObject.FontSize = '0.1 mm'
    FreeCADGui.ActiveDocument.ActiveObject.FontSize = '0.05 mm'
    return
def myTxtXYZ_S(*xy_tx):
    for i in range(1,int(len(xy_tx)/2)+1):
        myTxtXYZ(xy_tx[2*i-2],xy_tx[2*i-1]+myXYZ2Txt(xy_tx[2*i-2]) )
    return
def myLine(A,B):
    Ax,Ay,Az=float(A.x),float(A.y),float(A.z)
    Bx,By,Bz=float(B.x),float(B.y),float(B.z)
    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(*args):
    for i in range(1,len(args)):
        myLine(args[i-1],args[i])
    return
def myLine_C(*args):
    for i in range(1,len(args)):
        myLine(args[i-1],args[i])
    myLine(args[i],args[0])
    return
def myLine_H(*args):
    for i in range(1,len(args)):
        myLine(args[0],args[i])
    return
#
myLine_C  (A,B,C)
myLine_H  (O, A,B,C)
myLine_S  (O,G,Q)
myLine_S  (O,P,G)
myTxtXYZ_S(A,"A",B,"B",C,"C",O,"O",G,"G",P,"P",Q,"Q")
#
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")
```

isometric

![0png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/fa0d7c24-9ff3-fed8-a47e-a2d6661a91ad.png)

上空から

![1png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/1e5f8db8-f0cf-538e-937b-59a6bc44c59a.png)

# 参考
この岐阜大学の問題と広島大学の問題と似ていると思いました。

https://qiita.com/mrrclb48z/items/383a97bfe1c27b0ab395

from sympy.simplify.fu import TR2i　を使っていました。

https://qiita.com/mrrclb48z/items/73209467dcd77093874a

https://qiita.com/mrrclb48z/items/693e1a20e293a528bccb