高中数学 with Python: 二次曲线
发布: (2026年1月9日 GMT+8 09:37)
3 分钟阅读
原文: Dev.to
Source: Dev.to
Source:
圆锥曲线概述
圆、抛物线、椭圆和双曲线是四种 圆锥曲线——当平面切割双锥体时产生的曲线。
所得到曲线的形状取决于切割平面与锥体轴之间的夹角。
| 圆锥曲线类型 | 标准形式(笛卡尔方程) |
|---|---|
| 圆 | ((x-h)^2 + (y-k)^2 = r^2) |
| 抛物线 | (y = a(x-h)^2 + k)(或 (x = a(y-k)^2 + h)) |
| 椭圆 | (\displaystyle \frac{(x-h)^2}{a^2} + \frac{(y-k)^2}{b^2} = 1) |
| 双曲线 | (\displaystyle \frac{(x-h)^2}{a^2} - \frac{(y-k)^2}{b^2} = 1)(或符号互换的形式) |
本程序展示的内容
下面的交互式程序可视化一个圆锥、一个切割平面以及由此产生的二维截面。
- 右侧图中的 图例 显示截面的显式方程。
- 使用滑块更改切割角 β,观察曲线在圆、椭圆、抛物线和双曲线之间的转变。
该代码在 AI 的帮助下生成,旨在用于探索,而非作为一步步的课堂练习。
实时笔记本
# Initial setup for displaying Japanese characters in graphs
!pip install -q japanize-matplotlib
import japanize_matplotlib # Enables proper display of Japanese text in plots
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider
def draw_conic_with_equation(beta_deg):
alpha_deg = 45 # Fixed cone half‑angle
alpha = np.radians(alpha_deg)
beta = np.radians(beta_deg)
d = 0.5 # Plane offset from the origin
fig = plt.figure(figsize=(14, 6))
# --- Left: 3D cone and cutting plane ---
ax1 = fig.add_subplot(121, projection='3d')
r = np.linspace(0, 2, 40)
theta = np.linspace(0, 2 * np.pi, 40)
R, THETA = np.meshgrid(r, theta)
X_cone = R * np.cos(THETA)
Y_cone = R * np.sin(THETA)
Z_cone_up = R / np.tan(alpha)
Z_cone_down = -R / np.tan(alpha)
X_p = np.linspace(-2, 2, 10)
Y_p = np.linspace(-2, 2, 10)
XP, YP = np.meshgrid(X_p, Y_p)
ZP = XP * np.tan(beta) + d
ax1.plot_surface(X_cone, Y_cone, Z_cone_up, alpha=0.15, color='cyan')
ax1.plot_surface(X_cone, Y_cone, Z_cone_down, alpha=0.15, color='cyan')
ax1.plot_surface(XP, YP, ZP, alpha=0.4, color='orange')
ax1.set_title("3D View")
# --- Right: 2D cross section ---
ax2 = fig.add_subplot(122)
# Expanded equation of the cross section:
# y^2 = (tan^2(beta) - 1)·x^2 + (2·d·tan(beta))·x + d^2
x_range = np.linspace(-4, 4, 1000)
tan_b = np.tan(beta)
y_sq = (x_range * tan_b + d)**2 - x_range**2
valid = y_sq >= 0
x_plot = x_range[valid]
y_plot = np.sqrt(y_sq[valid])
# Coefficients for legend display
A = tan_b**2 - 1
B = 2 * d * tan_b
C = d**2
eq_label = rf'$y^2 = ({A:.2f})x^2 + ({B:.2f})x + {C:.2f}$'
ax2.plot(x_plot, y_plot, color='blue', linewidth=2, label=eq_label)
ax2.plot(x_plot, -y_plot, color='blue', linewidth=2)
# Determine conic type based on angle β
if beta_deg == 0:
shape_type = "Circle"
elif beta_deg < alpha_deg:
shape_type = "Ellipse"
elif beta_deg == alpha_deg:
shape_type = "Parabola"
else:
shape_type = "Hyperbola"
ax2.set_title(f"2D Cross Section: {shape_type}")
ax2.set_xlabel('x')
ax2.set_ylabel('y')
ax2.set_xlim(-3, 3)
ax2.set_ylim(-3, 3)
ax2.grid(True)
ax2.axhline(0, color='black', lw=1)
ax2.axvline(0, color='black', lw=1)
# Legend in the lower‑left corner
ax2.legend(loc='lower left', fontsize=10)
plt.tight_layout()
plt.show()
# Interactive slider for the cutting angle β
interact(
draw_conic_with_equation,
beta_deg=FloatSlider(min=0, max=85, step=1, value=0, description='Angle β')
)