如何在Python中旋转曲线使其经过指定二维坐标点?
旋转曲线使其经过指定点的实现方法
核心思路
要让曲线旋转后经过指定点,本质是找到合适的旋转中心和旋转角度,使得原曲线上某一点经过旋转变换后恰好落在目标点上。通过联立旋转变换方程与原曲线方程,用数值方法即可求解出所需的旋转角度。
具体步骤(以曲线 $y=e^x+2$ 经过点 $(5,6)$ 为例)
1. 定义旋转变换公式
假设绕点 $(a,b)$ 旋转 $\theta$ 弧度,平面上任意点 $(x,y)$ 旋转后的坐标 $(x',y')$ 满足:
$$
\begin{cases}
x' = (x-a)\cos\theta - (y-b)\sin\theta + a \
y' = (x-a)\sin\theta + (y-b)\cos\theta + b
\end{cases}
$$
这里选择原曲线上的点作为旋转中心(比如 $x=0$ 处的点 $(0,3)$),这样 $b=f(a)=e^0+2=3$,简化计算。
2. 建立求解方程
需要找到原曲线上的点 $(x_0, y_0)$(满足 $y_0=e^{x_0}+2$)和旋转角度 $\theta$,使得旋转后 $(x_0,y_0)$ 变为 $(5,6)$。代入变换公式得到方程组:
$$
\begin{cases}
5 = x_0\cos\theta - (e^{x_0}-1)\sin\theta \
3 = x_0\sin\theta + (e^{x_0}-1)\cos\theta
\end{cases}
$$
3. 数值求解旋转角度
使用数值方法(牛顿法)求解上述方程组,借助 scipy.optimize.root 实现高效求解。
4. 生成旋转后的曲线并绘图
对原曲线上的所有点应用旋转变换,得到旋转后的曲线,最后绘图验证结果。
完整代码实现
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import root # 定义原曲线函数 def f(x): return np.exp(x) + 2 # 定义待求解的方程组 def equations(vars): x0, theta = vars dx = x0 - rot_center[0] dy = f(x0) - rot_center[1] eq1 = dx * np.cos(theta) - dy * np.sin(theta) - (target_point[0] - rot_center[0]) eq2 = dx * np.sin(theta) + dy * np.cos(theta) - (target_point[1] - rot_center[1]) return [eq1, eq2] # 设置参数 rot_center = (0, f(0)) # 旋转中心:原曲线x=0处的点(0,3) target_point = (5, 6) # 目标点 initial_guess = [1, 0] # 初始猜测值:x0=1,theta=0弧度 # 求解方程组 solution = root(equations, initial_guess) x0_sol, theta_sol = solution.x # 生成原曲线和旋转后的曲线点 x_original = np.linspace(-3, 3, 100) y_original = f(x_original) def rotate_point(x, y, center, theta): a, b = center dx = x - a dy = y - b x_rot = dx * np.cos(theta) - dy * np.sin(theta) + a y_rot = dx * np.sin(theta) + dy * np.cos(theta) + b return x_rot, y_rot x_rotated, y_rotated = rotate_point(x_original, y_original, rot_center, theta_sol) # 绘图 plt.figure(figsize=(10, 6)) plt.plot(x_original, y_original, label='原曲线 $y=e^x+2$', color='#1f77b4') plt.plot(x_rotated, y_rotated, label=f'旋转后曲线 (θ={theta_sol:.2f} rad)', color='#ff7f0e') plt.scatter(*target_point, color='#2ca02c', s=120, zorder=5, label='目标点 (5,6)') plt.scatter(*rot_center, color='#9467bd', s=120, zorder=5, label=f'旋转中心 {rot_center}') plt.scatter(x0_sol, f(x0_sol), color='#d62728', s=120, zorder=5, label=f'原曲线对应点 ({x0_sol:.2f}, {f(x0_sol):.2f})') plt.xlabel('x', fontsize=12) plt.ylabel('y', fontsize=12) plt.legend(fontsize=10) plt.grid(True, alpha=0.3) plt.show()
关键说明
- 若需要更换旋转中心,只需修改
rot_center的值即可(建议选择原曲线上的点,减少计算复杂度)。 - 绕原点旋转时经计算无解(联立方程后得到的 $\cos\theta$ 绝对值大于1,无实数解),因此需选择其他旋转中心。
- 数值求解的初始猜测值会影响收敛性,若求解失败可尝试调整
initial_guess(比如调整x0的范围)。
内容的提问来源于stack exchange,提问作者TH3CODEgUy
相关产品推荐
相关产品推荐

