Псевдогиперболоиды 2-го порядка на питоне

1. Геометрическая модель псевдогиперболоид 2-го порядка

2. Геометрия псевдогиперболоида с ползунками

import numpy as np

import matplotlib.pyplot as plt

# Параметры (Ваши)

a = 0.05

b = 0.5

R = 20.0

neck_radius = 1.0  # где обрезаем правый рог (вход)

# Геометрия

L = a * np.sqrt(1 + (R/b)**2)

x_neck = a * np.sqrt(1 + ((R — neck_radius)/b)**2)

def y_hyper(x):

    return b * np.sqrt(np.maximum((x/a)**2 — 1.0, 0))

def r_wall(x):

    «»»Радиус трубки от смещённой оси y=R»»»

    return R — y_hyper(np.abs(x))

# Сечение плоскостью z=0:

# верхняя стенка: y = R + r_wall(x)

# нижняя стенка: y = R — r_wall(x)

x = np.linspace(-L, L, 3000)

rw = r_wall(x)

y_up = R + rw

y_dn = R — rw

# ===== ФИГУРА =====

fig, axes = plt.subplots(2, 1, figsize=(18, 12))

# — (1) ПОЛНЫЙ ВИД —

ax = axes[0]

# Закрытая левая половина (заполнено серо-голубым = СТЕНКИ закрыты)

mask_left = x <= -a

ax.fill_between(x[mask_left], y_dn[mask_left], y_up[mask_left],

                color=’lightsteelblue’, alpha=0.7, label=’ЗАКРЫТЫЙ рог (стенки замкнуты)’)

# Открытая правая половина — обрезана при x_neck

mask_right_open = (x >= a) & (x <= x_neck)

ax.fill_between(x[mask_right_open], y_dn[mask_right_open], y_up[mask_right_open],

                color=’mistyrose’, alpha=0.7, label=’ОТКРЫТЫЙ рог (вход)’)

# Часть правого рога ЗА срезом — показываем как обрезанную (полупрозрачно, пунктир)

mask_right_cut = x > x_neck

ax.fill_between(x[mask_right_cut], y_dn[mask_right_cut], y_up[mask_right_cut],

                color=’gray’, alpha=0.15)

ax.plot(x[mask_right_cut], y_up[mask_right_cut], ‘k:’, lw=0.7, alpha=0.4)

ax.plot(x[mask_right_cut], y_dn[mask_right_cut], ‘k:’, lw=0.7, alpha=0.4)

# ФОКАЛЬНОЕ КОЛЬЦО: |x| < a — ТОР, в сечении это два отдельных «кружка»

mask_focal = np.abs(x) < a

# В фокальной зоне y_hyper=0, r_wall=R → стенка от y=0 до y=2R

ax.fill_between(x[mask_focal], y_dn[mask_focal], y_up[mask_focal],

                color=’gold’, alpha=0.6, label=’ФОКАЛЬНОЕ кольцо |x|<a’)

# Стенки (контуры)

ax.plot(x[x<=x_neck], y_up[x<=x_neck], ‘k-‘, lw=2)

ax.plot(x[x<=x_neck], y_dn[x<=x_neck], ‘k-‘, lw=2)

# Ось вращения (смещённая)

ax.axhline(R, color=’red’, ls=’—‘, lw=1.5, alpha=0.8, label=f’ось вращения y=R={R}’)

# Линия среза (вход)

ax.plot([x_neck, x_neck], [R-neck_radius, R+neck_radius],

        ‘g-‘, lw=4, label=f’ВХОД (срез x={x_neck:.2f})’)

# Левая игла (закрыта)

ax.plot([-L, -L], [R-0.05, R+0.05], ‘b-‘, lw=4, label=’Игла закрыта’)

# Подписи

ax.annotate(‘y=0 (труба касается!)’, xy=(0, 0), xytext=(L*0.3, -2),

            arrowprops=dict(arrowstyle=’->’, color=’purple’), fontsize=10, color=’purple’)

ax.annotate(f’y=2R={2*R}’, xy=(0, 2*R), xytext=(L*0.3, 2*R+1),

            arrowprops=dict(arrowstyle=’->’, color=’purple’), fontsize=10, color=’purple’)

ax.axvline(-a, color=’orange’, lw=0.7, ls=’:’, alpha=0.7)

ax.axvline(a, color=’orange’, lw=0.7, ls=’:’, alpha=0.7)

ax.set_xlabel(‘x’, fontsize=12)

ax.set_ylabel(‘y  (плоскость z=0)’, fontsize=12)

ax.set_title(f’Псевдогиперболоид: сечение плоскостью z=0\n’

             f’a={a}, b={b}, R={R}, L={L:.3f}, x_neck={x_neck:.3f}’, fontsize=13)

ax.legend(loc=’center right’, fontsize=10)

ax.set_aspect(‘equal’)

ax.grid(alpha=0.3)

ax.set_xlim(-L*1.05, L*1.05)

ax.set_ylim(-2, 2*R+2)

# — (2) ZOOM на фокальное кольцо —

ax = axes[1]

xz = np.linspace(-3*a, 3*a, 1000)

rwz = r_wall(xz)

y_upz = R + rwz

y_dnz = R — rwz

mask_fz = np.abs(xz) < a

mask_lz = xz <= -a

mask_rz = xz >= a

ax.fill_between(xz[mask_fz], y_dnz[mask_fz], y_upz[mask_fz],

                color=’gold’, alpha=0.6, label=’ФОКАЛЬНОЕ кольцо |x|<a’)

ax.fill_between(xz[mask_lz], y_dnz[mask_lz], y_upz[mask_lz],

                color=’lightsteelblue’, alpha=0.7, label=’Левый рог’)

ax.fill_between(xz[mask_rz], y_dnz[mask_rz], y_upz[mask_rz],

                color=’mistyrose’, alpha=0.7, label=’Правый рог’)

ax.plot(xz, y_upz, ‘k-‘, lw=2)

ax.plot(xz, y_dnz, ‘k-‘, lw=2)

ax.axhline(R, color=’red’, ls=’—‘, lw=1.5, alpha=0.7, label=f’ось y=R={R}’)

ax.axhline(0, color=’purple’, ls=’:’, lw=1, alpha=0.7, label=’y=0′)

ax.axhline(2*R, color=’purple’, ls=’:’, lw=1, alpha=0.7, label=f’y=2R={2*R}’)

ax.axvline(-a, color=’orange’, lw=1, ls=’:’, alpha=0.8)

ax.axvline(a, color=’orange’, lw=1, ls=’:’, alpha=0.8)

ax.set_xlabel(‘x’, fontsize=12)

ax.set_ylabel(‘y’, fontsize=12)

ax.set_title(f’ZOOM на фокальное кольцо |x|<a={a}\n’

             f’В этой зоне труба максимально широкая: от y=0 до y=2R={2*R}’,

             fontsize=13)

ax.legend(fontsize=10)

ax.set_aspect(‘equal’)

ax.grid(alpha=0.3)

ax.set_xlim(-3*a, 3*a)

ax.set_ylim(-2, 2*R+2)

plt.tight_layout()

plt.savefig(«geometry_2d.png», dpi=140)

plt.show()

print(f»  • Это ОСЕСИММЕТРИЧНАЯ фигура вокруг прямой y=R»)

print(f»  • На сечении z=0 видны ДВЕ полосы (верх и низ от оси y=R)»)

print(f»  • В реальности это ОДНО тело: тор-образный канал»)

print(f»  • На концах (x=±L) сжимается в иглу»)

print(f»  • В центре (|x|<a) самая широкая часть — ФОКАЛЬНОЕ КОЛЬЦО»)

print(f»  • Левая игла ЗАКРЫТА (купол)»)

print(f»  • Правый рог обрезан при x={x_neck:.3f}, там ВХОД (открытый)»)