Алгоритм триангуляции сферы
21 октября 2024, 18:39
От автора @mr.shruslan@mail.ru
Для тестирования идеи будем пользоваться Python скриптом, который вшит в NVP платформу. Можно сразу визуализировать свои мысли и быстро править ошибки.
Алгоритм будет таким (я сам придумал😅):
1. Определяем точки координаты сечений сферы по высоте.
new_center = start_center + R * math.sin(alpha * n) # Координаты центра
new_radius = start_radius * math.cos(rad) # Радиус окружности
2. Получаем точки каждой окружности в равном кол-ве. Для этого уже есть абстракция Polygon. И по сути окружность - это и есть полигон, только углов много.
3. Идем циклом по всем окружностям попарно и соединяем точки по треугольникам.
4. Рендерим получившиеся треугольники
Давайте посмотрим, что получится в итоге:
import math
from System.Collections.Generic import *
# входные данные
sphere_radius = Inputs[0]
center = Inputs[1]
segments_count = int(Inputs[2])
# угол для получения сечений от центра сферы
alpha = 180 / segments_count
# число углов многоугольника для окружности
angle_count = segments_count
# вектор для смещения многоугольника
vector_z = Context.CreatePoint(0,0,1)
polygons = []
# определение кол-ва сегментов вверх/вниз по углу
start_end_range = int(segments_count / 2)
for i in range(-start_end_range, start_end_range):
# определяем угол в радианах
rad = math.radians(alpha * i)
# получаем соординату центра сечения сферы
new_center_z = center.Z + sphere_radius * math.sin(rad)
new_center = Context.CreatePoint(center.X, center.Y, new_center_z)
# получаем радиус сечения сферы
new_radius = sphere_radius * math.cos(rad)
# рисуем полигон с помощью средств NVP
polygon = Context.CreatePolygon(new_center, new_radius, angle_count, 0, False)
polygons.append(polygon)
# визуализируем треугольники
for i in range(1, len(polygons)):
first = polygons[i-1]
second = polygons[i]
# достаем точки из полигона 1
first_points = list(first.GetPoints())
# достаем точки из полигона 2
second_points = list(second.GetPoints())
# рисуем линии треугольников для визуализации
for p_i in range(1, len(first_points)):
fp1 = first_points[p_i-1]
fp2 = first_points[p_i]
sp1 = second_points[p_i-1]
sp2 = second_points[p_i]
Context.CreateLine(fp1, sp1)
Context.CreateLine(fp2, sp1)
Context.CreateLine(fp2, sp2)
Result.Set(List[object](polygons))