Алгоритм триангуляции сферы
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))