Какой самый простой способ вычисления главной кривизны для треугольника сетки?

19

У меня есть сетка, и в области вокруг каждого треугольника я хочу вычислить оценку основных направлений кривизны. Я никогда раньше такого не делал, и Википедия не очень помогает. Можете ли вы описать или указать мне простой алгоритм, который может помочь мне вычислить эту оценку?

Предположим, что я знаю положения и нормали всех вершин.

ap_
источник

Ответы:

24

Когда мне понадобилась оценка кривизны сетки для шейдера скина, алгоритм, на котором я остановился, был такой:

Сначала я вычислил скалярную кривизну для каждого ребра в сетке. Если ребро имеет позиции и нормали n 1 , n 2 , то я оценил его кривизну как:p1,p2n1,n2

curvatureзнак равно(n2-N1)(п2-п1)|п2-п1|2

Это вычисляет разницу в нормалях, спроецированных вдоль края, как часть длины края. (Смотрите ниже, как я придумал эту формулу.)

Затем для каждой вершины я посмотрел на кривизну всех ребер, которые касаются ее. В моем случае я просто хотел получить скалярную оценку «средней кривизны», поэтому в итоге я взял среднее геометрическое от абсолютных значений всех кривизны ребер в каждой вершине. В вашем случае вы можете найти минимальную и максимальную кривизну и считать эти ребра основными направлениями кривизны (возможно, ортонормировать их с нормалью вершины). Это немного грубо, но это может дать вам достаточно хороший результат для того, что вы хотите сделать.


Мотивация для этой формулы заключается в том, что происходит в 2D применительно к кругу:

формула кривизны применяется к двум точкам на окружности

Предположим, у вас есть круг радиуса (поэтому его кривизна равна 1 / r ), и у вас есть две точки на окружности с их нормалями nр1/р . Положения точек относительно центра окружности будут p 1 = r n 1 и p 2 = r n 2 , благодаря свойству, что нормали окружности или сферы всегда указывают прямо из его центра.N1,N2п1знак равнорN1п2знак равнорN2

Поэтому вы можете восстановить радиус как рзнак равно|п1|/|N1|или , Но в общем, положение вершин не будет относительно центра круга. Мы можем обойти это, вычитая два: p 2 - p 1|п2|/|N2|

п2-п1знак равнорN2-рN1знак равнор(N2-N1)рзнак равно|п2-п1||N2-N1|кривизназнак равно1рзнак равно|N2-N1||п2-п1|

Результат точен только для кругов и сфер. Однако мы можем расширить его, чтобы сделать его более «терпимым», и использовать его в произвольных трехмерных сетках, и, похоже, он работает достаточно хорошо. Мы можем сделать формулу более «толерантной», сначала спроецировав вектор на направление ребра, p 2 - p 1 . Это позволяет этим двум векторам быть не совсем параллельными (как в случае круга); мы просто спроецируем любой компонент, который не параллелен. Мы можем сделать это, поставив точки с нормализованным вектором ребра: кривизнаN2-N1п2-п1

кривизназнак равно(N2-N1)нормализуют(п2-п1)|п2-п1|знак равно(N2-N1)(п2-п1)/|п2-п1||п2-п1|знак равно(N2-N1)(п2-п1)|п2-п1|2

Et voilà, есть формула, которая появилась в верхней части этого ответа. Кстати, хорошая сторона выгода от использования подписанной проекции (скалярное произведение) является то , что формула затем дает подписанную кривизну: положительная результат на выпуклый, так и отрицательном для вогнутых поверхностей.


Другой подход, который я могу себе представить, используя, но не пытался, это оценить вторую фундаментальную форму поверхности в каждой вершине. Это можно сделать, установив касательный базис в вершине, затем преобразовав все соседние вершины в это касательное пространство и используя метод наименьших квадратов, чтобы найти матрицу 2FF наилучшего соответствия. Тогда основными направлениями кривизны будут собственные векторы этой матрицы. Это кажется интересным, поскольку может позволить вам найти направления кривизны, «подразумеваемые» соседними вершинами без каких-либо ребер, явно указывающих в этих направлениях, но с другой стороны, это намного больше кода, больше вычислений и, возможно, менее численно устойчиво.

Статья, в которой используется такой подход, - Русинкевич, «Оценка кривизны и ее производных на треугольных сетках» . Он работает путем оценки матрицы 2FF наилучшего соответствия на треугольник, а затем усредняет матрицы на вершину (аналогично тому, как вычисляются гладкие нормали).

Натан Рид
источник
1
К вашему сведению, если это имеет значение, я использовал ваш ответ здесь blender.stackexchange.com/questions/146819/… но добавив вес, используя угол вокруг p1. Не знаете, найдете ли вы это ценным? В любом случае, не стесняйтесь комментировать. Благодарю.
лимон
19

Просто чтобы добавить еще один способ к превосходному ответу @NathanReed, вы можете использовать среднее значение и гауссову кривизну, которые можно получить с помощью дискретного Лапласа-Бельтрами.

vя

                                         введите описание изображения здесь

A(vя)13vJ

е(vя)

ΔSе(vя)знак равно12A(vя)ΣvJN1(vя)(соTαяJ+соTβяJ)(е(vJ)-е(vя))

vJN1(vя)vя

При этом довольно просто вычислить среднюю кривизну (теперь для простоты давайте назовем функцию вашей сетки в интересующей вершине просто v

ЧАСзнак равно12||ΔSv||

θJ как

                                        введите описание изображения здесь

Гауссова кривизна:

Кзнак равно(2π-ΣJθJ)/A

После всей этой боли основные дискретные искривления даются:

К1знак равноЧАС+ЧАС2-К  и  К2знак равноЧАС-ЧАС2-К

Если вы интересуетесь этой темой (и добавите некоторую ссылку на этот пост), вы можете прочитать следующее: Операторы дискретной дифференциальной геометрии для триангулированных 2-многообразий [Meyer et al. 2003].

За изображения я благодарю своего бывшего профессора Нилой Митру, поскольку я нашел их в некоторых заметках, которые я сделал для его лекций.

cifz
источник
Оба ответа действительно хороши, мне было трудно выбрать. Поскольку я спросил о простейшем способе, я думаю, Натан берет торт.
ap_
2
Кзнак равно(π-ΣJθJ)/AмяИксеd
@teodron Может быть, у вас есть понимание средней кривизны для вершин границы? Можно ли это определить?
Музейный
vя
-1

@ Натан-Рид: Просто вопрос к ответу Натана-Рида: почему вы использовали среднее геометрическое? Было ли это потому, что оно «смоделировано» после гауссовой кривизны?

Габриель
источник
3
Если у вас есть новый вопрос, задайте его, нажав кнопку « Задать вопрос» . Включите ссылку на этот вопрос, если это помогает обеспечить контекст. - Из обзора
Dragonseel