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の実行環境と 参考のおすすめです。