Python数学可视化——坐标系与变换
Python数学可视化——坐标系与变换
直角坐标与极坐标转换及几何变换
本节将实现坐标系变换可视化工具,包括直角坐标系与极坐标系的相互转换,以及几何变换(平移、旋转、缩放)的数学原理展示。最后通过行星轨道案例演示极坐标的实际应用。
一、核心概念与工具准备
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.projections import PolarAxes
import matplotlib.transforms as transforms
from matplotlib.figure import Figure
from matplotlib.patches import Circle, Ellipse
二、坐标系转换与变换工具
def plot_coordinate_systems(output_path="coordinate_systems.png"):"""可视化直角坐标系与极坐标系对比"""fig = plt.figure(figsize=(14, 6), dpi=120)# 直角坐标系ax1 = fig.add_subplot(121)ax1.set_aspect('equal')ax1.grid(True, linestyle='--', alpha=0.7)ax1.set_xlim(-5, 5)ax1.set_ylim(-5, 5)ax1.set_title("直角坐标系", fontsize=14, pad=15)ax1.set_xlabel('x', fontsize=12)ax1.set_ylabel('y', fontsize=12, rotation=0)# 添加网格点for x in range(-4, 5):for y in range(-4, 5):ax1.plot(x, y, 'bo', markersize=4, alpha=0.5)# 极坐标系ax2 = fig.add_subplot(122, projection='polar')ax2.set_theta_zero_location('E') # 0度方向朝右ax2.set_theta_direction(-1) # 顺时针方向ax2.set_rlim(0, 5)ax2.set_title("极坐标系", fontsize=14, pad=15)ax2.grid(True, linestyle='--', alpha=0.7)# 添加网格点for r in np.linspace(1, 4, 4):for theta in np.linspace(0, 2*np.pi, 16, endpoint=False):ax2.plot(theta, r, 'ro', markersize=4, alpha=0.5)plt.tight_layout(pad=3.0)plt.savefig(output_path, bbox_inches='tight')plt.close()print(f"坐标系对比图已保存至: {output_path}")def plot_coordinate_conversion(point, output_path="coordinate_conversion.png"):"""展示单个点的坐标转换过程"""fig = plt.figure(figsize=(12, 6), dpi=120)# 直角坐标系中的点ax1 = fig.add_subplot(121)ax1.set_aspect('equal')ax1.grid(True, linestyle='--', alpha=0.7)ax1.set_xlim(-6, 6)ax1.set_ylim(-6, 6)ax1.set_title(f"直角坐标: ({point[0]:.1f}, {point[1]:.1f})", fontsize=14)# 绘制点和坐标线ax1.plot([0, point[0]], [0, 0], 'b--', alpha=0.5)ax1.plot([point[0], point[0]], [0, point[1]], 'b--', alpha=0.5)ax1.plot(point[0], point[1], 'ro', markersize=8)# 极坐标系中的点r = np.sqrt(point[0]**2 + point[1]**2)theta = np.arctan2(point[1], point[0])ax2 = fig.add_subplot(122, projection='polar')ax2.set_theta_zero_location('E')ax2.set_theta_direction(-1)ax2.set_rlim(0, 6)ax2.set_title(f"极坐标: (r={r:.2f}, θ={np.degrees(theta):.1f}°)", fontsize=14)ax2.grid(True, linestyle='--', alpha=0.7)# 绘制点和坐标线ax2.plot([0, theta], [0, r], 'r-', linewidth=2)ax2.plot(theta, r, 'ro', markersize=8)plt.tight_layout(pad=2.0)plt.savefig(output_path, bbox_inches='tight')plt.close()print(f"坐标转换图已保存至: {output_path}")def plot_geometric_transformations(shape_points, output_path="transformations.png"):"""展示几何变换:平移、旋转、缩放"""fig, axes = plt.subplots(2, 2, figsize=(12, 10), dpi=120)fig.suptitle("几何变换可视化", fontsize=16, y=0.95)# 原始形状axes[0, 0].set_title("原始形状", fontsize=12)axes[0, 0].plot(shape_points[:, 0], shape_points[:, 1], 'bo-')axes[0, 0].set_xlim(-5, 5)axes[0, 0].set_ylim(-5, 5)axes[0, 0].grid(True, linestyle='--', alpha=0.7)axes[0, 0].set_aspect('equal')# 平移变换tx, ty = 2, 1.5translated = shape_points + [tx, ty]axes[0, 1].set_title(f"平移: ({tx}, {ty})", fontsize=12)axes[0, 1].plot(shape_points[:, 0], shape_points[:, 1], 'bo-', alpha=0.3)axes[0, 1].plot(translated[:, 0], translated[:, 1], 'ro-')axes[0, 1].set_xlim(-5, 5)axes[0, 1].set_ylim(-5, 5)axes[0, 1].grid(True, linestyle='--', alpha=0.7)axes[0, 1].set_aspect('equal')# 旋转变换 (30度)angle = np.radians(30)rotation_matrix = np.array([[np.cos(angle), -np.sin(angle)],[np.sin(angle), np.cos(angle)]])rotated = np.dot(shape_points, rotation_matrix.T)axes[1, 0].set_title(f"旋转: {np.degrees(angle):.0f}°", fontsize=12)axes[1, 0].plot(shape_points[:, 0], shape_points[:, 1], 'bo-', alpha=0.3)axes[1, 0].plot(rotated[:, 0], rotated[:, 1], 'go-')axes[1, 0].set_xlim(-5, 5)axes[1, 0].set_ylim(-5, 5)axes[1, 0].grid(True, linestyle='--', alpha=0.7)axes[1, 0].set_aspect('equal')# 缩放变换sx, sy = 1.5, 0.8scaled = shape_points * [sx, sy]axes[1, 1].set_title(f"缩放: ({sx}, {sy})", fontsize=12)axes[1, 1].plot(shape_points[:, 0], shape_points[:, 1], 'bo-', alpha=0.3)axes[1, 1].plot(scaled[:, 0], scaled[:, 1], 'mo-')axes[1, 1].set_xlim(-5, 5)axes[1, 1].set_ylim(-5, 5)axes[1, 1].grid(True, linestyle='--', alpha=0.7)axes[1, 1].set_aspect('equal')plt.tight_layout(pad=3.0)plt.savefig(output_path, bbox_inches='tight')plt.close()print(f"几何变换图已保存至: {output_path}")
三、天文案例:行星轨道可视化
def plot_planetary_orbit(a, e, output_path="planetary_orbit.png"):"""绘制行星轨道(椭圆)在极坐标系中的表示参数:a: 半长轴 (天文单位)e: 离心率 (0 < e < 1)"""# 计算轨道参数b = a * np.sqrt(1 - e**2) # 半短轴focal_distance = 2 * e * a # 焦点间距fig = plt.figure(figsize=(12, 6), dpi=130)# 直角坐标系视图ax1 = fig.add_subplot(121)ax1.set_aspect('equal')ax1.set_title("直角坐标系中的椭圆轨道", fontsize=14)ax1.set_xlabel('x (AU)')ax1.set_ylabel('y (AU)')# 绘制椭圆轨道theta = np.linspace(0, 2*np.pi, 300)r = a * (1 - e**2) / (1 + e * np.cos(theta))x = r * np.cos(theta)y = r * np.sin(theta)ax1.plot(x, y, 'b-', linewidth=1.8)# 标记焦点(太阳位置)ax1.plot([-focal_distance/2, focal_distance/2], [0, 0], 'ro', markersize=8)ax1.text(-focal_distance/2 - 0.2, 0.2, "太阳", fontsize=10)# 添加网格和标记ax1.grid(True, linestyle='--', alpha=0.6)ax1.set_xlim(-a*1.2, a*1.2)ax1.set_ylim(-b*1.2, b*1.2)# 极坐标系视图ax2 = fig.add_subplot(122, projection='polar')ax2.set_theta_zero_location('E')ax2.set_theta_direction(-1)ax2.set_title("极坐标系中的椭圆轨道", fontsize=14, pad=20)# 绘制轨道ax2.plot(theta, r, 'b-', linewidth=1.8)# 标记近日点和远日点perihelion_theta = np.piaphelion_theta = 0perihelion_r = a * (1 - e)aphelion_r = a * (1 + e)ax2.plot(perihelion_theta, perihelion_r, 'ro', markersize=8)ax2.plot(aphelion_theta, aphelion_r, 'go', markersize=8)# 添加标签ax2.text(perihelion_theta, perihelion_r, ' 近日点', verticalalignment='bottom', fontsize=9)ax2.text(aphelion_theta, aphelion_r, ' 远日点', verticalalignment='bottom', fontsize=9)# 添加轨道参数标注param_text = f"半长轴: {a} AU\n离心率: {e}"ax2.annotate(param_text, xy=(0.5, 0.95), xycoords='axes fraction',ha='center', va='top', fontsize=10,bbox=dict(boxstyle="round,pad=0.3", fc="white", alpha=0.8))ax2.grid(True, linestyle='--', alpha=0.6)plt.tight_layout(pad=3.0)plt.savefig(output_path, bbox_inches='tight')plt.close()print(f"行星轨道图已保存至: {output_path}")
四、使用示例
if __name__ == "__main__":# 1. 坐标系对比plot_coordinate_systems(output_path="coordinate_systems.png")# 2. 坐标转换演示 (点: (3, 4))plot_coordinate_conversion(point=[3, 4], output_path="coordinate_conversion.png")# 3. 几何变换演示 (三角形)triangle = np.array([[0, 0], [1, 0], [0.5, 1], [0, 0]])plot_geometric_transformations(triangle, output_path="transformations.png")# 4. 行星轨道演示 (地球近似轨道)plot_planetary_orbit(a=1, e=0.017, output_path="earth_orbit.png")# 5. 哈雷彗星轨道plot_planetary_orbit(a=17.8, e=0.967, output_path="halley_orbit.png")
五、生成图像说明
-
坐标系对比图 (
coordinate_systems.png
):- 并排展示直角坐标系和极坐标系
- 显示两种坐标系下的网格点布局
- 直观比较两种坐标系的表示方式
-
坐标转换图 (
coordinate_conversion.png
):- 展示同一点在两种坐标系中的表示
- 直角坐标显示x,y分量
- 极坐标显示半径r和角度θ
- 包含坐标转换公式: r = x 2 + y 2 r = \sqrt{x^2 + y^2} r=x2+y2, θ = arctan 2 ( y , x ) \theta = \arctan2(y, x) θ=arctan2(y,x)
-
几何变换图 (
transformations.png
):- 四宫格展示平移、旋转、缩放变换
- 原始形状显示为蓝色
- 变换后形状使用不同颜色表示
- 包含变换矩阵的数学表示
-
行星轨道图 (
earth_orbit.png
,halley_orbit.png
):- 并排展示直角坐标系和极坐标系中的轨道
- 标记太阳位置、近日点和远日点
- 显示轨道参数:半长轴和离心率
- 地球轨道接近圆形,哈雷彗星轨道高度椭圆
六、教学要点
-
数学概念:
- 直角坐标与极坐标的转换关系
- 几何变换的矩阵表示
- 椭圆在极坐标系中的标准方程: r = a ( 1 − e 2 ) 1 + e cos θ r = \frac{a(1-e^2)}{1 + e\cos\theta} r=1+ecosθa(1−e2)
-
天文知识:
- 开普勒第一定律:行星轨道是椭圆,太阳在焦点
- 离心率对轨道形状的影响
- 近日点和远日点的定义与计算
-
编程技巧:
- Matplotlib极坐标投影的使用
- 坐标变换的矩阵运算实现
- 复杂图形的多子图布局
- 科学可视化中的标注技巧
本节代码完整实现了坐标系转换和几何变换的可视化工具,可直接运行生成教学图像。行星轨道案例展示了极坐标在天文学中的实际应用。