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?

(途中)複素数平面(その1/3)「2025 慶応義塾大学 理工学部【1】(1)のみ」をsympyとFreeCADでやってみた。

Last updated at Posted at 2025-03-28

長文です。 (その2/3)を作成中です。以下、高校数学の範囲外が含まれています。
・参照サイトは、ページの最後です。
・問題文は2次元ですが、3次元FreeCADのマクロで、XY平面上に作図しました。

・パイソニスタの方へ

「myメソッド1」のおすすめのページを探しています。
 メソッド1: zだけで        ←←← これです。
 メソッド2: zをx+iyに置き換えて
 メソッド3: zをR*(cos(θ)+I*sin(θ))に置き換えて
 メソッド4: 最初からxyを想定して
 メソッド5: 外部の怪しい?モジュールをインストールで
 メソッド6: いつの日か、アフィン変換行列でやってみたい。

・分冊

オリジナル

・Youtube
 数数英数 様
 2025 慶應理工1⚠️ 終了  
 複素数平面のみ(0:00〜02:15) https://youtu.be/bkf8fuNceIs
 フル     (0:00〜17:02)

・問題文(mathjax テキスト形式)
 大学入試数学問題集成 様。いつもお世話になっております。
 2025 慶応義塾大学 理工学部MathJax【1】(1)
 https://mathexamtest.web.fc2.com/2025/202513338/2025133380300mj.html#top-0301
 https://mathexamtest.web.fc2.com/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 < 複素数平面の最初からわかってアポロニウスの円で。Iを使って。

# ver0.1
from sympy import *
var('A,B',complex=True)
A,B=-I,sqrt(3)
P1=( 1*A+2*B)/(2+1)
P2=(-1*A+2*B)/(2-1)
M =(P1+P2)/2
print("#",M,abs(P1-M))
# 4*sqrt(3)/3 + I/3 4/3

・ver0.2 < 複素数平面の最初からわかってアポロニウスの円で。Iを使わず、xy平面で。

# ver0.2
from sympy import *
# var('x,y')                          # real=True が必要です。
var('x,y,t',real=True)
O,A,B=map(Point,[(0,0),(0,-1),(sqrt(3),0)])
P1=( 1*A+2*B)/(2+1)
P2=(-1*A+2*B)/(2-1)
M =(P1+P2)/2
Ci=Circle(M,P1.distance(P2)/2)
print("#",Ci)
# Circle(Point2D(13*sqrt(3)/12, 1/12), 5/6)
# ----------- 
# implicit で
# waku=6
# # plot_implicit(Ci           ,(x,-waku,waku),(y,-waku,waku),aspect="equal",size=(6, 6))  # 無理でした。
# plot_implicit  (Ci.equation(),(x,-waku,waku),(y,-waku,waku),aspect="equal",size=(6, 6))
# ------------
# parametric で
Ci_ap=Ci       .arbitrary_point()
Li_ap=Line(A,B).arbitrary_point()
plot_parametric((10*cos(t),10*sin(t),(t,0,2*pi)),
                (Li_ap[0],Li_ap[1],(t,0,1   )),
                (Ci_ap[0],Ci_ap[1],(t,0,2*pi)),
                 aspect = "equal",size=(6,6)  )

・ver0.3 < wikipediaの公式を使って。

# ver0.3 
from sympy import *
var('m,n')
A,B=map(Point,[(0,-1),(sqrt(3),0)])
print("#",((-n*A+m*B)/(m-n))                     .subs({m:2**2,n:1**2}))
print("#",( abs((m*n)/(m**2-n**2))*A.distance(B)).subs({m:2,n:1}))
# Point2D(4*sqrt(3)/3, 1/3)
# 4/3

sympyで(いつもの方法で)

・ver0.4 複素数平面→xy平面
 途中で、複素数平面からxy平面のCircleに持ち込んでいます。
 myI_Pointで、複素数平面→xy平面変換です。

# ver0.4 複素数平面→xy平面
from sympy import *
var('x,y,t',real=True)
def myI_Point(my):
    return Point(re(my),im(my))
z=x+I*y;A=-I;B=sqrt(3)
myLhs=z-A;myRhs=2*(z-B)
# abs2=(myLhs*conjugate(myLhs)-(myRhs*conjugate(myRhs)))             # expand()が必要です
abs2  =(myLhs*conjugate(myLhs)-(myRhs*conjugate(myRhs))).expand()   ;print("#",abs2)
print("#",Circle(abs2))
# -3*x**2 + 8*sqrt(3)*x - 3*y**2 + 2*y - 11
# Circle(Point2D(4*sqrt(3)/3, 1/3), 4/3)
# 
# # ----------- 
# # implicit で
# waku=4
# plot_implicit(abs2,(x,-waku,waku),(y,-waku,waku),aspect="equal",size=(6, 6))
# # ----------- 
# parametric で
Ci_ap=Circle(abs2)                     .arbitrary_point()
Li_ap=Line  (myI_Point(A),myI_Point(B)).arbitrary_point()
waku=5
plot_parametric((waku*cos(t),waku*sin(t),(t,0,2*pi)),
                (Li_ap[0],Li_ap[1],(t,0,1   )),
                (Ci_ap[0],Ci_ap[1],(t,0,2*pi)),
                 aspect = "equal",size=(5,5)  )

・青色の円を非表示です。
111.png

FreeCADのマクロで作図

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

# 以下でます。 
# この機能は非推奨です。この機能を直接使用しないでください。
#   「make_linear_dimension」または「make_linear_dimension_obj」のいずれかを使用してください。
import FreeCAD
import Part
import DraftTools
import Draft
import Mesh
############################################################################
# ver0.3 xy平面の最初からわかってアポロニウスの円でwikipediaの公式で
from sympy import *
var('m,n')
A,B=map(Point,[(0,-1),(sqrt(3),0)])
print("#",((-n*A+m*B)/(m-n))                     .subs({m:2**2,n:1**2}))
print("#",( abs((m*n)/(m**2-n**2))*A.distance(B)).subs({m:2,n:1}))
# Point2D(4*sqrt(3)/3, 1/3)
# 4/3
############################################################################
O=Point(0,0)
M=((-n*A+m*B)/(m-n))                     .subs({m:2**2,n:1**2})
r=(abs((m*n)/(m**2-n**2))*A.distance(B)).subs({m:2,n:1})
############################################################################
# 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平面に作図しました。
############################################################################
# 円の作図 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
##################################################################################
myCircle_2D   (Circle(M,r))
myLine_S_2D     (A,B)  
#
myFontsize =0.2
myTxtXYZ_XY_S_2D(myFontsize,O,"O",A,"A",B,"B",M,"M")
#
myOvershoot=myFontsize*3
myDimension(myFontsize,myOvershoot,M,M+Point(r,0),"HL")
####################################################################################
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

上空からです。
・寸法表示を勉強中です。分数4/3の表示へ。√も
222.png

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

(テンプレート)

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

ver0.1

>仮に軌跡がまったくイメージできなかったとした(私)
>先ずやるべき変形は両辺2乗する事
>アポロニウスの円というものになります。
zが、左辺と右辺に別れているので、
左辺(一方)に集めたら何か見えてくるかもしれない。(?zについて解く)

ver0.2

class sympy.geometry.ellipse.Circle(*args, **kwargs)
https://docs.sympy.org/latest/modules/geometry/ellipses.html#sympy.geometry.ellipse.Circle
>A circle can be constructed from an equation in the form
>a*x**2+by*2+gx+hy+c=0,too:

ver0.3

>もし知らなけければ、これを機会に復習?するといいでしょう。
>すぐに答えを出していいと思います。
 m, n を互いに異なる正の実数とする。
 線分ABを m : n に内分する点を Q、外分する点をRとすると、
 アポロニウスの円の中心
 アポロニウスの円の半径
 <https://ja.wikipedia.org/wiki/アポロニウスの円#アポロニウスの円の中心

ver0.4

・class sympy.functions.elementary.complexes.conjugate(arg)
https://docs.sympy.org/latest/modules/functions/elementary.html#sympy.functions.elementary.complexes.conjugate

arbitrary_point(parameter='t')
https://docs.sympy.org/latest/modules/geometry/lines.html#sympy.geometry.line.LinearEntity.arbitrary_point
arbitrary_point(parameter='t')
https://docs.sympy.org/latest/modules/geometry/ellipses.html#sympy.geometry.ellipse.Ellipse.arbitrary_point

sympy.plotting.plot.plot_parametric(*args, show=True,**kwargs)
https://docs.sympy.org/latest/modules/plotting.html#sympy.plotting.plot.plot_parametric

Qiita内

arairuca 様。いつもお世話になっております。

出題範囲(単元)

Youtube

UFOキャッチャーとスイカ割り」私は、複素数平面を始めました。
 Masaki Koga [数学解説] 様
 複素数の極形式[数学III 複素数平面9(高校数学理論講座)] 
 UFOキャッチャーとスイカ割り(1:45〜) https://youtu.be/7aXWIB9mFfc?t=105
 フル             (0:00〜15:39) https://youtu.be/7aXWIB9mFfc
スイカの位置は、実部虚部座標系です。>UFOキャッチャー
>Masaki Koga [数学解説] 様より
「極形式はスイカ割り」厳密言うとチョット違う... 
>教科書と違う複素数の定義...
「スイカ割り理論?」でいくと、今回同時にスイカ割りを開始(移動なし)。AさんとBさんの腕(棒)の長さの比が決まっていて、スイカを並べたら、スイカが円状に配置されました。非日常です。
複素数平面は、もしかして学習指導要領の 単元「数学と人間の活動」 に関連するかも。毎日する活動では,ないです。

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?