Python实现两点间带角度椭圆的高度旋转问题
问题分析
你当前的椭圆旋转逻辑有误:直接将旋转角度deg加到极角theta上,相当于让椭圆的极坐标点绕中心旋转,但缩放因子ellipse_h是作用在全局y方向的,而非椭圆的局部短轴方向,导致ellipse_h为负时,缩放方向无法随椭圆旋转同步变化。另外,angle函数返回的已经是弧度,你后续又错误地将其转成弧度计算cos和sin,这会导致旋转角度偏差。
解决方案
正确的流程应该是:先生成以原点为中心的标准椭圆(长轴沿x轴),再通过旋转矩阵将椭圆旋转到目标角度,最后平移到两点的中点。同时保留ellipse_h的符号来控制椭圆的朝向。
关键修正点
- 移除多余的弧度转换:
deg本身是弧度,直接用np.cos(deg)和np.sin(deg)即可 - 分离椭圆生成与旋转步骤:先创建未旋转的椭圆点,再应用旋转变换
- 用旋转矩阵处理坐标:旋转矩阵公式为:
x_rot = x * cosθ - y * sinθ y_rot = x * sinθ + y * cosθ
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt def distance(x1, y1, x2, y2): return np.sqrt(np.power(x2 - x1, 2) + np.power(y2 - y1, 2)) def midpoint(x1, y1, x2, y2): return [(x1 + x2) / 2, (y1 + y2) / 2] def angle(x1, y1, x2, y2): # 返回弧度值 return np.arctan2(y2 - y1, x2 - x1) x1 = 100 y1 = 150 x2 = 200 y2 = 190 ellipse_h = -0.5 # 测试这个值 x_coords = [] y_coords = [] mid = midpoint(x1, y1, x2, y2) center_x, center_y = mid ellipse_resolution = 40 step = 2 * np.pi / ellipse_resolution radius = distance(x1, y1, x2, y2) * 0.5 rot_angle = angle(x1, y1, x2, y2) cos_rot = np.cos(rot_angle) sin_rot = np.sin(rot_angle) # 先生成未旋转的椭圆点(长轴沿x轴) for theta in np.arange(0, np.pi + step, step): # 标准椭圆参数方程:x = a*cosθ, y = b*sinθ x_local = radius * np.cos(theta) y_local = ellipse_h * radius * np.sin(theta) # 应用旋转矩阵 x_rotated = x_local * cos_rot - y_local * sin_rot y_rotated = x_local * sin_rot + y_local * cos_rot # 平移到中心 x = center_x + x_rotated y = center_y + y_rotated x_coords.append(x) y_coords.append(y) plt.xlabel("X") plt.ylabel("Y") plt.title("Arc between 2 Points") plt.plot(x_coords, y_coords) plt.scatter([x1, x2], [y1, y2]) plt.axis('equal') plt.show()
代码说明
- 生成局部椭圆点:先在以原点为中心的坐标系中生成椭圆,
y_local用ellipse_h * radius * np.sin(theta),保留符号控制椭圆朝向。 - 旋转变换:通过旋转矩阵将局部椭圆点旋转到两点连线的角度,确保缩放方向随椭圆同步旋转。
- 平移到中点:将旋转后的点平移到两点的中心位置,完成最终绘制。
现在测试ellipse_h = -0.5,椭圆的短轴方向会正确跟随旋转后的椭圆,不会出现方向错位的问题。
内容的提问来源于stack exchange,提问作者Dr. Pontchartrain
相关产品推荐
相关产品推荐

