результат перестает быть таким уж удивительным
Да, согласен. Но результату, полученному на плоскости я и не удивлялся. За то результат на сфере в этом плане гораздо более интересен. Хотя логика всё равно остаётся той же самой.
Предлагаю такую схему: разберите плоский алгоритм по вашему выбору, затем мы обсудим его перенос на сферу.
Проблема в том, что я не знаю даже за что взяться. В книге
O'Rourke - Computational Geometry in C, которую вы предложили, подробно разбирается только алгоритм, в котором диаграмма Вороного строится через выпуклую оболочку точек, получаемых проецированием с плоскости на трёхмерный параболоид. Со сферой в этом плане даже ничего проецировать не надо: погружаем в трёхмерие и стоим выпуклую оболочку. Однако алгоритм для построения выпуклой оболочки в трёхмерии не использует тот факт, что среди всех точек сферы никогда не найдётся такой, что она окажется внутри оболочки. Этот факт вообще может как-то упростить вычисления?
Брутфорсом выпуклую оболочку построить легко. В матлабе это дело даже хорошо векторизуется и занимает четыре строчки:
function indexes = get_convex_hull_brute(thetas, phis)
dsize = numel(thetas);
indexes = [nchoosek(1 : dsize, 3) flipud(nchoosek(1 : dsize, dsize - 3))];
flags = is_internal(thetas(indexes), phis(indexes));
indexes = indexes(0 == sum(flags, 2), 1 : 3);
end
Здесь, правда, всё нагрузка ложится на функцию is_internal, которая для каждой строчки координат точек через первые три точки проводит окружность, а для остальных определяет, лежат ли они внутри этой окружности или нет. Для 50 точек расчёт уже занимает секунду, поэтому надо улучшать алгоритм.
Но пока не совсем понимаю, как из полученной триангуляции строить вершины диаграммы Вороного. Если центр описанной окружности лежит внутри треугольника, то всё понятно: он и есть вершина. А что, если не лежит? Такие случаи скорее даже правило, чем исключение: