0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

おうぎ形の半径の長さは?「気付きました?実は簡単に解くことができます!【数学】」をsympyとFreeCADでやってみたい。

Last updated at Posted at 2024-09-05

・問題文は2次元ですが、3次元FreeCADのマクロで、XY平面上に作図しました。
・基本に忠実に?やってみました。

オリジナル

・さあ、学ぼう! 様 (0:00〜5:56)

sympyで(オリジナル 様の方法を参考に)

ver0.1 三平方の定理より

・web上でも、できます。本ページ最後におすすめにリンクあります。sympy Liveで。
・solveで xとODがでました。おいしいですネ。

# ver0.1 三平方の定理より
from sympy import *
var("x,OD",real=True,positive=True)
eq1=Eq( x   **2+(4+6)**2,OD**2)
eq2=Eq((x+8)**2+ 4   **2,OD**2)
print("#",solve([eq1,eq2],[x,OD])[0][1])
# 5*sqrt(65)/4

WolframAlpha で(〃)

・ODをdとしています。

 解 (省略)

・(参考)ODのままでは、できませんでした。
https://www.wolframalpha.com/input?i=x%5E2%2B%284%2B6%29%5E2%3DOD%5E2%2C%28x%2B8%29%5E2%2B4%5E2%3DOD**2&lang=ja

sympyで(いつもの方法で)

ver 0.2  垂直二等分線と鉛直線の交点計算で。

・基本に忠実に、最初に浮かんだのがコレ。
・ver0.2は、原点をAで計算しています。最後に点Oを原点へ移動していません。
・初めて、perpendicular_line 使いました。
Create a new Line perpendicular to this linear entity which passes through the point p
https://docs.sympy.org/latest/modules/geometry/lines.html#sympy.geometry.line.LinearEntity.perpendicular_line

from sympy import *
AB,BC,CD=4,8,6
A=  Point(0, 0  )
B=A+Point(AB,0  )
C=B+Point(0 ,-BC)
D=C+Point(CD,0  )
O=Line(B,D).perpendicular_line(B.midpoint(D)).intersection(Line(A,B).perpendicular_line(A))[0]
print("#",O.distance(D))
# 5*sqrt(65)/4

ver 0.3 連立方程式で.>弧の上にBとDがあります。

・ver0.3は、原点をOとしています。作図がラクです。

# ver0.3 連立方程式で.>弧の上にBとDがあります。
from sympy import *
var("r,OA",real=True,positive=True)
AB,BC,CD=4,8,6
O=  Point(0,0  )
A=O+Point(0,OA )
B=A+Point(AB,0 )
C=B+Point(0,-BC)
D=C+Point(CD,0 )
sol=solve([Eq(O.distance(B),r),Eq(O.distance(D),r)],[r,OA])
print("#",sol[0][0])
# 5*sqrt(65)/4

ver0.4 sympy風? 最後に値の代入。

・何もここまで? ver0.3を作ってからですけど。

# ver0.4 sympy風? 最後に値の代入。
from sympy import *
var("r,OA"    ,real=True,positive=True)
var("AB,BC,CD",real=True,positive=True)
O=  Point(0,0  )
A=O+Point(0,OA )
B=A+Point(AB,0 )
C=B+Point(0,-BC)
D=C+Point(CD,0 )
r=solve([Eq(O.distance(B),r),Eq(O.distance(D),r)],[r,OA])[0][0]
print("#",r)
rep={AB:4,BC:8,CD:6}
r=r.subs(rep)
print("#",r.subs(rep))
# sqrt(4*AB**2*BC**2 + (2*AB*CD + BC**2 + CD**2)**2)/(2*BC)
# 5*sqrt(65)/4

FreeCADのマクロで作図

・問題文は2次元ですが、3次元FreeCADのマクロで、XY平面に作図しました。
・計算部分は、Ver.0.3 の コピー貼り付けです。
・subsで、計算結果に置換しています。

import FreeCAD
import Part
import DraftTools
import Draft
import Mesh
############################################################################
from sympy import *
var("r,OA",real=True,positive=True)
AB,BC,CD=4,8,6
O=  Point(0,0  )
A=O+Point(0,OA )
B=A+Point(AB,0 )
C=B+Point(0,-BC)
D=C+Point(CD,0 )
sol=solve([Eq(O.distance(B),r),Eq(O.distance(D),r)],[r,OA])
print("#",sol[0][0])
# 5*sqrt(65)/4
###########################################################################
# 作図用
rep={r:sol[0][0],OA:sol[0][1]}
r=sol[0][0]
A=A.subs(rep)
B=B.subs(rep)
C=C.subs(rep)
D=D.subs(rep)
############################################################################
# 3D作図 z=0 XY平面に作図しました。
############################################################################
# 円の作図 FrecCADのdocより
# https://wiki.freecad.org/Macro_Circle
def Freecad3D_circle(x=0.0,y=0.0,z=0.0,radius=0.0,diameter=0.0,circumference=0.0,area=0.0,startangle=0.0,endangle=0.0,arc=0.0,anglecenter=0.0,cord=0.0,arrow=0.0,center=0,placemObject=""):
    from math import sqrt, pi
    if placemObject == "":
        pl = FreeCAD.Placement()
        pl.Rotation = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation()   
        pl.Base = FreeCAD.Vector(x,y,z)
    else:
        pl = FreeCAD.Placement()
        pl = placemObject                                  # placement imposted
    if diameter != 0:                                      # with diameter
        radius = diameter / 2.0
    elif circumference != 0:                               # with circumference
        radius = (circumference / pi) / 2.0
    elif area != 0:                                        # with area
        radius =  sqrt((area / pi))
    elif (cord != 0) and (arrow != 0):                     # with cord and arrow
        radius = ((arrow**2) + (cord**2) / 4.0) / (arrow*2) 
    elif (arc != 0) and (anglecenter != 0):                # with arc and anglecenter central in degrees
        radius = ((360/anglecenter)*arc) / pi/2.0
        if endangle != 0:
            startangle  = endangle - anglecenter
        endangle   = anglecenter + startangle
        startangle  = endangle - anglecenter
    if radius != 0:
        try:
            Draft.makeCircle(radius,placement=pl,face=False,startangle=startangle,endangle=endangle,support=None)
            if center != 0:
                x=pl.Base.x
                y=pl.Base.y
                z=pl.Base.z
                Draft.makePoint(x,y,z)
        except Exception:
            App.Console.PrintError("Unexpected keyword argument" + "\n")
        App.ActiveDocument.recompute()
    else:
        App.Console.PrintMessage("Unexpected keyword argument" + "\n")
        App.Console.PrintMessage("circle(x,y,z,radius,diameter,circumference,area,startangle,endangle,[arc,anglecenter],[cord,arrow],center,placemObject)" + "\n")
        App.Console.PrintMessage("circle(radius=10.0,placemObject=App.Placement(App.Vector(11,20,30), App.Rotation(30,40,0), App.Vector(0,0,0)))" + "\n")
    return
def myCircle_2D(myCi):
    x=myCi.center.x
    y=myCi.center.y
    r=myCi.radius
    Freecad3D_circle(
           x=float(x),y=float(y),z=0.0,
           radius=float(abs(r)),
           center=1,
           placemObject=App.Placement(App.Vector(float(x),float(y),0),
           App.Rotation(0,0,0),App.Vector(0,0,0)))
    return
def myCircle_Ogigata_2D(myCi,myStAngle,myEndAngle):
    x=myCi.center.x
    y=myCi.center.y
    r=myCi.radius
    Freecad3D_circle(
           x=float(x),y=float(y),z=0.0,
           radius=float(abs(r)),
           startangle=myStAngle,
           endangle=myEndAngle,
           center=1,
           placemObject=App.Placement(App.Vector(float(x),float(y),0),
           App.Rotation(0,0,0),App.Vector(0,0,0)))
    myLine_S_2D(Point(x,y),Point(x+r*cos(rad(myStAngle)), y+r*sin(rad(myStAngle))))
    myLine_S_2D(Point(x,y),Point(x+r*cos(rad(myEndAngle)), y+r*sin(rad(myEndAngle))))
    return
def myXYZ2Txt_2D(A):
    return ""
def myXYZ2Txt_XY_2D(A):
    return '(' + str(A.x) + ',' + str(A.y) +  ')'
def myTxtXYZ_2D(A,myWedgei):
    P5x=float(A.x)
    P5y=float(A.y)
    P5z=0.0
    p5 = FreeCAD.Vector(P5x, P5y, P5z)
    myText = Draft.makeText(myWedgei, p5)
    myText.Label = myWedgei
    FreeCADGui.ActiveDocument.ActiveObject.FontSize = '0.7 mm'
    # FreeCADGui.ActiveDocument.ActiveObject.FontSize = '0.5 mm'
    #FreeCADGui.ActiveDocument.ActiveObject.FontSize = '1.0 mm'
    return
def myTxtXYZ_S_2D(*xy_tx):
    for i in range(1,int(len(xy_tx)/2)+1):
        myTxtXYZ_2D(xy_tx[2*i-2],xy_tx[2*i-1]+myXYZ2Txt_2D(xy_tx[2*i-2]) )
    return
def myTxtXYZ_XY_S_2D(*xy_tx):
    for i in range(1,int(len(xy_tx)/2)+1):
        myTxtXYZ_2D(xy_tx[2*i-2],xy_tx[2*i-1]+myXYZ2Txt_XY_2D(xy_tx[2*i-2]) )
    return
def myLine_2D(A,B):
    Ax,Ay,Az=float(A.x),float(A.y),0.0
    Bx,By,Bz=float(B.x),float(B.y),0.0
    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_2D(*args):
    for i in range(1,len(args)):
        myLine_2D(args[i-1],args[i])
    return
def myLine_C_2D(*args):
    for i in range(1,len(args)):
        myLine_2D(args[i-1],args[i])
    myLine_2D(args[i],args[0])
    return
def myLine_H_2D(*args):
    for i in range(1,len(args)):
        myLine_2D(args[0],args[i])
    return
##################################################################################
myLine_S_2D        (A,B,C,D)  
myTxtXYZ_XY_S_2D   (O,"O",A,"A",B,"B",C,"C",D,"D")
myCircle_Ogigata_2D(Circle(O,r),0,90)
#
myLine_S_2D        (Point(0,0),Point(0,r))
myLine_S_2D        (Point(0,0),Point(r,0))
####################################################################################
doc = App.activeDocument()
#App.ActiveDocument.addObject("App::Origin", "Origin")
#App.ActiveDocumen!t.getObject('Origin').Visibility = True
App.ActiveDocument.recompute()
Gui.activeDocument().activeView().viewAxonometric()
Gui.SendMsgToActiveView("ViewFit")

isometric方向?です。(省略)
拡大図

2.png

拡大図(CADの操作で寸法線を追加)
・(青色の)角度寸法は、ニセモノです。Part>計測>角度計算 です。
・角度寸法の表示は、まだ勉強中です。3.png

いつもの? sympyの実行環境と 参考のおすすめです。

(テンプレート)

・以下ができたら、助かります。指定と全部です

いつもと違うおすすめです。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?