Представлен быстрый алгоритм вычисления объёма простой, замкнутой, триангулированной 3D-сетки. Это предположение — прямое следствие теоремы о дивергенции. Дальнейшие обобщения на другие типы сеток возможны, но пока выходят за рамки рассмотрения.
Отправная точка — определение объёма как тройного интеграла по области от константы, равной единице:
Пусть — функция в такая, что её дивергенция равна единице. Для целей данного вывода выбирается:
Легко проверить, что
Следовательно,
По теореме о дивергенции это равно поверхностному интегралу:
Этот поверхностный интеграл, определённый по поверхности S 3D-сетки, равен сумме своих кусочных треугольных частей. Пусть обозначает поверхность -го треугольника сетки. Тогда,
Пусть представляет -ю вершину -го треугольника. Пусть равно векторной разности между и , а аналогично равно . Каждый отдельный треугольник таким образом может быть параметризован как:
Тогда простое дифференцирование даёт:
Следовательно,
Таким образом, поверхностный интеграл можно переписать в терминах этой параметризации, подставив определение где необходимо:
Это векторное произведение постоянно на всём треугольнике и легко вычисляется по данным вершин. Достаточно вычислить только X-компоненту векторного произведения; остальные равны нулю из-за скалярного произведения с нулевыми компонентами . таким образом можно переписать как:
Далее рассматривается поверхностный интеграл . Раскрытие с помощью параметризации даёт:
Этот интеграл можно вычислить напрямую, рассматривая данные вершин как константы:
Подставляя это в исходную сумму и вынося постоянный множитель за пределы внутреннего цикла (чтобы избежать деления в цикле), получается следующая компактная формула для объёма:
Анализ производительности
Итоговый алгоритм не содержит ни численного интегрирования, ни дифференцирования. В отличие от распространённых наивных алгоритмов вычисления объёма, которые по сути эквивалентны рендерингу сетки с последующей выборкой из результата рендера — дорогостоящей операции, — здесь присутствует только один цикл, проходящий по треугольникам. Таким образом, алгоритм вычисления объёма имеет сложность O(n) относительно числа треугольников. Более того, вычисление для каждого отдельного треугольника столь же эффективно: при естественном раскрытии векторного произведения внутренняя часть содержит семь сложений и три умножения. Вне цикла требуется всего одно умножение. Таким образом, для сетки из треугольников алгоритму требуется сложений и умножений, то есть операций с плавающей точкой. Это очень быстро.
Для примерной оценки: если объём нужно вычислять каждый кадр в высокопроизводительном приложении на 60 кадров в секунду, без помощи GPU, используя только возможности CPU Raspberry Pi за $35, за один кадр можно обработать порядка 30 миллионов треугольников.
Мотивация
Скоро экзамен по векторному исчислению, и требуется к нему подготовиться. К тому же, кто не любит 3D-графику?!
Было бы (приятной) неожиданностью, если бы этот алгоритм оказался новым. Дополнительное исследование, проведённое после публикации, показало, что статья Efficient Feature Extraction for 2D/3D Objects in Mesh Representation авторства Ча Чжэн и Цухана Чена, судя по всему, описывает тот же алгоритм, хотя и с другим выводом. Было весело, пока это длилось!