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?

アフィン変換行列(3/4)「(AI先生へ)正三角形の頂点求め方について、多くの解法を教えて下さい。」を聞きました。

Last updated at Posted at 2025-03-04

4部作 アフィン変換行列 上のタグと同じです。

ChatGPT先生へ

・質問リストの追番は無視して下さい。1個ずつです。途中の回答表示は省略しています。

# 質問リスト
1. 正三角形の2つの頂点(Ax,Ay)と(Bx,By)がわかっていて、第3の頂点を求めたい。多くの解法を教えて下さい。  
2. 上記のまとめの表の1列目に、方法の追番を追加して下さい。  
3. 上記の表の見出しを、 # →方法 へ 方法→名称 に変更して下さい。  
4. 上記の表を、Markdown形式のソースコードを教えて下さい。  
5. 私の質問をMarkdown形式でリスト化して出力して。Markdown形式でリストからアスタリスクは削除して。1行目に、# 質問リスト の文字を出力して。  
上記の5つの方法を、sympyのソースコードで教えて下さい。

・(枝分かれ?) 以下1~5を順番に繰り返しました。

上記の方法1を、sympyのソースコードで教えて下さい。

目次

方法 名称 概要 特徴
1 ベクトル回転 ( AB ) を ( 60^\circ ) 回転 計算が直感的でプログラムしやすい
2 中点と高さ 中点から垂直方向に高さを加える 幾何的に分かりやすい
3 極座標 角度を利用して回転 三角関数を使うがシンプル
4 複素数 複素数の回転を利用 数式が簡潔で実装しやすい
5 連立方程式 距離条件から求める 計算が長いが理論的に確実

ChatGPT の回答は必ずしも正しいとは限りません。重要な情報は確認するようにしてください。
(回答抜粋)

方法1.ベクトル回転

import sympy as sp

def rotate_point(x, y, cx, cy, angle):
    """
    点(x, y)を(cx, cy)を中心にangleだけ回転する。
    """
    angle = sp.rad(angle)  # 角度をラジアンに変換
    cos_theta = sp.cos(angle)
    sin_theta = sp.sin(angle)
    
    x_new = cx + (x - cx) * cos_theta - (y - cy) * sin_theta
    y_new = cy + (x - cx) * sin_theta + (y - cy) * cos_theta
    
    return sp.simplify(x_new), sp.simplify(y_new)

def equilateral_triangle_vertices(ax, ay, bx, by):
    """
    正三角形の3つ目の頂点を求める。
    """
    # 60度回転(反時計回り)
    cx1, cy1 = rotate_point(bx, by, ax, ay, 60)
    
    # -60度回転(時計回り)
    cx2, cy2 = rotate_point(bx, by, ax, ay, -60)
    
    return (cx1, cy1), (cx2, cy2)

# シンボリック変数の定義
Ax, Ay, Bx, By = sp.symbols('Ax Ay Bx By')
C1, C2 = equilateral_triangle_vertices(Ax, Ay, Bx, By)

# 結果を表示
print("第3の頂点(反時計回り):", C1)
print("第3の頂点(時計回り):", C2)

方法2.中点と高さ

import sympy as sp

def find_equilateral_triangle_vertices(A, B):
    x1, y1 = A
    x2, y2 = B
    
    # 中点 M
    Mx, My = (x1 + x2) / 2, (y1 + y2) / 2
    
    # AB の長さ
    d = sp.sqrt((x2 - x1)**2 + (y2 - y1)**2)
    
    # 正三角形の高さ h
    h = (sp.sqrt(3) / 2) * d
    
    # AB に垂直なベクトル (u, v)
    u, v = -(y2 - y1) / d, (x2 - x1) / d
    
    # 2つの C の座標を求める
    C1 = (Mx + h * u, My + h * v)
    C2 = (Mx - h * u, My - h * v)
    
    return C1, C2

# 例: A(0, 0), B(2, 0) の場合
A = (0, 0)
B = (2, 0)
C1, C2 = find_equilateral_triangle_vertices(A, B)

print("第3の頂点の候補:")
print("C1:", C1)
print("C2:", C2)

方法3.極座標

from sympy import symbols, cos, sin, atan2, pi, simplify

# 点 A, B の座標
x1, y1 = symbols('x1 y1')
x2, y2 = symbols('x2 y2')

# AB の長さ
d = ((x2 - x1)**2 + (y2 - y1)**2)**0.5

# AB の傾き
theta = atan2(y2 - y1, x2 - x1)

# 第3の頂点 C の座標(反時計回り)
x3_1 = x1 + d * cos(theta + pi/3)
y3_1 = y1 + d * sin(theta + pi/3)

# 第3の頂点 C の座標(時計回り)
x3_2 = x1 + d * cos(theta - pi/3)
y3_2 = y1 + d * sin(theta - pi/3)

# 結果を簡単にする
x3_1, y3_1 = simplify(x3_1), simplify(y3_1)
x3_2, y3_2 = simplify(x3_2), simplify(y3_2)

# 出力
(x3_1, y3_1), (x3_2, y3_2)

方法4.複素数

from sympy import symbols, I, exp, pi, simplify

# A, B の座標をシンボルとして定義
Ax, Ay, Bx, By = symbols('Ax Ay Bx By')

# A, B を複素数として表現
zA = Ax + Ay * I
zB = Bx + By * I

# 60度回転の複素数表現
rotation = exp(I * pi / 3)  # e^(iπ/3) = cos(60°) + i*sin(60°)

# C の座標を計算(時計回りと反時計回り)
zC1 = zA + (zB - zA) * rotation  # 反時計回り
zC2 = zA + (zB - zA) * exp(-I * pi / 3)  # 時計回り

# 実数部分と虚数部分を取り出して C の座標を求める
C1x, C1y = simplify(zC1.expand().as_real_imag())  # 反時計回り
C2x, C2y = simplify(zC2.expand().as_real_imag())  # 時計回り

# 結果を表示
print(f"反時計回りの C の座標: ({C1x}, {C1y})")
print(f"時計回りの C の座標: ({C2x}, {C2y})")

方法5.連立方程式

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

# 頂点A, Bの座標を定義
A_x, A_y = 1, 2  # Aの座標
B_x, B_y = 4, 6  # Bの座標

# Cの座標を変数として定義
x, y = symbols('x y')

# 点A, B, Cの距離が等しいという条件
eq1 = Eq((x - A_x)**2 + (y - A_y)**2, (x - B_x)**2 + (y - B_y)**2)

# 正三角形なので、面積が一致することも考慮して、ABの長さを計算
# 点A, Bの距離
AB = ((B_x - A_x)**2 + (B_y - A_y)**2)**0.5
# ABを底辺とした三角形の高さを求める(面積から高さを求める)
height = (3**0.5 / 2) * AB

# 中点Mを求める
M_x = (A_x + B_x) / 2
M_y = (A_y + B_y) / 2

# Cの座標が中点Mから垂直方向に高さだけずれることを考慮
# Cの座標を求めるために、この垂直方向ベクトルを求める
eq2 = Eq((x - M_x)**2 + (y - M_y)**2, height**2)

# 連立方程式を解く
solutions = solve((eq1, eq2), (x, y))

# 解を表示
print(solutions)

Gemini先生へ

copilot先生へ

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

(テンプレート)

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

wikipdia内

Qiit内

google検索

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?