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?

平面図形「【高校入試数学 想定外?! 正答率0.4% 】...~山形県公立入試数学~」をsympyとFreeCADでやってみたい。ユークリッド原論も。

Last updated at Posted at 2025-01-09

・長文です。以下、中学数学の範囲外が含まれています。
・問題文は2次元ですが、3次元FreeCADのマクロで、XY平面上に作図しました。
・AI先生に画像の丸投げ? 私の説明不足でした。あきらめました。

オリジナル

Youtube

MAスカッと塾 様 (0:00〜4:50) 赤の面積を求めよ。
https://youtu.be/oIi9AdjQVEo

PDF

5山形県 <R3年(2021年)春 全問PDF
???以下直接だと、待ち時間あり。このサイトにアクセスできません
https://homepage1.canvas.ne.jp/ynaka/R3PDF/05yamagata.pdf#page=8
< 数学苦手な中学生,応援します 様内
http://homepage1.canvas.ne.jp/ynaka/zenmon.html

sympyのweb上での実行方法

SymPy Live Shellで。FreeCADのマクロは、以下で実行できません。
https://qiita.com/mrrclb48z/items/00dd08b0317069be9342#web%E4%B8%8A%E3%81%AE%E5%AE%9F%E8%A1%8C%E6%96%B9%E6%B3%95sympy-live-shell%E3%81%A7
 

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

??? 無難に、/2をRaional(1,2)です。実数も変数も、ルート内も。分数、無理数のsympyの威力。
・ver0.1
 途中、怪しい。trを使っていない。

# ver0.1
from sympy import *    
var('r,siromarukuromaru',nonnegative=True) 
AB,DE=8,6
r=AB*Rational(1,2)
OA=OD=OC=OE=OB=r
degOBC=degOCB=degOED=degODE=siromarukuromaru
trOOBC =Triangle(sas=(r,180-(degOBC+degOCB),r)) 
trOOED =Triangle(sas=(r,180-(degOED+degODE),r)) 
print("#",trOOBC==trOOED)
CB=DE                                              # 怪しい。trを使っていない。
BG=OD                                              # 平行四辺形
h =sqrt(OB**2-(CB*Rational(1,2))**2)               #;print(h)
CG=CB-BG
trCFG =Triangle(asa=(siromarukuromaru,CG,siromarukuromaru)) 
trCOB =Triangle(asa=(siromarukuromaru,CB,siromarukuromaru)) 
print("#",are_similar(trCFG,trCOB))
sojihi=CG/CB                                       # ;print(sojihi)
print("#",Rational(1,2)*CB*h*sojihi**2)
# True
# True
# sqrt(7)/3

sympyで(いつもの方法で)

・ver0.2 CAD風
 ??? >ここで紹介した解法は、あくまでも一例ということでご覧ください。

# ver0.2 CAD風
from sympy import *    
AB,DE=8,6
r    =AB*Rational(1,2)
O,A,B=map(Point,[(0,0),(-r,0),(r,0)])
D,E  =Circle(O,r).intersection(Line(A,B).parallel_line(Point(0,sqrt(r**2-(DE*Rational(1,2))**2)))) 
C    =Circle(O,r).intersection(Line(O,D).parallel_line(B))[1]   
F    =Line(O,C)  .intersection(Line(D,E))[0]               
G    =Line(B,C)  .intersection(Line(D,E))[0]               
print("#",Triangle(C,F,G).area)
# sqrt(7)/3

・ver0.3 最後にsubsで代入
 もっとsympy風。AB,DEの値を最後にsubsで代入。途中ver0.2と同じ。
 ??? ver0.2があってこそ。

# ver0.3 最後にsubsで代入
from sympy import *    
var('AB,DE',nonnegative=True) 
r    =AB*Rational(1,2)
O,A,B=map(Point,[(0,0),(-r,0),(r,0)])
D,E  =Circle(O,r).intersection(Line(A,B).parallel_line(Point(0,sqrt(r**2-(DE*Rational(1,2))**2)))) 
C    =Circle(O,r).intersection(Line(O,D).parallel_line(B))[1]   
F    =Line(O,C)  .intersection(Line(D,E))[0]               
G    =Line(B,C)  .intersection(Line(D,E))[0]               
print("#",Triangle(C,F,G).area)
print("#",Triangle(C,F,G).area.subs({AB:8,DE:6}))
# sqrt(AB**2 - DE**2)*(AB**2 - 4*AB*DE + 4*DE**2)/(16*DE)
# sqrt(7)/3

FreeCADのマクロで作図

・問題文は2次元ですが、3次元FreeCADのマクロで、XY平面に作図しました。
・計算部分は、Ver.0.4 の コピー貼り付けです。
 面積計算にHを使っていないので、途中作図用にHの計算をしています。

# 以下でます。 
# この機能は非推奨です。この機能を直接使用しないでください。
#   「make_linear_dimension」または「make_linear_dimension_obj」のいずれかを使用してください。
import FreeCAD
import Part
import DraftTools
import Draft
import Mesh
############################################################################
# ver0.2
# ??? >ここで紹介した解法は、あくまでも一例ということでご覧ください。
# ??? 無難に、実数も変数も、/2よりRaionalです.ルート内も。sympyの威力。
from sympy import *    
AB,DE=8,6
r    =AB*Rational(1,2)
O,A,B=map(Point,[(0,0),(-r,0),(r,0)])
D,E  =Circle(O,r).intersection(Line(A,B).parallel_line(Point(0,sqrt(r**2-(DE*Rational(1,2))**2)))) 
C    =Circle(O,r).intersection(Line(O,D).parallel_line(B))[1]   
F    =Line(O,C)  .intersection(Line(D,E))[0]               
G    =Line(B,C)  .intersection(Line(D,E))[0]               
print("#",Triangle(C,F,G).area)
# sqrt(7)/3
############################################################################
H  =Line(B,C)  .intersection(Line(O,E))[0]               
############################################################################
# 3D作図 z=0 XY平面に作図しました。
# 2024-10-08 fontsize 追加しました。従来と互換性がありません。 
# 2024-10-20 HR 
############################################################################
def myDimension(fontsize,myExtOvershoot,start_point, end_point,HVP):
    x1, y1 = start_point.args
    x2, y2 = end_point.args
    myFlipText = True
    if HVP=="PL":
       myP1  =Point(float(x1),float(y1))
       myP2  =Point(float(x2),float(y2))
       myFlipText = False
       myExtOvershoot1=abs(myExtOvershoot)
    elif HVP=="PR":
       myP1  =Point(float(x1),float(y1))
       myP2  =Point(float(x2),float(y2))
       myFlipText = False
       myExtOvershoot1=-abs(myExtOvershoot)
    elif HVP=="VL":
       if x1<x2 and y1<y2:
          myP1  =Point(float(x1),float(y1))
          myP2  =Point(float(x1),float(y2))
          myExtOvershoot1= abs(myExtOvershoot)
          myFlipText = False
       elif x1<x2 and y1>y2:
          myP1  =Point(float(x1),float(y1))
          myP2  =Point(float(x1),float(y2))
          myExtOvershoot1=-abs(myExtOvershoot)
       elif x1>x2 and y1<y2:
          myP1  =Point(float(x2),float(y1))
          myP2  =Point(float(x2),float(y2))
          myExtOvershoot1= abs(myExtOvershoot)
          myFlipText = False
       else:
          myP1  =Point(float(x2),float(y1))
          myP2  =Point(float(x2),float(y2))
          myExtOvershoot1=-abs(myExtOvershoot)
    elif HVP=="VR":
       if x1<x2 and y1<y2:
          myP1  =Point(float(x2),float(y1))
          myP2  =Point(float(x2),float(y2))
          myExtOvershoot1=-abs(myExtOvershoot)
          myFlipText = False
       elif x1<x2 and y1>y2:
          myP1  =Point(float(x2),float(y1))
          myP2  =Point(float(x2),float(y2))
          myExtOvershoot1= abs(myExtOvershoot)
       elif x1>x2 and y1<y2:
          myP1  =Point(float(x1),float(y1))
          myP2  =Point(float(x1),float(y2))
          myExtOvershoot1=-abs(myExtOvershoot)
       else:
          myP1  =Point(float(x1),float(y1))
          myP2  =Point(float(x1),float(y2))
          myExtOvershoot1= abs(myExtOvershoot)
    elif HVP=="HL":
       if x1 < x2 and y1<y2:
          myP1  =Point(float(x1),float(y2))
          myP2  =Point(float(x2),float(y2))
          myExtOvershoot1= abs(myExtOvershoot)
          myFlipText = False
       elif x1 < x2 and y1>y2:
          myP1  =Point(float(x1),float(y1))
          myP2  =Point(float(x2),float(y1))
          myExtOvershoot1= abs(myExtOvershoot)
          myFlipText = False
       elif x1 > x2 and y1<y2:
          myP1  =Point(float(x1),float(y1))
          myP2  =Point(float(x2),float(y1))
          myExtOvershoot1= abs(myExtOvershoot)
       else:
          myP1  =Point(float(x1),float(y2))
          myP2  =Point(float(x2),float(y2))
          myExtOvershoot1= abs(myExtOvershoot)
    elif HVP=="HR":
       #if x1<x2 and y1<y2: # 2024-10-20 HR
       if x1<x2 and y1<=y2:
          myP1  =Point(float(x1),float(y1))
          myP2  =Point(float(x2),float(y1))
          myExtOvershoot1=-abs(myExtOvershoot)
          myFlipText = False
       elif x1<x2 and y1>y2:
          myP1  =Point(float(x1),float(y2))
          myP2  =Point(float(x2),float(y2))
          myExtOvershoot1=-abs(myExtOvershoot)
          myFlipText = False
       elif x1>x2 and y1<y2:
          myP1  =Point(float(x1),float(y2))
          myP2  =Point(float(x2),float(y2))
          myExtOvershoot1=-abs(myExtOvershoot)
       else:
          myP1  =Point(float(x1),float(y1))
          myP2  =Point(float(x2),float(y1))
          myExtOvershoot1=-abs(myExtOvershoot)
    else:  
      print("")
    myM   =myP1.midpoint(myP2)
    myT   =myM+myExtOvershoot1*((myP1-myM).unit).rotate( -pi/2 )
    dimension = Draft.makeDimension(
        FreeCAD.Vector(myP1.x, myP1.y, 0),           # 点1の座標
        FreeCAD.Vector(myP2.x, myP2.y, 0),           # 点2の座標
        FreeCAD.Vector(float(myT.x),float(myT.y),0)  # 矢印の位置を中央に設定
    )
    # Ext Overshootを設定
    dimension.ViewObject.ExtOvershoot = -float(myExtOvershoot)
    
    dimension.ViewObject.FlipText = myFlipText

    # 矢印のスタイルを設定
    dimension.ViewObject.ArrowType    = "Arrow"  # 矢印のタイプを "Arrow" に設定
    dimension.ViewObject.ArrowSize    = fontsize/5
    dimension.ViewObject.TextSpacing  = 0
    dimension.ViewObject.LineColor    = (0.0, 1.0, 0.0)  # 緑色
    dimension.ViewObject.FontSize     = fontsize  # フォントサイズを指定
def myXYZ2Txt_2D(A):
    return ""
def myXYZ2Txt_XY_2D(A):
    return '(' + str(A.x) + ',' + str(A.y) +  ')'
def myTxtXYZ_2D(fontsize,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 = str(fontsize,)+' mm'
    return
def myTxtXYZ_S_2D(fontsize,*xy_tx):
    for i in range(1,int(len(xy_tx)/2)+1):
        myTxtXYZ_2D(fontsize,xy_tx[2*i-2],xy_tx[2*i-1]+myXYZ2Txt_2D(xy_tx[2*i-2]) )
    return
def myTxtXYZ_XY_S_2D(fontsize,*xy_tx):
    for i in range(1,int(len(xy_tx)/2)+1):
        myTxtXYZ_2D(fontsize,xy_tx[2*i-2],xy_tx[2*i-1]+myXYZ2Txt_XY_2D(xy_tx[2*i-2]) )
    return

def myTxtXYZ_MoveY_2D(fontsize,MoveY,A,myWedgei):
    P5x=float(A.x)
    P5y=float(A.y)+MoveY
    P5z=0.0
    p5 = FreeCAD.Vector(P5x, P5y, P5z)
    myText = Draft.makeText(myWedgei, p5)
    myText.Label = myWedgei
    FreeCADGui.ActiveDocument.ActiveObject.FontSize = str(fontsize,)+' mm'
    return
def myTxtXYZ_XY_S_MoveY_2D(fontsize,MoveY,*xy_tx):
    for i in range(1,int(len(xy_tx)/2)+1):
        myTxtXYZ_MoveY_2D(fontsize,MoveY,xy_tx[2*i-2],xy_tx[2*i-1]+myXYZ2Txt_XY_2D(xy_tx[2*i-2]) )
    return
############################################################################
# 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 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
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
##################################################################################
myCircle_Ogigata_2D(Circle(O,r),0,180)
myLine_S_2D (A,O,B)  
myLine_S_2D (O,D,F,G,E)     #  myLine_S_2D (O,D,E) 
myLine_S_2D (O,F,C,G,H,B) # ine_S_2D (O,C,B)   
myLine_S_2D (O,H,E)  
myFontsize =0.4
myOvershoot=myFontsize*6
myTxtXYZ_XY_S_2D              (myFontsize,O,"O",A,"A",B,"B",C,"C",D,"D")
myTxtXYZ_XY_S_2D              (myFontsize,E,"E",F,"F",H,"H")
#myTxtXYZ_XY_S_2D              (myFontsize,E,"E",F,"F",G,"G")
#myTxtXYZ_XY_S_2D              (myFontsize,E,"E",F,"F")
myTxtXYZ_XY_S_MoveY_2D(myFontsize,myFontsize,G,"G")
# myTxtXYZ_XY_S_MoveY_2D(myFontsize,-myMoveY,A,"A")
myDimension(myFontsize,myOvershoot,A,B,"HR")
myDimension(myFontsize,myOvershoot,D,E,"PL")
####################################################################################
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方向。斜め方向から。
(省略)

上空からです。
角度寸法、はCAD操作です。
未。三角形のハッチング。

111.png

??? (追加) AI先生へ画像の丸投げをあきらめました。残念。

(反省)PDFを? PDFから?丸投げすべきでした。
・(Youtubeスクショ画像省略)

(だめでした)ChatGPT先生へ

・申し訳ありません。私の説明不足でした。私の丸投げで平行のコメントをしていません。

(回答抜粋)
??? C = Point(0, radius) # 半円上の頂点C
??? このコードを実行すると、三角形 △CFG の面積が 9 と出力されます。

あきらめました。

Gemini先生へ

copilot先生へ

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

(テンプレート)

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

sympyのDoc

・ver0.1

・ver0.2 (いつもの方法で)

intersection(o)
https://docs.sympy.org/latest/modules/geometry/ellipses.html#sympy.geometry.ellipse.Circle.intersection

・FreeCAD
(テンプレートを参照)

AI先生へ(深入りはやめました。何もそこまでしなくても)

平行四辺形の対角が同じなのを、sympyで証明して下さい。

(ステキ過ぎて省略)
コードを実行すると、is_equal が 0 になれば、対角線が等しいことが証明されます。
ユークリッド言論にありますか
ユークリッド『原論』**には直接的には登場しません。...
ユークリッド『原論』第1巻(Book I)の命題34では、...
このように、『原論』には直接的な記述はないものの、関連する命題を組み合わせれば証明が可能です。

平行線の同位角、錯角が同じ。ユークリッド言論にありますか。

命題 27~29(Book I)...
ユークリッドの第5公準(平行線公準)...

wikipedia

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?