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?

ChatGPT-3.5先生へ「sympyで外心の計算できるのに、垂心の計算できないのはなぜですか。」(抜粋)

Last updated at Posted at 2024-09-09

・正しくは、以下でした。そのままです。再質問は、していません。
 「sympyで外心の計算できるのに、垂心の計算できないのはなぜですか。」
      ↓
 「sympyで外心の計算できるのに、垂心の計算できないのはなぜですか。」
・改行を挿入していません。
 申し訳ありません。

パイソニスタの方へ
・垂心の行列式のベスト?な質問の仕方をコメントいただけたら幸いです。

property circumcenter
The circumcenter of the triangle
The circumcenter is the center of the circumcircle.

property orthocenter
The orthocenter of the triangle.
The orthocenter is the intersection of the altitudes of a triangle. It may lie inside, outside or on the triangle.

1回目

・具体的な値はもちろん、外心、垂心ともOKです。

User

from sympy import *
var('Ax,Ay,Bx,By,Cx,Cy',real=True)
A,B,C=map(Point,[(Ax,Ay),(Bx,By),(Cx,Cy)])
print("#",Triangle(A,B,C).circumcenter)
print("#",Triangle(A,B,C).orthocenter)
外心の計算できるのに、垂心の計算できないのはなぜですか。

ChatGPT

SymPy の最新版では、orthocenter は正常に計算できるはずです。もし計算できない場合は、以下の点を確認してみてください:
...(省略)
SymPy の最新版のバージョンを教えて下さい。

ChatGPT

The latest version of SymPy is 1.13.0, which was released in early July 2023. You can check out the detailed release notes on their GitHub page for more information about new features and improvements​(

あきらめました。

2回目(projection)

・slopeは、y軸方向に望ましくありません。
 無限大のテストは、していません。

User

sympyで垂心の計算を、Lineのprojectionで計算する方法を教えて下さい。

以下途中省略

ユーザー定義関数でお願いします。
引数は、Triangleでお願いします。
from sympy import Point, Line, Triangle

# 垂心を計算するユーザー定義関数 (引数は Triangle)
def calculate_orthocenter(triangle):
    """
    Triangle オブジェクトを引数として、三角形の垂心を計算します。
    
    :param triangle: SymPy の Triangle オブジェクト
    :return: 垂心の座標を表す Point オブジェクト
    """
    
    # 三角形の頂点を取得
    A, B, C = triangle.vertices
    
    # 三角形の辺を定義
    line_BC = Line(B, C)
    line_CA = Line(C, A)
    
    # 各頂点から対辺への射影を求める
    proj_A_on_BC = line_BC.projection(A)
    proj_B_on_CA = line_CA.projection(B)
    
    # 頂点から対辺に下ろした垂線を定義
    line_A_proj = Line(A, proj_A_on_BC)
    line_B_proj = Line(B, proj_B_on_CA)
    
    # 垂線の交点を求め、これが垂心
    orthocenter = line_A_proj.intersection(line_B_proj)[0]
    
    return orthocenter

# 座標変数の定義
from sympy import symbols
x1, y1, x2, y2, x3, y3 = symbols('x1 y1 x2 y2 x3 y3')

# 三角形の頂点を定義
A = Point(x1, y1)
B = Point(x2, y2)
C = Point(x3, y3)

# Triangle オブジェクトの生成
triangle = Triangle(A, B, C)

# 垂心の計算
orthocenter = calculate_orthocenter(triangle)

# 結果を表示
orthocenter
実行しましたが、終了しません。
修正したユーザー定義関数の例
from sympy import Point, Line, Triangle, solve, Eq

# 垂心を計算するユーザー定義関数 (引数は Triangle)
def calculate_orthocenter(triangle):
    """
    Triangle オブジェクトを引数として、三角形の垂心を計算します。
    
    :param triangle: SymPy の Triangle オブジェクト
    :return: 垂心の座標を表す Point オブジェクト
    """
    
    # 三角形の頂点を取得
    A, B, C = triangle.vertices
    
    # 三角形の辺を定義
    line_BC = Line(B, C)
    line_CA = Line(C, A)
    
    # 辺BCの法線方向の直線の方程式を求める (Aを通る垂線)
    slope_BC = line_BC.slope
    slope_perpendicular_to_BC = -1 / slope_BC  # BCに垂直な直線の傾き
    line_A_perpendicular = Line(A, slope=slope_perpendicular_to_BC)  # Aを通る直線
    
    # 同様に辺CAに垂直なBを通る直線
    slope_CA = line_CA.slope
    slope_perpendicular_to_CA = -1 / slope_CA
    line_B_perpendicular = Line(B, slope=slope_perpendicular_to_CA)
    
    # 2つの垂線の交点を求める(垂心)
    orthocenter = line_A_perpendicular.intersection(line_B_perpendicular)[0]
    
    return orthocenter

# 座標変数の定義
from sympy import symbols
x1, y1, x2, y2, x3, y3 = symbols('x1 y1 x2 y2 x3 y3')

# 三角形の頂点を定義
A = Point(x1, y1)
B = Point(x2, y2)
C = Point(x3, y3)

# Triangle オブジェクトの生成
triangle = Triangle(A, B, C)

# 垂心の計算
orthocenter = calculate_orthocenter(triangle)

# 結果を表示
orthocenter

結果がででました。

GPT-4o. の Free プランの制限に達しました。

以上未確認です。

???何か勘違い 3回目

User

垂心の計算を、sympyの行列を使って計算する方法を教えて下さい。
ユーザー定義関数で。引数はsympyのTriangeでお願いします。
from sympy import symbols, Matrix, Eq, solve
from sympy.geometry import Triangle

def calculate_orthocenter(triangle: Triangle):
    # 三角形の頂点を取得
    A, B, C = triangle.vertices

    # 頂点の座標を取得
    x1, y1 = A
    x2, y2 = B
    x3, y3 = C

    # 三角形の辺の中点を計算
    def midpoint(p1, p2):
        return ((p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2)

    # 辺ABとACの中点
    M1 = midpoint(A, B)
    M2 = midpoint(A, C)

    # 辺ABとACのベクトル
    AB = Matrix([x2 - x1, y2 - y1])
    AC = Matrix([x3 - x1, y3 - y1])

    # ABとACの法線ベクトル(垂直ベクトル)
    normal1 = Matrix([-AB[1], AB[0]])
    normal2 = Matrix([-AC[1], AC[0]])

    # 垂直二等分線の方程式を作成
    def perpendicular_bisector(p, normal):
        return Eq(normal[0] * symbols('x') + normal[1] * symbols('y') - (normal[0] * p[0] + normal[1] * p[1]), 0)

    eq1 = perpendicular_bisector(M1, normal1)
    eq2 = perpendicular_bisector(M2, normal2)

    # 方程式を解く
    x, y = symbols('x y')
    solution = solve((eq1, eq2), (x, y))

    return solution

# 使用例
triangle = Triangle((0, 0), (1, 0), (0, 1))
orthocenter = calculate_orthocenter(triangle)
print(orthocenter)

3回目の続き

垂心と外心を間違っていませんか?垂心でお願いします。

おっしゃる通りです、(途中省略)
垂心の計算コード

from sympy import symbols, Eq, solve
from sympy.geometry import Triangle, Point

def calculate_orthocenter(triangle: Triangle):
    # 三角形の頂点を取得
    A, B, C = triangle.vertices

    # 頂点の座標を取得
    x1, y1 = A
    x2, y2 = B
    x3, y3 = C

    # 各辺に対する高さの方程式を作成する関数
    def altitude_equation(p1, p2, p3):
        # 辺p1p2に対する高さの方程式を作成
        dx1, dy1 = p2[0] - p1[0], p2[1] - p1[1]
        a, b = -dy1, dx1
        c = a * p1[0] + b * p1[1]
        return Eq(a * symbols('x') + b * symbols('y'), c)
    
    # 各頂点に対する高さの方程式
    eq1 = altitude_equation(B, C, A)
    eq2 = altitude_equation(A, C, B)
    
    # 方程式を解く
    x, y = symbols('x y')
    orthocenter = solve((eq1, eq2), (x, y))

    return orthocenter

# 使用例
triangle = Triangle(Point(0, 0), Point(1, 0), Point(0, 1))
orthocenter = calculate_orthocenter(triangle)
print(orthocenter)

3回目の続きの続き

行列を使って下さい。
from sympy import Matrix, symbols, Eq, solve
from sympy.geometry import Triangle, Point

def calculate_orthocenter(triangle: Triangle):
    # 三角形の頂点を取得
    A, B, C = triangle.vertices

    # 頂点の座標を取得
    x1, y1 = A
    x2, y2 = B
    x3, y3 = C

    # 各辺の直線方程式の係数を計算する関数
    def line_equation(p1, p2):
        a = p2[1] - p1[1]
        b = p1[0] - p2[0]
        c = a * p1[0] + b * p1[1]
        return a, b, -c

    # 辺AB, BC, CAの直線方程式の係数
    a1, b1, c1 = line_equation(A, B)  # AB
    a2, b2, c2 = line_equation(B, C)  # BC
    a3, b3, c3 = line_equation(C, A)  # CA

    # 高さの直線方程式の係数を計算する関数
    def altitude_equation(p1, a, b, c):
        # 頂点p1からの高さの方程式を作成
        a_perp = b
        b_perp = -a
        c_perp = a_perp * p1[0] + b_perp * p1[1]
        return a_perp, b_perp, -c_perp

    # 高さの直線方程式の係数
    a1_perp, b1_perp, c1_perp = altitude_equation(C, a1, b1, c1)  # 高さ from C
    a2_perp, b2_perp, c2_perp = altitude_equation(A, a2, b2, c2)  # 高さ from A

    # 高さの直線方程式の行列を作成
    matrix = Matrix([
        [a1_perp, b1_perp, c1_perp],
        [a2_perp, b2_perp, c2_perp]
    ])
    
    # 高さの交点を求める
    x, y = symbols('x y')
    eqs = [
        Eq(a1_perp * x + b1_perp * y + c1_perp, 0),
        Eq(a2_perp * x + b2_perp * y + c2_perp, 0)
    ]
    
    # 行列と方程式を解く
    solution = solve(eqs, (x, y))

    return solution

# 使用例
triangle = Triangle(Point(0, 0), Point(1, 0), Point(0, 1))
orthocenter = calculate_orthocenter(triangle)
print(orthocenter)
行列式を使って下さい。

(私が行列と行列式を間違っていました。)

from sympy import Matrix, symbols, Eq, solve

def calculate_orthocenter(x1, y1, x2, y2, x3, y3):
    # 高さの直線方程式を作成するための変数
    X, Y = symbols('X Y')
    
    # 各辺の直線方程式の係数を計算する関数
    def line_equation(x1, y1, x2, y2):
        a = y2 - y1
        b = x1 - x2
        c = a * x1 + b * y1
        return a, b, -c

    # 辺AB, BC, CAの直線方程式の係数
    a1, b1, c1 = line_equation(x1, y1, x2, y2)  # AB
    a2, b2, c2 = line_equation(x2, y2, x3, y3)  # BC
    a3, b3, c3 = line_equation(x3, y3, x1, y1)  # CA

    # 高さの直線方程式の係数を計算する関数
    def altitude_equation(x1, y1, a, b, c):
        # 頂点(x1, y1)からの高さの方程式を作成
        a_perp = b
        b_perp = -a
        c_perp = a_perp * x1 + b_perp * y1
        return a_perp, b_perp, -c_perp

    # 高さの直線方程式の係数
    a1_perp, b1_perp, c1_perp = altitude_equation(x3, y3, a1, b1, c1)  # 高さ from (x3, y3)
    a2_perp, b2_perp, c2_perp = altitude_equation(x1, y1, a2, b2, c2)  # 高さ from (x1, y1)

    # 行列式を使って交点を計算する
    matrix = Matrix([
        [a1_perp, b1_perp, c1_perp],
        [a2_perp, b2_perp, c2_perp]
    ])
    
    # 高さの交点を求めるための方程式
    determinant = Matrix([
        [a1_perp, b1_perp, c1_perp],
        [a2_perp, b2_perp, c2_perp],
        [1, 1, 1]
    ]).det()

    if determinant == 0:
        raise ValueError("The heights are parallel or coincident, no unique intersection.")

    # 交点の座標を求めるための方程式
    equations = [
        Eq(a1_perp * X + b1_perp * Y + c1_perp, 0),
        Eq(a2_perp * X + b2_perp * Y + c2_perp, 0)
    ]
    
    # 方程式を解く
    solution = solve(equations, (X, Y))

    return solution

# 使用例
orthocenter = calculate_orthocenter(0, 0, 1, 0, 0, 1)
print(orthocenter)

私がくたびれてたので、終了です。

4回目

垂心を直接行列式のみで計算する方法を教えて下さい
sympyのユーザー定義関数のソースコードで

(未確認です。)

import sympy as sp
from sympy.geometry import Triangle

def orthocenter(triangle):
    """
    SymPyのTriangleクラスを使って三角形の垂心を計算する関数
    :param triangle: SymPyのTriangleクラスのインスタンス
    :return: (H_x, H_y) 垂心の座標
    """
    # 三角形の頂点を取得
    A, B, C = triangle.vertices
    x1, y1 = A.x, A.y
    x2, y2 = B.x, B.y
    x3, y3 = C.x, C.y
    
    # Dの行列式
    det_D = sp.Matrix([
        [x1, y1, 1],
        [x2, y2, 1],
        [x3, y3, 1]
    ]).det()

    # H_x (x座標) の計算
    H_x = sp.Matrix([
        [x1**2 + y1**2, y1, 1],
        [x2**2 + y2**2, y2, 1],
        [x3**2 + y3**2, y3, 1]
    ]).det() / (2 * det_D)

    # H_y (y座標) の計算
    H_y = sp.Matrix([
        [x1, x1**2 + y1**2, 1],
        [x2, x2**2 + y2**2, 1],
        [x3, x3**2 + y3**2, 1]
    ]).det() / (2 * det_D)

    return H_x, H_y

# 使用例: 三角形の頂点を定義して垂心を求める
A = sp.Point(0, 0)  # 頂点A
B = sp.Point(1, 0)  # 頂点B
C = sp.Point(0, 1)  # 頂点C

# Triangleクラスのインスタンスを作成
triangle = Triangle(A, B, C)

# 垂心を計算
H_x, H_y = orthocenter(triangle)

# 結果を表示
print(f"垂心の座標: H_x = {H_x}, H_y = {H_y}")

リンク

過去問 類題

”垂心” でサイト内検索

2024 大学入学共通テスト 追試験 数学I・数学【5】 
https://mathexamtest.web.fc2.com/2024/202410000/2024100000300mj.html#top-0309

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?