LoginSignup
0
0

More than 1 year has passed since last update.

空間図形「21年 兵庫県大 商経・情報 3」をsympyとFreeCADでやってみた。

Last updated at Posted at 2022-12-05

座標空間内の8点.....平行四辺形....
オリジナル

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

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

勉強中

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

from sympy import *
var('p q t')
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
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)
O=Point3D(0,0,0)
A=Point3D(0,0,1)
B=Point3D(1,0,1)
C=Point3D(1,1,1)
D=Point3D(0,1,1)
E=Point3D(1,0,0)
F=Point3D(1,1,0)
P=Point3D(1,0,p)
Q=Point3D(0,1,q)
Hp=O+t*(C-O)
lp=P.distance(Hp).subs({t:solve((Hp-P).dot(C-O),t)[0]}).simplify()
print("#(1)",lp.subs({p:0}))
print("#(2)",lp)
ans=solve(myTaisekiGyouretuSiki(O,P,C,Q),q)[0]
print("#(3)",ans)
S =(myMensekiVector3D((O-P),(C-P))*2).subs({q:ans})
S2=(S**2).simplify()
ans=solve(diff(S2,p))[0]
print("#(4)最小値",ans,S.subs({p:ans}))
print("#(4)最大値",0  ,S.subs({p:0}))
print("#(4)最大値",1  ,S.subs({p:1}))
plot(S,(p,0,1))
#(1) sqrt(6)/3
#(2) sqrt(6*p**2 - 6*p + 6)/3
#(3) 1 - p
#(4)最小値 1/2 sqrt(6)/2
#(4)最大値 0 sqrt(2)
#(4)最大値 1 sqrt(2)

以下の、on line sympyで、上記のソースコードを貼り付けて実行できました。Plotもでました。
私の環境は,pycharmです。 

グラフの縦横比は、調整してありません。pとSの関係。

Figure_1.png

FreeCADのマクロで

マクロからsympyを使っています。
(4)の最小値の条件で作図しました。
ワイヤーフレームです。Part Boxは、使っていません。

png1.png

import FreeCAD
import Part
import Draft
import Mesh
#########################################################################################################
from sympy import *
var('p q t')
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
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)
O=Point3D(0,0,0)
A=Point3D(0,0,1)
B=Point3D(1,0,1)
C=Point3D(1,1,1)
D=Point3D(0,1,1)
E=Point3D(1,0,0)
F=Point3D(1,1,0)
G=Point3D(0,1,0)
P=Point3D(1,0,p)
Q=Point3D(0,1,q)
Hp=O+t*(C-O)
lp=P.distance(Hp).subs({t:solve((Hp-P).dot(C-O),t)[0]}).simplify()
print("#(1)",lp.subs({p:0}))
print("#(2)",lp)
ans=solve(myTaisekiGyouretuSiki(O,P,C,Q),q)[0]
print("#(3)",ans)
S =(myMensekiVector3D((O-P),(C-P))*2).subs({q:ans})
S2=(S**2).simplify()
ans=solve(diff(S2,p))[0]
print("#(4)最小値",ans,S.subs({p:ans}))
print("#(4)最大値",0  ,S.subs({p:0}))
print("#(4)最大値",1  ,S.subs({p:1}))
#########################################################################################################
# 怪しいです。
P=P.subs({p:ans})
Q=Q.subs({q:1-ans})
#########################################################################################################
# 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.1 mm'
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]) )
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])
myTxtXYZ_S(O,"O",A,"A",B,"B",C,"C",D,"D",E,"E",F,"F",G,"G",P,"P",Q,"Q")
myLine_S(O,E,F,G,O)
myLine_S(A,B,C,D,A)
myLine(A,O)
myLine(B,E)
myLine(C,F)
myLine(D,G)
myLine_S(O,P,C,Q,O)
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")
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