LoginSignup
0
0

空間ベクトル「2023札幌医科大学前期【1】」をsympyとFreeCADでやってみた。

Last updated at Posted at 2023-03-30

FreeCADのマクロで作図しました。
テクニカルな方法?を含めて4通りの計算方法です。

オリジナル

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

sympyで (1)数学入試問題様のやり方:平方完成で

平方完成
https://qiita.com/mrrclb48z/items/38e849f41f46bf0c8f9c
??? 第2引数の使い方を教えて下さい。??? 

from sympy import *
t    =Symbol ('t'    ,real=True)
x,h,k=symbols('x h k',real=True)
def myHeihokanseiABC(f,t):
    f=f.subs({t:x})
    g=Poly(f).all_coeffs()[0]*( x - h )**2 + k
    ans=solve( f - g, [ h, k ] ) 
    return a,ans[0][0],ans[0][1]
a=Point(3,-1,2)
b=Point(2, 2,1)
pp=((a+t*b).distance(Point(0,0,0))**2).expand()
ans=myHeihokanseiABC(pp,t)
print("#",ans[1],sqrt(ans[2]))
# -2/3 sqrt(10)

sympyで (2)数学入試問題様のやり方:内積で

無理に、最小値を1行でprint出力する必要もありませんでした
後半部分は、内積条件からPの座標計算です。

from sympy import *
t=Symbol('t',real=True)
a=Point(3,-1,2)
b=Point(2, 2,1)
#
print("#",(a+t*b).subs({t:solve(b.dot(a+t*b))[0]}).distance(Point(0,0,0)) )
#
P=a+t*b
ans=solve(b.dot(P))[0]
P=P.subs({t:ans})
print("#",ans,P.distance(Point(0,0,0)) )
# sqrt(10)
# -2/3 sqrt(10)

sympyで (3)直線への垂線計算で

??? tの計算(自作関数mySolveT)について、いい方法がありますか ???
平方が見えないのがステキです。最小値を計算後,tを求めています。不思議ですね。

from sympy import *
t=Symbol ('t',real=True)
def mySolveT(OQ, OA):
    return solve([
                  Eq(OQ.x,t*OA.x),
                  Eq(OQ.y,t*OA.y),
                  Eq(OQ.z,t*OA.z)
                 ],
                 [t])
O=Point(0, 0,0)
a=Point(3,-1,2)
b=Point(2, 2,1)
print("#",O.distance(Line(a,a+t*b).projection(O)))
#
p=Line(a,a+t*b).projection(O)
#以下の3行は、うまくいきませんでした。
#ans=solve(Eq(P,a+t*b),t)
#t=(P-a)/b
#t=(P-a).distance(O)/b.distance(O)
print("#",mySolveT((p-a),b)[t],p.distance(O))
# sqrt(10)
# -2/3 sqrt(10)

sympyで (4)sympyのminimum 関数で

参考より。minimum 関数をみつけました。
(3)と同様に、
平方が見えないのがステキです。最小値を計算後,tを求めています。不思議ですね。

from sympy import *
t=Symbol ('t',real=True)
O=Point(0, 0,0)
a=Point(3,-1,2)
b=Point(2, 2,1)
p=a+t*b
minp=minimum(p.distance(O),t,S.Reals)
print("#",solveset(Eq(p.distance(O),minp),t,S.Reals).args[0],minp)
# -2/3 sqrt(10)
plot(p.distance(O),0,(t,-5,5))

原点から直線までの離れ
縦横比は、異なります。
橙色y=0は、ダミーです。非表示?同じ色?

0png.png

計算の実行環境

①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。

??? タブレット環境で、コピー貼り付けが実行できませんでした。???

FreeCADのマクロで作図

import FreeCAD
import Part
import Draft
import Mesh
#########################################################################################################
# 計算
from sympy import *
t=Symbol('t',real=True)
a=Point(3,-1,2)
b=Point(2, 2,1)
print("#",(a+t*b).subs({t:solve(b.dot(a+t*b))[0]}).distance(Point(0,0,0)) )
P=a+t*b
ans=solve(b.dot(P))[0]
P=P.subs({t:ans})
print("#",ans,P.distance(Point(0,0,0)) )
##########################################################################################################
### 作図用
O=Point(0,0,0)
##########################################################################################################
### 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.3 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
#
myLine_S  (O,a,a+b)
myLine    (O,P)
myTxtXYZ_S(O,"O",a,"a",a+b,"a+b",P,"P")
#
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

上空から

1png.png

参考

最小値は「minimum関数」です。<

sympy.calculus.util.minimum(f, symbol, domain=Reals)

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