Моделирование Псевдопараболоидов на Питоне

Программный код для моделирования:

————————————————————————-

import matplotlib.pyplot as plt

import numpy as np

# — Общие параметры параболы —

a = 1  # Для параболы y = ax^2 (и y = -ax^2)

# — Параметры первой фигуры (базовый профиль от X=0 до X=2) —

initial_reflection_axis_x = 1 # Ось симметрии/отражения для создания первой фигуры

# Определяем исходные ветви параболы (часть от X=0 до X=initial_reflection_axis_x)

x_segment_original = np.linspace(0, initial_reflection_axis_x, 200)

y_upper_segment_original = a * x_segment_original**2

y_lower_segment_original = -a * x_segment_original**2

# Вычисляем ЗЕРКАЛЬНОЕ отображение первого сегмента

x_segment_reflected = 2 * initial_reflection_axis_x — x_segment_original # От 1 до 2

y_upper_segment_reflected = y_upper_segment_original

y_lower_segment_reflected = y_lower_segment_original

# Комбинированный профиль ПЕРВОЙ 2D-фигуры (от X=0 до X=2)

x_first_figure_profile_upper = np.concatenate((x_segment_original, x_segment_reflected))

y_first_figure_profile_upper = np.concatenate((y_upper_segment_original, y_upper_segment_reflected))

x_first_figure_profile_lower = np.concatenate((x_segment_original, x_segment_reflected))

y_first_figure_profile_lower = np.concatenate((y_lower_segment_original, y_lower_segment_reflected))

# Упорядочиваем по x для корректного отображения

sort_idx_upper = np.argsort(x_first_figure_profile_upper)

x_first_figure_profile_upper = x_first_figure_profile_upper[sort_idx_upper]

y_first_figure_profile_upper = y_first_figure_profile_upper[sort_idx_upper]

sort_idx_lower = np.argsort(x_first_figure_profile_lower)

x_first_figure_profile_lower = x_first_figure_profile_lower[sort_idx_lower]

y_first_figure_profile_lower = y_first_figure_profile_lower[sort_idx_lower]

# — Фокусы 2D-ветвей для ПЕРВОЙ 2D-фигуры —

# Исходные фокусы (красный/зеленый кружок)

focus_1_upper_orig_x, focus_1_upper_orig_y = 0, 1 / (4 * a)

focus_1_lower_orig_x, focus_1_lower_orig_y = 0, -1 / (4 * a)

# Зеркальные фокусы (красный/зеленый крестик)

focus_1_upper_refl_x, focus_1_upper_refl_y = 2 * initial_reflection_axis_x — focus_1_upper_orig_x, focus_1_upper_orig_y # X=2

focus_1_lower_refl_x, focus_1_lower_refl_y = 2 * initial_reflection_axis_x — focus_1_lower_orig_x, focus_1_lower_orig_y # X=2

# Фокусные зоны внутри 2D-профиля (чёрные точки, как вы просили)

# Они находятся на оси симметрии первой фигуры X=1

concentration_x_2d_figure = initial_reflection_axis_x

concentration_y_upper = 1 / (4 * a)

concentration_y_lower = -1 / (4 * a)

# — Настройка общей фигуры для двух подграфиков —

fig, axes = plt.subplots(1, 2, figsize=(20, 9)) # Одна строка, два столбца, увеличенный размер

# — График 1: Псевдопараболоид 2-го порядка —

# Вращение первой фигуры вокруг своей оси симметрии (X=1)

ax1 = axes[0]

ax1.set_title(‘Псевдопараболоид 2-го Порядка’, fontsize=14)

# Профиль первой фигуры

ax1.plot(x_first_figure_profile_upper, y_first_figure_profile_upper,

         label=f’Профиль фигуры (верх)’, color=’blue’, linewidth=2)

ax1.plot(x_first_figure_profile_lower, y_first_figure_profile_lower,

         label=f’Профиль фигуры (низ)’, color=’green’, linewidth=2, linestyle=’—‘)

# Фокусы 2D-ветвей первой фигуры

ax1.plot(focus_1_upper_orig_x, focus_1_upper_orig_y, ‘o’, color=’red’, markersize=8, zorder=5, label=f’Фокус исходной ветви (X=0)’)

ax1.plot(focus_1_lower_orig_x, focus_1_lower_orig_y, ‘o’, color=’darkgreen’, markersize=8, zorder=5, label=f’Фокус исходной ветви (X=0)’)

ax1.plot(focus_1_upper_refl_x, focus_1_upper_refl_y, ‘x’, color=’red’, markersize=10, mew=2, zorder=5, label=f’Фокус зеркальной ветви (X=2)’)

ax1.plot(focus_1_lower_refl_x, focus_1_lower_refl_y, ‘x’, color=’darkgreen’, markersize=10, mew=2, zorder=5, label=f’Фокус зеркальной ветви (X=2)’)

# Ось вращения (совпадает с осью симметрии первой фигуры)

rotation_axis_2nd_order = initial_reflection_axis_x # X=1

ax1.axvline(x=rotation_axis_2nd_order, color=’purple’, linestyle=’—‘, linewidth=3,

            label=f’Ось вращения (X={rotation_axis_2nd_order})’)

# Фокусные зоны (чёрные точки)

ax1.plot(concentration_x_2d_figure, concentration_y_upper, ‘ko’, markersize=15, zorder=10,

         label=f’Фокусная зона ({concentration_x_2d_figure}, {concentration_y_upper:.2f})’)

ax1.plot(concentration_x_2d_figure, concentration_y_lower, ‘ko’, markersize=15, zorder=10,

         label=f’Фокусная зона ({concentration_x_2d_figure}, {concentration_y_lower:.2f})’)

ax1.set_xlabel(‘X-ось’)

ax1.set_ylabel(‘Y-ось’)

ax1.grid(True)

ax1.set_aspect(‘equal’, adjustable=’box’)

ax1.set_xlim([-0.5, 2.5])

ax1.set_ylim([-1.5, 1.5])

ax1.legend(loc=’lower center’, bbox_to_anchor=(0.5, -0.25), fancybox=True, shadow=True, ncol=3, fontsize=’small’)

# — График 2: Псевдопараболоид 3-го порядка —

# Вращение первой фигуры вокруг новой оси вращения (X=2.5)

ax2 = axes[1]

ax2.set_title(‘Псевдопараболоид 3-го Порядка’, fontsize=14)

# Профиль первой фигуры (тот же самый)

ax2.plot(x_first_figure_profile_upper, y_first_figure_profile_upper,

         label=f’Профиль фигуры (верх)’, color=’blue’, linewidth=2)

ax2.plot(x_first_figure_profile_lower, y_first_figure_profile_lower,

         label=f’Профиль фигуры (низ)’, color=’green’, linewidth=2, linestyle=’—‘)

# Фокусы 2D-ветвей первой фигуры (те же самые, так как это та же базовая фигура)

ax2.plot(focus_1_upper_orig_x, focus_1_upper_orig_y, ‘o’, color=’red’, markersize=8, zorder=5, label=f’Фокус исходной ветви (X=0)’)

ax2.plot(focus_1_lower_orig_x, focus_1_lower_orig_y, ‘o’, color=’darkgreen’, markersize=8, zorder=5, label=f’Фокус исходной ветви (X=0)’)

ax2.plot(focus_1_upper_refl_x, focus_1_upper_refl_y, ‘x’, color=’red’, markersize=10, mew=2, zorder=5, label=f’Фокус зеркальной ветви (X=2)’)

ax2.plot(focus_1_lower_refl_x, focus_1_lower_refl_y, ‘x’, color=’darkgreen’, markersize=10, mew=2, zorder=5, label=f’Фокус зеркальной ветви (X=2)’)

# Новая ось вращения

new_rotation_axis_x = 2.5

ax2.axvline(x=new_rotation_axis_x, color=’darkorange’, linestyle=’—‘, linewidth=3,

            label=f’Новая Ось вращения (X={new_rotation_axis_x})’)

# Фокусные зоны (чёрные точки) — остаются на X=1, так как они относятся к 2D-профилю

ax2.plot(concentration_x_2d_figure, concentration_y_upper, ‘ko’, markersize=15, zorder=10,

         label=f’Фокусная зона ({concentration_x_2d_figure}, {concentration_y_upper:.2f})’)

ax2.plot(concentration_x_2d_figure, concentration_y_lower, ‘ko’, markersize=15, zorder=10,

         label=f’Фокусная зона ({concentration_x_2d_figure}, {concentration_y_lower:.2f})’)

ax2.set_xlabel(‘X-ось’)

ax2.set_ylabel(‘Y-ось’)

ax2.grid(True)

ax2.set_aspect(‘equal’, adjustable=’box’)

ax2.set_xlim([-0.5, 5.5]) # Расширяем ось X, чтобы новая ось была видна

ax2.set_ylim([-1.5, 1.5])

ax2.legend(loc=’lower center’, bbox_to_anchor=(0.5, -0.25), fancybox=True, shadow=True, ncol=3, fontsize=’small’)

plt.tight_layout(rect=[0, 0.03, 1, 0.95]) # Корректировка для размещения заголовков и легенд

plt.show()

————————————————————

Давайте подробно рассмотрим математический аппарат, лежащий в основе построения «псевдопараболоидов 2-го и 3-го порядка»

1. Исходный Эллипс и Расчет Фокусов

Начнем с базового элемента вашей конструкции — эллипса. Уравнение стандартного эллипса с центром в начале координат (0,0) и полуосями r_x (по оси X) и r_y (по оси Y) имеет вид:rx2​x2​+ry2​y2​=1

В вашем коде:

  • rx = полуось по оси X (горизонтальная)
  • ry = полуось по оси Y (вертикальная)

Расстояние до фокусов (c) для эллипса, когда большая полуось лежит на оси X (r_xr_y), рассчитывается по формуле:c=rx2​−ry2​​ Это расстояние от центра эллипса до каждого фокуса. Фокусы такого эллипса находятся в точках (pmc,0).

В вашем коде этот расчет представлен строкой:

Python

c = np.sqrt(rx**2 — ry**2)

2. Построение «Веретена» (Основы для «Первой Фигуры»)

Вы используете два эллипса, центры которых смещены, и из них формируете «веретена».

Эллипс 1 (для левой части)

  • Центр: (h_ell1,k_ell1)
    • В вашем коде: h_ell1 = rx, k_ell1 = 1.0. То есть (2.0,1.0).
  • Фокусы эллипса 1:
    • F_1_x1=h_ell1−c
    • F_1_x2=h_ell1+c
    • F_1_y1=k_ell1
    • F_1_y2=k_ell1
    • Эти фокусы: (h_ell1pmc,k_ell1).
  • Построение веретена:
    • Вы берете верхнюю половину эллипса: y_pos=r_ysqrt1−frac(x−h_ell1)2r_x2.
    • Затем вы делаете «странное» преобразование: y_segment_rotated_and_shifted1 = -y_positive_ellipse_base1 + k_ell1. Это отражает верхнюю половину относительно горизонтальной линии y=k_ell1 и сдвигает ее, создавая нижнюю часть веретена.
    • После этого вы зеркально отражаете полученный сегмент по X (x_segment_reflected1 = 2 * h_ell1 — x_segment_base1), чтобы создать симметричную часть веретена.

Эллипс 2 (для правой части)

  • Центр: (h_ell2,k_ell2)
    • В вашем коде: h_ell2 = -rx, k_ell2 = 1.0. То есть (−2.0,1.0).
  • Фокусы эллипса 2: (h_ell2pmc,k_ell2).
  • Построение веретена 2 аналогично веретену 1.

3. Зеркальное Отображение «Веретен» по Оси Y=0

Вы создаете зеркальные копии уже сформированных веретен относительно оси X (Y=0).

  • Если исходная Y-координата была y, то зеркальная становится −y.
  • Это применяется к координатам веретен и к Y-координатам их центров и фокусов:
    • y_pseudoparabola1_left_mirrored = -y_pseudoparabola1[idx_left1]
    • foci1_y1_mirrored = -foci1_y1 и т.д.
    • k_ell1_mirrored = -k_ell1 и т.д.

4. Поворот на 90 Градусов Против Часовой Стрелки

Следующий ключевой шаг — это поворот всей геометрии на 90 градусов против часовой стрелки. Правило поворота точки (x,y) на 90 градусов против часовой стрелки вокруг начала координат (0,0) дает новую точку (−y,x).

Ваша функция rotate_ccw_90(x_coords, y_coords) реализует это:

Python

def rotate_ccw_90(x_coords, y_coords):

    return -y_coords, x_coords

Эта операция применяется ко всем элементам: точкам веретен, фокусам и центрам. На этом этапе формируется ваша «первая фигура».

Координаты фокусов после поворота:

  • Если исходный фокус был (X_foci,Y_foci), то после поворота он становится (−Y_foci,X_foci).
  • Например, фокус F_1_x1 из (h_ell1−c,k_ell1) становится (−k_ell1,h_ell1−c).

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

  • «Первая фигура»: Это полностью сформированная и повернутая геометрия, полученная на предыдущем шаге (все четыре веретена: оригинальные и зеркальные).
  • Ось вращения: Согласно вашему определению, для 2-го порядка вращение происходит «вокруг оси симметрии одной (первой) фигуры». В повернутой системе координат, симметричная ось для вашей «первой фигуры» находится на X=0.
  • Фокальные зоны (Места сосредоточения энергии):
    • В контексте эллипсоидов вращения, фокальные зоны — это точки на оси вращения, куда сходятся лучи.
    • В классическом эллипсоиде вращения, образованном вращением эллипса с полуосями r_x (вдоль оси вращения) и r_y (перпендикулярно), фокусы будут на (0,pmsqrtr_x2−r_y2) относительно центра, если вращение идёт вокруг оси Y, или (pmsqrtr_x2−r_y2,0) если вращение вокруг оси X.
    • В вашей повернутой системе, где ось вращения стала X=0, а исходный эллипс имел r_x вдоль горизонтальной оси, фокусы будут находиться на Y-оси. Если мы рассматриваем «совокупную» форму как эллипсоид, то его главные фокусы будут на оси X=0 (новой оси вращения) на расстоянии c от центра.
    • Поэтому, на графике для ПЭ 2-го порядка, фокальные зоны расположены как точки: (0,c) и (0,−c). Это отражает концентрацию энергии на центральной оси.

Ваш код для этих фокусов:

Python

focal_point_pe2_y1 = c

focal_point_pe2_y2 = -c

ax1.plot(0, focal_point_pe2_y1, ‘o’, color=’red’, markersize=15, zorder=10, …)

ax1.plot(0, focal_point_pe2_y2, ‘o’, color=’red’, markersize=15, zorder=10, …)


6. Построение Псевдопараболоида 3-го Порядка

  • «Первая фигура»: Это та же самая «первая фигура» (совокупность веретен) из левого графика.
  • Сдвиг: Перед вращением вы применяете сдвиг по оси X к этой «первой фигуре».
    • shift_x_for_pe3 = 2.0
    • Все X-координаты точек «первой фигуры» сдвигаются на -shift_x_for_pe3.
    • Например, если точка была (x,y), она становится (x−shift_x_for_pe3,y).
  • Новая ось вращения: Согласно вашему определению, «Псевдопараболоид 3-го порядка строится вращением одной (первой) фигуры вокруг новой оси вращения». В вашем коде эта новая ось вращения явно задана как X=0 на правом графике.
  • Фокальные зоны (Места сосредоточения энергии):
    • Поскольку «первая фигура» сдвигается, ее внутренние фокальные точки также сдвигаются вместе с ней.
    • Фокусы, которые для ПЭ 2-го порядка были в (0,c) и (0,−c), после сдвига на -shift_x_for_pe3 теперь будут находиться в (−shift_x_for_pe3,c) и (−shift_x_for_pe3,−c).
    • Когда эта сдвинутая фигура вращается вокруг новой оси X=0, эти сдвинутые фокальные точки описывают кольца в 3D-пространстве.
      • Координата X, где расположены эти кольца, будет X = -shift_x_for_pe3.
      • Радиус этих колец будет равен абсолютной величине их Y-координаты, то есть ∣c∣.
    • На 2D-графике (проекции) эти кольцевые фокальные зоны отображаются как две точки: (-shift_x_for_pe3, c) и (-shift_x_for_pe3, -c).
    • Ваш код для этих фокусов:

Python

focus_pe3_shifted_x = 0 — shift_x_for_pe3

focal_point_pe3_y1 = c

focal_point_pe3_y2 = -c

ax2.plot(focus_pe3_shifted_x, focal_point_pe3_y1, ‘s’, color=’darkred’, markersize=15, …)

ax2.plot(focus_pe3_shifted_x, focal_point_pe3_y2, ‘s’, color=’darkred’, markersize=15, …)

Почему они в разных местах?

Именно из-за этого сдвига «первой фигуры» относительно неподвижной новой оси вращения (X=0) для ПЭ 3-го порядка.

  • ПЭ 2-го порядка: Фокусы находятся на оси вращения (поскольку ось вращения совпадает с осью симметрии фигуры).
  • ПЭ 3-го порядка: Фокусы сдвигаются вместе с фигурой, и поэтому они не совпадают с новой осью вращения (X=0), а располагаются на некотором расстоянии от нее (X=−2.0). При вращении вокруг X=0, эти смещенные фокусы формируют кольца, которые мы видим как точки на X=−2.0.

Это различие в положении фокальных зон точно отражает модель: во втором случае мы вращаем сдвинутую фигуру относительно определенной оси, что приводит к образованию тороидальных форм с соответствующим изменением положения фокальных зон.