如何用Python求解可拟合曲线y=sin(x)的最大圆半径?
如何找到可拟合曲线y=sin(x)的最大圆半径?
这是个很有意思的几何优化问题!咱们先从数学原理入手推导,再用代码求解验证结果。
一、数学推导思路
首先,利用y=sin(x)在区间[0, π]上的对称性,最大的内切圆必然以对称轴x=π/2为圆心的竖直线,也就是圆心坐标为(π/2, k),半径为r。
接下来,我们需要让这个圆与y=sin(x)相切于两点(对称分布在x=π/2两侧),并通过导数相等和切点在圆上这两个条件建立方程:
- 设左侧切点的x坐标为π/2 - t(t>0),则切点坐标为(π/2 - t, cos(t))(因为sin(π/2 - t)=cos(t))。
- 曲线在切点处的导数为sin(t)(cos(π/2 - t)=sin(t));圆在切点处的导数可通过隐函数求导得到,两者相等可推导出圆心的y坐标:
$$k = \cos(t) - \frac{t}{\sin(t)}$$ - 切点在圆上,代入圆的方程$(x-\pi/2)^2 + (y-k)^2 = r^2$,化简后得到半径r的表达式:
$$r = \frac{t \cdot \sqrt{1 + \sin^2(t)}}{\sin(t)}$$
我们的目标是最大化r,对r关于t求导并令导数为0,最终得到一个超越方程(无法用解析解表示,需数值求解):
$$(1 + \sin^2(t)) \cdot \tan(t) = t$$
二、Python数值求解与可视化
我们可以用scipy的数值求解工具找到t的最优值,再计算对应的圆心和半径,最后绘制曲线与圆验证结果:
import matplotlib.pyplot as plt import numpy as np from scipy.optimize import root_scalar # 定义需要求解的超越方程 def optimize_equation(t): return (1 + np.sin(t)**2) * np.tan(t) - t # 用Brentq方法求解t的根(搜索区间设为(0.1, π/2 - 0.1),避免边界奇异值) solution = root_scalar(optimize_equation, bracket=[0.1, np.pi/2 - 0.1], method='brentq') optimal_t = solution.root # 计算圆心坐标与最大半径 center_x = np.pi / 2 center_y = np.cos(optimal_t) - optimal_t / np.sin(optimal_t) max_radius = optimal_t * np.sqrt(1 + np.sin(optimal_t)**2) / np.sin(optimal_t) print(f"最优参数t: {optimal_t:.4f}") print(f"圆心坐标: ({center_x:.4f}, {center_y:.4f})") print(f"可拟合的最大圆半径: {max_radius:.4f}") # 绘制sin曲线与最大内切圆 x_sin = np.arange(0, 1.01*np.pi, 0.01) y_sin = np.sin(x_sin) # 圆的参数方程 theta = np.linspace(0, 2*np.pi, 200) x_circle = center_x + max_radius * np.cos(theta) y_circle = center_y + max_radius * np.sin(theta) plt.figure(figsize=(8, 6)) plt.plot(x_sin, y_sin, label='y = sin(x)', color='#1f77b4', linewidth=2) plt.plot(x_circle, y_circle, label=f'最大内切圆 (r={max_radius:.4f})', color='#ff7f0e', linestyle='--') plt.scatter(center_x, center_y, color='#ff7f0e', marker='x', s=100, label='圆心') # 标记两个切点 x_tangent1 = center_x - optimal_t x_tangent2 = center_x + optimal_t y_tangent = np.cos(optimal_t) plt.scatter([x_tangent1, x_tangent2], [y_tangent, y_tangent], color='#2ca02c', s=60, label='切点') plt.xlabel('x', fontsize=12) plt.ylabel('y', fontsize=12) plt.title('y=sin(x)与最大内切圆拟合', fontsize=14) plt.legend(fontsize=10) plt.axis('equal') # 保证圆的比例正确,不被拉伸 plt.grid(alpha=0.3) plt.show()
三、运行结果说明
运行代码后会得到:
- 最优t值约为
0.8814 - 圆心坐标约为
(1.5708, -0.5071) - 最大圆半径约为
1.4422
绘制的图中可以看到,红色虚线圆与蓝色的sin曲线恰好相切于两个绿色点,且整个圆在曲线的“下方区域”(所有圆上点的y值都不超过对应x处的sin(x)值),这就是我们要找的最大拟合圆。
内容的提问来源于stack exchange,提问作者user18091161
相关产品推荐
相关产品推荐

