1
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?

長方形の4頂点から、内部の円へ4接線「幾何学チャレンジ問題 AQ=?」をsympyとFreeCADでやってみたい。

Last updated at Posted at 2024-09-02

・作図は、いくつであっても、の一つです。
・問題文は2次元ですが、3次元FreeCADのマクロで、XY平面上に作図しました。

パイソニスタの方へ
教えて下さい。
・simplify()もsqrtdenest()も、簡略化できませんでした。
・長方形の縦横の辺の長さ、半径に必要十分条件を計算する方法です。

オリジナル

・YUUU0123 様 (0:00〜5:51)
>消えてしまいます。

YouTubeのコメントありがとうございました。
>こんばんわ。r>1はなくてもよかったのですが、円の半径がいくつであっても、答えは√77、ですので、限りなく円の半径を0に近づけてしまえば、x²+6²=8²+7²で解けてしまうため、ちょっと変えてみました。
>こんばんわ。調べましたが、定理としての名前は、出てきません。名前のない定理(定理といっていいものかわかりませんが)ですね。

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

ver0.1 プログラムの2行余計でした。

# ver0.1 プログラムの2行余計でした。
from sympy import *
var('x,r',real=True,positive=True)
print("#",solve(Eq((x**2+r**2)+(6**2+r**2),(8**2+r**2)+(7**2+r**2)),[x,r]))
print("#",solve(Eq((x**2+r**2)+(6**2+r**2),(8**2+r**2)+(7**2+r**2)),[x,r])[0])
print("#",solve(Eq((x**2+r**2)+(6**2+r**2),(8**2+r**2)+(7**2+r**2)),[x,r])[0][0])
# [(sqrt(77), r)]
# (sqrt(77), r)
# sqrt(77)

sympyで(いつもの方法で)

できませんでした。ver0.2 連立方程式。値の代入で対応しました。

・長方形の横の辺の長さが2*u,縦の辺の長さが2*v
・3例です。

# できませんでした。ver0.2 連立方程式。直接、値の代入で対応しました。
from sympy import *
var('u,v,x,r',real=True,positive=True)
var('Ox,Oy'  ,real=True)
A,B,C,D,O=map(Point,[(-u, v),(-u,-v),(u,-v),(u,v),(Ox,Oy)])
sol=solve([Eq(B.distance(O),sqrt(8**2+r**2)),
           Eq(C.distance(O),sqrt(6**2+r**2)),
           Eq(D.distance(O),sqrt(7**2+r**2))
          ],[Ox,Oy,r])
print("#",sol[0])
print("#",sol[1])
O,r=Point(sol[0][0],sol[0][1]),sol[0][2]
print("#",sqrt(A.distance(O)**2-r**2)            )
print("#",sqrt(A.distance(O)**2-r**2).simplify() )
print()
rep={u: 6,v: 5};print("#",(sqrt(A.distance(O)**2-r**2)).subs(rep),float(r.subs(rep)),5)
rep={u: 6,v: 6};print("#",(sqrt(A.distance(O)**2-r**2)).subs(rep),float(r.subs(rep)),6)
rep={u: 7,v: 5};print("#",(sqrt(A.distance(O)**2-r**2)).subs(rep),float(r.subs(rep)),5)
# (u - sqrt(u**4 - 14*u**2 + 49)/u, -13/(4*v), sqrt(16*u**4*v**2 + 16*u**2*v**4 - 904*u**2*v**2 + 169*u**2 + 784*v**2)/(4*u*v))
# (u + sqrt(u**4 - 14*u**2 + 49)/u, -13/(4*v), sqrt(16*u**4*v**2 + 16*u**2*v**4 - 904*u**2*v**2 + 169*u**2 + 784*v**2)/(4*u*v))
# sqrt((-2*u + sqrt(u**4 - 14*u**2 + 49)/u)**2 + (v + 13/(4*v))**2 - (16*u**4*v**2 + 16*u**2*v**4 - 904*u**2*v**2 + 169*u**2 + 784*v**2)/(16*u**2*v**2))
# sqrt(4*u**2 - 4*sqrt(u**4 - 14*u**2 + 49) + 49)

# sqrt(77) 2.5067132087877764 5
# sqrt(77) 4.141800802656846 6
# sqrt(77) 4.35 5

FreeCADのマクロで作図

・問題文は2次元ですが、3次元FreeCADのマクロで、XY平面に作図しました。
・計算部分は、Ver.0.2 の コピー貼り付けです。
・接点の座標計算は、2円の交点計算より、座標変換にしたらよかった。
 左右考えなくて、よかったカモ。

import FreeCAD
import Part
import DraftTools
import Draft
import Mesh
############################################################################
# できませんでした。ver0.2 連立方程式。値の代入で対応しました。
from sympy import *
var('u,v,x,r',real=True,positive=True)
var('Ox,Oy'  ,real=True)
A,B,C,D,O=map(Point,[(-u, v),(-u,-v),(u,-v),(u,v),(Ox,Oy)])
sol=solve([Eq(B.distance(O),sqrt(8**2+r**2)),
           Eq(C.distance(O),sqrt(6**2+r**2)),
           Eq(D.distance(O),sqrt(7**2+r**2))
          ],[Ox,Oy,r])
print("#",sol[0])
print("#",sol[1])
O,r=Point(sol[0][0],sol[0][1]),sol[0][2]
print("#",sqrt(A.distance(O)**2-r**2)            )
print("#",sqrt(A.distance(O)**2-r**2).simplify() )
print()
rep={u: 6,v: 5};print("#",(sqrt(A.distance(O)**2-r**2)).subs(rep),float(r.subs(rep)),5)
#rep={u: 6,v: 6};print("#",(sqrt(A.distance(O)**2-r**2)).subs(rep),float(r.subs(rep)),6)
#rep={u: 7,v: 5};print("#",(sqrt(A.distance(O)**2-r**2)).subs(rep),float(r.subs(rep)),5)
############################################################################
A=A.subs(rep)
B=B.subs(rep)
C=C.subs(rep)
D=D.subs(rep)
r    =sol[0][2]                  .subs(rep)
x    =sqrt(A.distance(O)**2-r**2).subs(rep)
rep_r={r:sol[0][2].subs(rep),x:sqrt(A.distance(O)**2-r**2).subs(rep)}
O=O.subs(rep).subs(rep_r) ;print(O)
P=Circle(O,r).intersection(Circle(D,7))[0]
Q=Circle(O,r).intersection(Circle(A,x))[0]
R=Circle(O,r).intersection(Circle(B,8))[1]
S=Circle(O,r).intersection(Circle(C,6))[1]
############################################################################
# 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 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.3 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_C_2D     (A,B,C,D)  
myTxtXYZ_XY_S_2D(O,"O",A,"A",B,"B",C,"C",D,"D")
myCircle_2D     (Circle(O ,r ))
myLine_S_2D     (D,P)  
myLine_S_2D     (A,Q)  
myLine_S_2D     (B,R)  
myLine_S_2D     (C,S)
myTxtXYZ_XY_S_2D(P,"P",Q,"Q",R,"R",S,"S")  
####################################################################################
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の操作で寸法線を追加)
・作図は、いくつであっても、の一つです。

√77
https://www.wolframalpha.com/input?i=%E2%88%9A77&lang=ja
3.png

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

(テンプレート)

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

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

1
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
1
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?