我正在嘗試生成一個直角三角形,斜邊 = 1,內角為 25,底邊旋轉 30 度。我已經按照我的理解正確輸入了觸發公式,并且我懷疑存在某種舍入錯誤。因為 matplot 中生成的三角形與直角三角形略有偏差。
import math
import matplotlib.pyplot as plt
from annotation import label
angle_b = math.radians(25) # the interior 25 degree angle of our right triangle
angle_a = math.radians(30) # 30 degree angle between the plotted angle_b triangle base and the x axis.
point_A = (0,0)
point_B = (math.cos(angle_a angle_b), math.sin(angle_a angle_b))
point_C = (math.cos(angle_a) * math.cos(angle_b), math.sin(angle_a) * math.cos(angle_b))
# Label our points
label(plt, 'A', point_A)
label(plt, 'B', point_B)
label(plt, 'C', point_C)
# Draw the right triangle between our points.
plt.plot(*zip(point_A, point_B, point_C, point_A), marker='o', color='black')

如您所見,角度 ACB 不是
現在解決了。由于線路,我終于讓它作業了ax.set_aspect('equal')

uj5u.com熱心網友回復:
問題是默認情況下,matplotlib 在 x 和 y 方向上不使用相同的距離。相反,matplotlib 嘗試將所有內容很好地適應給定的邊界。
這些不均勻的距離會扭曲角度,也會使圓變形。
您可以通過 強制相同的縱橫比ax.set_aspect('equal')。
要通過角度計算位置,并在 B 點獲得右角,您需要考慮長度 AC 是cos(b)AC 長度的倍。AC 可以選擇長度為 1。或者,您可以將 B 和 C 除以cos(b)得到一個更大的三角形,其中 AB 的長度將為 1。
import matplotlib.pyplot as plt
import math
angle_b = math.radians(25) # the interior 25 degree angle of our right triangle
angle_a = math.radians(30) # 30 degree angle between the plotted angle_b triangle and the x axis.
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(14, 5), sharey=True)
for ax in (ax1, ax2):
point_A = (0, 0)
if ax == ax1:
point_B = (math.cos(angle_a angle_b) * math.cos(angle_b), math.sin(angle_a angle_b) * math.cos(angle_b))
point_C = (math.cos(angle_a), math.sin(angle_a))
ax.set_title('length AC is 1')
else:
point_B = (math.cos(angle_a angle_b), math.sin(angle_a angle_b))
point_C = (math.cos(angle_a) / math.cos(angle_b), math.sin(angle_a) / math.cos(angle_b))
ax.set_title('length AB is 1')
point_M = ((point_A[0] point_C[0]) / 2, (point_A[1] point_C[1]) / 2)
# Draw the right triangle between our points.
ax.plot(*zip(point_A, point_B, point_C, point_A), marker='o', color='black')
# draw a circle around the 3 points
ax.add_patch(plt.Circle(point_M, math.sqrt((point_M[0] - point_A[0]) ** 2 (point_M[1] - point_A[1]) ** 2),
ec='r', ls='--', fc='none'))
ax.set_aspect('equal', 'datalim')
plt.show()

相同的計算適用于任何角度。以下是 12 次以 30 度為步長旋轉的情況:

下面的代碼展示ax.set_aspect('equal')了原點的效果。
import matplotlib.pyplot as plt
import math
angle_b = math.radians(25) # the interior 25 degree angle of our right triangle
angle_a = math.radians(30) # 30 degree angle between the plotted angle_b triangle and the x axis.
point_A = (0, 0)
point_B = (math.cos(angle_a angle_b), math.sin(angle_a angle_b))
point_C = (math.cos(angle_a) * math.cos(angle_b), math.sin(angle_a) * math.cos(angle_b))
point_M = ((point_A[0] point_B[0]) / 2, (point_A[1] point_B[1]) / 2)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(16, 4), gridspec_kw={'width_ratios': [2, 1]})
for ax in (ax1, ax2):
# Draw the right triangle between our points.
ax.plot(*zip(point_A, point_B, point_C, point_A), marker='o', color='black')
# draw a circle around the 3 points
ax.add_patch(plt.Circle(point_M, math.sqrt((point_M[0] - point_A[0]) ** 2 (point_M[1] - point_A[1]) ** 2),
ec='r', ls='--', fc='none'))
ax1.set_title('Default aspect ratio, deforms the angles')
ax2.set_aspect('equal') # or plt.axis('equal')
ax2.set_title('Equal aspect ratio')
plt.tight_layout()
plt.show()

uj5u.com熱心網友回復:
你似乎把三角函式搞亂了。我將建議一步一步地緩慢移動,并使用變數名稱來幫助您記住正在發生的事情。
讓我們從原始三角形開始。如果interior_angle = np.deg2rad(25)且斜邊的長度為1,則 x 軸上的(np.cos(interior_angle), 0)直角為 ,另一個內角為(np.cos(interior_angle), np.sin(interior_angle))。圖中的兩點都不對應。
現在讓我們將三角形表示為一個矩陣,其列是頂點:
interior_angle = np.deg2rad(25)
vertices = np.array([
[0, np.cos(interior_angle), np.cos(interior_angle), 0],
[0, 0, np.sin(interior_angle), 0],
])
最后一個頂點是原點的重復,使繪圖更容易。
現在讓我們看看旋轉。對于rotation_angle = np.deg2rad(30),點(x, y)旋轉到(np.cos(rotation_angle) * x - np.sin(rotation_angle) * y, np.sin(rotation_angle) * x np.cos(rotation_angle) * y)。這可以表示為一個矩陣方程:
rotation_matrix = np.array([
[np.cos(rotation_angle), -np.sin(rotation_angle)],
[np.sin(rotation_angle), np.cos(rotation_angle)]])
p_out = rotation_matrix @ p_in
該陣列vertices的構造使其可以直接與旋轉矩陣相乘。因此你可以寫
rotation_angle = np.deg2rad(30)
rotation_matrix = np.array([
[np.cos(rotation_angle), -np.sin(rotation_angle)],
[np.sin(rotation_angle), np.cos(rotation_angle)]])
rotated_vertices = rotation_matrix @ vertices
繪制的影像現在應該更有意義:
plt.plot(*vertices)
plt.plot(*rotated_vertices)
plt.axis('equal')
plt.show()

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/362619.html
標籤:Python matplotlib 数学 几何学 三角学
上一篇:如何填充圖的下部直到指定范圍
