空間図形「2022年熊本大学・教育第1問」をsympyとFreeCADでやってみた。

平面と平面の交わりとして得られる直線...

オリジナル

https://kamelink.com/blog/2022/09/25/6-6-22-kumamotodai-kyouiku%E3%83%BBikango-1/

上と同じです。

https://ameblo.jp/mathisii/entry-12764715177.html

上と同じです。大学入試数学問題集成＞【1】＞入試の軌跡　数学

https://mathexamtest.web.fc2.com/2022/202210901/2022109010100mj.html
 
以下**7通り**です。
# sympyで(計算だけ)
**(解法1)** ますいしい様の手順で
勉強中＞成分をすべて整数で表した方が見やすいですね

**(解法2)** Distance from a point to a line「点と直線の距離 」3D空間上
```python
from sympy import *
A=Point3D(2.0, 0.0, 0.0)
B=Point3D(0.0, 3.0, 0.0)
C=Point3D(0.0, 0.0, 1.0)
D=Point3D(3.0,-1.0, Rational(5,6))
E=Point3D(8.0, 4.0,-Rational(1,3))
F=Point3D(5.0, 3.0, Rational(1,2))
print("#(問1) ",Line(A,B).distance(C))
print("#(問1) ",Line(D,E).distance(F))
sl=Plane(A,B,C).intersection(Plane(D,E,F))[0]
print("#(問2A)",Plane(Point3D(0,0,1), normal_vector=(0, 0, 1)).intersection(sl)[0])
print("#(問2A)",sl.direction_ratio[0]/12,sl.direction_ratio[1]/12,sl.direction_ratio[2]/12)
print("#(問2B)",Plane(Point3D(0,0,3), normal_vector=(0, 0, 1)).intersection(sl)[0])
print("#(問2B)",sl.direction_ratio[0]/4,sl.direction_ratio[1]/4,sl.direction_ratio[2]/4)
#(問1)  7*sqrt(13)/13
#(問1)  2*sqrt(985)/43
#(問2A) Point3D(2, -3, 1)
#(問2A) 2 -1 -2/3
#(問2B) Point3D(-4, 0, 3)
#(問2B) 6 -3 -2
```

**(解法3)** 三角形ができるか判定？最も長い辺長をc。隣辺?2点間の距離の和との比較で。a+b=cが一致。
**(解法4)** 三角形の面積=0で判定？ヘロンの公式。
**(解法5)** 三角形の面積=0で判定？内積を使う方法もありました。
**(解法6)** 三角形の面積=0で判定？外積を使う方法もありました。


# FreeCADのマクロで
?datum planeのスクリプトを探しています。
?datum planeの操作を勉強中です。
平面と平面の交わりとして得られる直線に見えません。

https://wiki.freecadweb.org/PartDesign_Plane


上の(解法2)のsympy計算に、FreeCAD作図を追加しました。

![png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/4079cb46-2192-5e01-580a-2bc7c99a0e79.png)

```python
import FreeCAD
import Part
import Draft
import Mesh
#########################################################################################################
# 計算
from sympy import *
A=Point3D(2.0, 0.0, 0.0)
B=Point3D(0.0, 3.0, 0.0)
C=Point3D(0.0, 0.0, 1.0)
D=Point3D(3.0,-1.0, Rational(5,6))
E=Point3D(8.0, 4.0,-Rational(1,3))
F=Point3D(5.0, 3.0, Rational(1,2))
print("#(問1) ",Line(A,B).distance(C))
print("#(問1) ",Line(D,E).distance(F))
sl=Plane(A,B,C).intersection(Plane(D,E,F))[0]
print("#(問2A)",Plane(Point3D(0,0,1), normal_vector=(0, 0, 1)).intersection(sl)[0])
print("#(問2A)",sl.direction_ratio[0]/12,sl.direction_ratio[1]/12,sl.direction_ratio[2]/12)
print("#(問2B)",Plane(Point3D(0,0,3), normal_vector=(0, 0, 1)).intersection(sl)[0])
print("#(問2B)",sl.direction_ratio[0]/4,sl.direction_ratio[1]/4,sl.direction_ratio[2]/4)
#(問1)  7*sqrt(13)/13
#(問1)  2*sqrt(985)/43
#(問2A) Point3D(2, -3, 1)
#(問2A) 2 -1 -2/3
#(問2B) Point3D(-4, 0, 3)
#(問2B) 6 -3 -2
L_1=Plane(Point3D(0,0,1), normal_vector=(0, 0, 1)).intersection(sl)[0]  #z=1
L_2=Plane(Point3D(0,0,3), normal_vector=(0, 0, 1)).intersection(sl)[0]  #z=3
##########################################################################################################
### 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'
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)
def myLine_S(*args):
    for i in range(1,len(args)):
        myLine(args[i-1],args[i])
    return 0
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]) ) 
myTxtXYZ_S(A,"A",B,"B",C,"C",D,"D",E,"E",F,"F",L_1,"L_1",L_2,"L_2")
myLine_S(A,B,C,A)
myLine_S(D,E,F,D)
myLine  (L_1,L_2)
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")
```

# 参考

https://qiita.com/mrrclb48z/items/7fa9e060b46334060ac7

https://ictsr4.com/sw/sympy%E3%81%AB%E3%82%88%E3%82%8B%E4%B8%89%E8%A7%92%E9%96%A2%E6%95%B0%E3%81%AE%E8%A8%88%E7%AE%97/

https://qiita.com/mrrclb48z/items/15beeb08dcd74e8bc183