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?

高校入試平面図形 相似「2024 千葉県高校入試 数学大問3(3)」をsympyとFreeCADでやってみたい。(その2/2) 垂心

Last updated at Posted at 2024-09-11

・良いように言えば、見直しのため。youtubeに私のコメントが多数あります。
・普通に言えば、半年前に投稿した事を、スッカリ忘れていました。

・今回、垂心について調べました。垂心を意識してです。
 垂心と外接円(正弦定理)とつながっていました。wikipedaより
https://ja.wikipedia.org/wiki/垂心#性質
ChatGPT先生へ「sympyで外心の計算できるのに、垂心の計算できないのはなぜですか。」(抜粋)
https://qiita.com/mrrclb48z/items/4b7c8b30aafc0705e399

・以下バージョン番号を2にしています。同じ間違い?もそのまま載せています。

(再)オリジナル

数学を数楽に 様 
youtube (10:11) 大問3(3)

sympyで

ver2.1 sympyのangle_betweenで

・半年前になぜやらなかったのか不思議?第一感のような気がします。
・点Bの座標が決まってしまえば、あとは飾り?です。
 原点は点D、点A(9,0),角Bが45°

angle_between(l2)
https://docs.sympy.org/latest/modules/geometry/lines.html#sympy.geometry.line.LinearEntity.angle_between
property orthocenter
https://docs.sympy.org/latest/modules/geometry/polygons.html#sympy.geometry.polygon.Triangle.orthocenter

# ver2.1 sympyのangle_betweenで
from sympy import *
var('By',real=True,positive=True)
C,D,A,B=map(Point,[(-6,0),(0,0),(9,0),(0,By)]) 
B=Point(0,solve(Eq(Line(B,C).angle_between(Line(B,A)),rad(45)),By)[0])
# 
E=Line(A,B).projection(C)
F=Line(B,D).intersection(Line(C,E))[0]
print("#",Triangle(E,B,F).area)
# 45
# おまけ
print("#",F)   #Dが原点です。
print("#",Triangle(A,B,C).orthocenter)
print("#",Triangle(A,B,C).circumradius,float(Triangle(A,B,C).circumradius))
# Point2D(0, 3)
# Point2D(0, 3)
# 15*sqrt(2)/2 10.606601717798213

ver2.2 正弦定理,外接円と直線の交点計算で

・原点は、点D、点A(9,0)

# ver2.2 正弦定理,外接円と直線の交点計算で
from sympy import *
var('r',real=True,positive=True)
AD,DC,degB=9,6,45
r=solve(Eq((AD+DC)/sin(rad(degB)),2*r),r)[0]
C,D,A=map(Point,[(-6,0),(0,0),(9,0)]) 
M=Circle(C,r).intersection(Circle(A,r))[1]
B=Circle(M,r).intersection(Line(D,A).perpendicular_line(D))[1]
E=Line(A,B).projection(C)
F=Line(B,D).intersection(Line(C,E))[0]
print("#",Triangle(E,B,F).area)
# 45

NotImplementedError。ver2.3 正弦定理,余弦定理の組み合わせで

# NotImplementedError。ver2.3 正弦定理,余弦定理の組み合わせで
from sympy import *
var('r,degA,degC',real=True,positive=True)
AD,DC,degB=9,6,45
r=solve(Eq((AD+DC)/sin(rad(degB)),2*r),r)[0]
AB,BC=2*r*sin(rad(degC)),2*r*sin(rad(degA))
sol=solve([Eq(degA+degB+degC,180),Eq(AB**2+BC**2-2*AB*BC*cos(rad(degB)),(AD+DC)**2)],[degA,degC])
print(sol)
# NotImplementedError: could not solve 450*sin(pi*degC/180)**2 (以下省略)

終了しませんでした。ver2.4 点Bを原点にして計算。sympyのprojectionnで.

# 終了しませんでした。ver2.4 点Bを原点にして計算。sympyのprojectionnで.
from sympy import *
var('BC,degC',real=True,positive=True)
AD,DC,degB=9,6,45
B=  Point( 0,0)
C=  Point(BC,0)
A=C+Point((AD+DC)*cos(rad(pi-degC)),(AD+DC)*sin(rad(pi-degC)))
D=Line(A,C).projection(B)
sol=solve([Eq(Line(B,B+Point(1,0)).angle_between(Line(B,A)),rad(45)),Eq(D.distance(C),DC)],[BC,degC])
print(sol)

ver2.5 直径BCの半円が見えます。(省略)

・点E,点Dが、半円上に見えますがが、座標計算では、点E点Fは飾りでした。
 ただし、点Fは、合同及び相似では、正弦定理および垂心のの公式で、大活躍します。

ver2.6 垂心の座標計算の行列式使用。 B=tan45°よりBF=AD+DC=15

・ここまでくると、何でもありに見えてきました。
https://ja.wikipedia.org/wiki/垂心#垂心の座標

# ver2.6 垂心の座標計算の行列式使用。 B=tan45°よりBF=AD+DC=15
from sympy import *
AD,DC=9,6
var('By', real=True)
def myOrthocenter(triangle):
    A, B, C = triangle.vertices
    x1, y1 = A.x, A.y
    x2, y2 = B.x, B.y
    x3, y3 = C.x, C.y
    det_D = Matrix([
        [x1, y1, 1],
        [x2, y2, 1],
        [x3, y3, 1]
    ]).det()
    H_x = Matrix([
        [-x2*x3-y1**2, y1, 1],
        [-x1*x3-y2**2, y2, 1],
        [-x1*x2-y3**2, y3, 1]
    ]).det() / (det_D)
    H_y = Matrix([
        [x1, -x1**2-y2*y3, 1],
        [x2, -x2**2-y1*y3, 1],
        [x3, -x3**2-y1*y2, 1]
    ]).det() / (det_D)
    return H_x, H_y
A,B,C=map(Point,[(9,0),(0,By),(-6, 0)])  
sol=solve(Eq(By-myOrthocenter(Triangle(A, B, C))[1],(AD+DC)),By)[1] 
B  =Point(0,sol)  
F  =Point(0,sol-(AD+DC))
E  =Line(A,B).projection(C)
print("#",Triangle(E,B,F).area)
# 45

ver2.7 点Bを原点にして計算。

・あきらめました。

FreeCADのマクロで作図

・計算部分は、ver2.2のコピー貼り付けです。

import FreeCAD
import Part
import DraftTools
import Draft
import Mesh
############################################################################
# ver2.2 正弦定理,外接円と直線で
# 原点は、点D、点A(9,0)
from sympy import *
var('r',real=True,positive=True)
AD,DC,degB=9,6,45
r=solve(Eq((AD+DC)/sin(rad(degB)),2*r),r)[0]
C,D,A=map(Point,[(-6,0),(0,0),(9,0)]) 
M=Circle(C,r).intersection(Circle(A,r))[1]
B=Circle(M,r).intersection(Line(D,A).perpendicular_line(D))[1]
E=Line(A,B).projection(C)
F=Line(B,D).intersection(Line(C,E))[0]
print("#",Triangle(E,B,F).area)
# 45
###########################################################################
############################################################################
# 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_C_2D        (A,B,C,D)  
myTxtXYZ_XY_S_2D   (M,"M",A,"A",B,"B",C,"C",D,"D")
myTxtXYZ_XY_S_2D   (E,"E",F,"F")
myLine_S_2D        (C,E)
myLine_S_2D        (B,D)
####################################################################################
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")

問題文は2次元ですが、3次元FreeCADのマクロで、XY平面上に作図しました。
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?