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?

平面図形「2025愛知公立高校入試図形3(2)平面図形、長方形、一部分の面積や線分の問題の解説」様を参考にsympyとFreeCADでやってみたい。

Last updated at Posted at 2025-04-17

長文です。 中学数学の範囲外が含まれています。
・問題文は2次元ですが、3次元FreeCADのマクロで、XY平面上に作図しました。

オリジナル

Youtube

 東亜紗美moveforward数学教室 様 (0:00〜16:51) 
 2025愛知公立高校入試図形3(2)平面図形、長方形、一部分の面積や線分の問題の解説
 https://youtu.be/iBzpFLHbBJM

PDF

・保護されていない通信
 23愛知県<R7年(2025年)全問PDF 大問3(2) ページの真ん中です。
 http://homepage1.canvas.ne.jp/ynaka/R7PDF/23aichi.pdf#page=7
 <数学苦手な中学生,応援します 様内
 http://homepage1.canvas.ne.jp/ynaka/index.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で(オリジナル 様の方法を参考に)

ver0.1

・>ソージだらけ。 >いろんな方法でできる。

# ver0.1
from sympy import *
var('x,y',positive=True)
AB,AD=4,6
ED   =Rational(1,3)*AD
BD   =sqrt(AB**2+AD**2)          #;print(BD)
x    =solve(Eq(BD/ED,AD/x),x)[0] #;print(x)
print("#",x/BD)
y   =solve(Eq(AB/x ,BD/y),y)[0]  #;print(y)
print("#",AB*AD*Rational(1,2)*y/AB*(BD-x)/BD)
# 3/13
# 90/13

sympyで(いつもの方法で)

ver0.2

・xy座標です。ソージは、私は苦手です。

# ver0.2
from sympy import *
# var('AB,AD',positive=True)
AB,AD  =4,6
A,B,C,D=map(Point,([(0,AB),(0,0),(AD,0),(AD,AB)]))
E      =A+Rational(2,3)*(D-A)
G      =Line(B,D).projection(E)               #;print(G)
F      =Line(C,D).intersection(Line(E,G))[0]  #;print(F)
print("#",D.distance(G)/D.distance(B))
print("#",Triangle(G,B,F).area)
# 3/13
# 90/13

ver0.3

・ver0.2と同じです。
 >有理化をしない。 >後で外れるから。
 最後にsubsです。

# ver0.3
from sympy import *
var('AB,AD',positive=True)
# AB,AD  =4,6
A,B,C,D=map(Point,([(0,AB),(0,0),(AD,0),(AD,AB)]))
E      =A+Rational(2,3)*(D-A)
G      =Line(B,D).projection(E)               #;print(G)
F      =Line(C,D).intersection(Line(E,G))[0]  #;print(F)
print("#",D.distance(G)/D.distance(B))
print("#",Triangle(G,B,F).area)
# 
rep={AB:4,AD:6}
print("#",(D.distance(G)/D.distance(B)).subs(rep))
print("#",(Triangle(G,B,F).area)       .subs(rep))
# sqrt((AB - AB*(3*AB**2 + 2*AD**2)/(3*(AB**2 + AD**2)))**2 + (AD - AD*(3*AB**2 + 2*AD**2)/(3*(AB**2 + AD**2)))**2)/sqrt(AB**2 + AD**2)
# AD**3*(3*AB**2 + 2*AD**2)/(18*AB*(AB**2 + AD**2))
# 3/13
# 90/13

FreeCADのマクロで作図

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

# 以下でます。 
# この機能は非推奨です。この機能を直接使用しないでください。
#   「make_linear_dimension」または「make_linear_dimension_obj」のいずれかを使用してください。
import FreeCAD
import Part
import DraftTools
import Draft
import Mesh
# # ##############################################
# ver0.2
# ソージは、私は苦手です。
from sympy import *
# var('AB,AD',positive=True)
AB,AD  =4,6
A,B,C,D=map(Point,([(0,AB),(0,0),(AD,0),(AD,AB)]))
E      =A+Rational(2,3)*(D-A)
G      =Line(B,D).projection(E)               #;print(G)
F      =Line(C,D).intersection(Line(E,G))[0]  #;print(F)
print("#",D.distance(G)/D.distance(B))
print("#",Triangle(G,B,F).area)
# 3/13
# 90/13
############################################################################
# 3D作図 z=0 XY平面に作図しました。
# 2024-10-08 fontsize 追加しました。従来と互換性がありません。 
# 2024-10-20 HR 
# 2025-03-27 HL 
############################################################################
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
          #myFlipText = True
       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平面に作図しました。
############################################################################
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)
myLine_S_2D(E,G,F,B,G,D)  
myFontsize =0.3
myTxtXYZ_XY_S_2D(myFontsize,A,"A",B,"B",C,"C",D,"D",E,"E",F,"F",G,"G")
myOvershoot=myFontsize*4
myDimension(myFontsize,myOvershoot,B,A,"VR")
myDimension(myFontsize,myOvershoot,A,D,"HL")
myDimension(myFontsize,myOvershoot,G,D,"PL")
myDimension(myFontsize,myOvershoot,F,D,"VL")
####################################################################################
doc = App.activeDocument()
#
# 2025-03-27 なんだか調子が悪い
# App.ActiveDocument.addObject("App::Origin", "Origin")
# App.ActiveDocumen!t.getObject('Origin').Visibility = True
origin = doc.addObject("App::Origin", "Origin")
# origin.Visibility = True
#
App.ActiveDocument.recompute()
Gui.activeDocument().activeView().viewAxonometric()
Gui.SendMsgToActiveView("ViewFit")

isometric方向。斜め方向から。
111.png

上空からです。平面図です。
・平行寸法は、override(手打ち)しています。
 無理数表示を勉強中です。
・角度寸法は、Measure Angularを使っています。
・単位がmmのままでした。勉強中です。いい言葉?ですね。
222.png

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

(テンプレート)

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

ver0.1

・Solvers
https://docs.sympy.org/latest/modules/solvers/solvers.html

ver0.2

・Project a point, line, ray, or segment onto this linear entity.
https://docs.sympy.org/latest/modules/geometry/lines.html#sympy.geometry.line.LinearEntity.projection
・The intersection with another geometrical entity.
https://docs.sympy.org/latest/modules/geometry/lines.html#sympy.geometry.line.LinearEntity.intersection

ver0.3

・Substitution
https://docs.sympy.org/latest/tutorials/intro-tutorial/basic_operations.html#substitution

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?