LoginSignup
0
0

More than 1 year has passed since last update.

空間図形「21年 宮崎大 工・医・農・教育 3」をsympyとFreeCADでやってみた。

Last updated at Posted at 2022-12-12

...3点A,B,Cを含む平面αをとし...
オリジナル

上と同じです。大学入試数学問題集成>【3】

sympyで(オリジナルのやり方)

勉強中

sympyで(sympy的?安易なやり方)

from sympy import *
var('p q')
def myMensekiVector3D(P,Q):
    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 myTaisekiGyouretuSiki(PTO,PTA,PTB,PTC):
    return Matrix([[PTA.x-PTO.x, PTA.y-PTO.y, PTA.z-PTO.z], \
                   [PTB.x-PTO.x, PTB.y-PTO.y, PTB.z-PTO.z], \
                   [PTC.x-PTO.x, PTC.y-PTO.y, PTC.z-PTO.z]]).det()/6
O,A,B,C,D=map(Point,([0,0,0],[1,1,0],[0,2,0],[0,0,6],[p,q,1]))
print("#(1)",(A-O).dot(D-O)/(O.distance(A)*O.distance(D)))
S=myMensekiVector3D(A-O,D-O)
print("#(2)",S)
qp=solve(myTaisekiGyouretuSiki(A,B,C,D),q)[0]
print("#(3)",D.subs({q:qp}) \
             .subs({p:solve(diff((S**2).subs({q:qp})),p)[0]}))
#(1) sqrt(2)*(p + q)/(2*sqrt(p**2 + q**2 + 1))
#(2) sqrt(p**2 - 2*p*q + q**2 + 2)/2
#(3) Point3D(5/6, 5/6, 1)

以下の、on line sympyで、上記のソースコードを貼り付けて実行できました。

FreeCADのマクロで

マクロからsympyを使っています。
(3)で作図しました。点DがCA上でした。

png1.png

上(FreeCAD:TOP)から見た。点Dは、OA上でもありました。

png2.png

import FreeCAD
import Part
import Draft
import Mesh
#########################################################################################################
from sympy import *
var('p q')
def myMensekiVector3D(P,Q):
    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 myTaisekiGyouretuSiki(PTO,PTA,PTB,PTC):
    return Matrix([[PTA.x-PTO.x, PTA.y-PTO.y, PTA.z-PTO.z], \
                   [PTB.x-PTO.x, PTB.y-PTO.y, PTB.z-PTO.z], \
                   [PTC.x-PTO.x, PTC.y-PTO.y, PTC.z-PTO.z]]).det()/6
O,A,B,C,D=map(Point,([0,0,0],[1,1,0],[0,2,0],[0,0,6],[p,q,1]))
print("#(1)",(A-O).dot(D-O)/(O.distance(A)*O.distance(D)))
S=myMensekiVector3D(A-O,D-O)
print("#(2)",S)
qp=solve(myTaisekiGyouretuSiki(A,B,C,D),q)[0]
print("#(3)",D.subs({q:qp}) \
             .subs({p:solve(diff((S**2).subs({q:qp})),p)[0]}))
#########################################################################################################
D=D.subs({q:qp}) \
             .subs({p:solve(diff((S**2).subs({q:qp})),p)[0]})
print("# CA",C.distance(A))
print("# CD+DA",C.distance(D),D.distance(A),C.distance(D)+D.distance(A))
#########################################################################################################
# 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.2 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
myTxtXYZ_S(O,"O",A,"A",B,"B",C,"C",D,"D")
myLine_S  (A,B,C,A)
myLine_S  (A,O,D)
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")
# CA sqrt(38)
# CD+DA 5*sqrt(38)/6 sqrt(38)/6 sqrt(38)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0