При процедурном моделировании в Blender при помощи Geometry Nodes, мы часто используем различные параметры геометрии меша, например, положение вертексов в пространстве, длину ребер, направление нормали. Также достаточно часто нам нужно знать угол между двумя соседними ребрами меша. Получить его при помощи нод GN и математики не составляет большого труда.
Для начала добавим на сцену плейн (Shift + a – Mesh – Plane) и сделаем из нее треугольник объединив две вершины в режиме редактирования (m – Collapse). Чуть передвинем вершины, чтобы треугольник получился не равнобедренным.
Добавим модификатор Geometry Nodes и инициируем новое дерево нод, нажатием на кнопку New.
Для того чтобы рассчитать угол между двумя любыми ребрами меша, нам нужно получить два вектора, лежащие вдоль этих ребер и выходящие из их общей точки. А для векторов при помощи математики мы легко найдем угол между ними.
Начнем отталкиваться от вертексов, т.к. каждый вертекс у нас соединен как раз с двумя ребрами, угол между которыми мы хотим получить.
Добавим нод Index (shift + a – Geometry – Read – Index).
С его выхода Index мы получим список индексов всех точек меша. В нашем случае:
1 |
[0, 1, 2] |
Имея индекс вертекса, мы можем получить индексы обоих примыкающих к нему ребер при помощи нода Edges of Vertex.
Этот нод по индексу вертекса получает список индексов всех примыкающих к нему ребер. Например, для вертекса с индексом 0 внутри нода Edges of Vertex будут получены ребра с индексами 0 и 2.
Однако с выхода Edge Index этот нод возвращает только первый в списке индекс из всех полученных индексов ребер.
Чтобы получить индекс второго примыкающего к вертексу ребра, мы можем сдвинуть сортировку в списке индексов ребер нода Edges of Vertex, через его параметр Sort Index. Если мы оставим в нем значение 0, мы получим индекс первого примыкающего к точке ребра, а если поставим 1, получим индекс второго примыкающего к точке ребра, за счет того, что последний индекс при сдвиге переносится на первое место.
Итак, добавим два нода Edge of Vertex (Mesh – Topology – Edge of Vertex) и в одном из них укажем в поле Sort Index значение 1. Подадим на них индексы точек с нода Index.
Теперь для каждого вертекса мы имеем два индекса прилегающих к нему ребер.
Теперь нам нужно по индексу ребре получить его координаты в пространстве. То есть перейти от ребра к вектору, лежащему вдоль ребра.
Это можно сделать при помощи нодов Sample Index и Position.
Добавим нод Position (shift + a – Geometry – Read – Position). С него мы получим координаты для наших ребер.
Для каждого из индексов ребер добавим по ноду Sample Index (shift + a – Geometry – Sample – Sample Index). Этот нод позволит получить положение ребра именно для заданного нами индекса. Соединим ноды, подав на входные сокеты геометрию, положение с нода Position и индекс с нодов Edge of Vertex.
Для правильного расчета нужно переключить домен у нода Sample Index в Edges и атрибут в векторный тип Vector.
Сейчас на выходе Vector каждого нода Sample Index мы получили координаты для ребер относительно опорной точки. Сдвинем их так, чтобы опорная точка находилась в начале координат.
Это легко сделать, вычтя текущее значение вектора из его положения в пространстве, которое мы уже получали через нод Position.
Добавим два нода Vector Math (shift + a – Utilities – Vector – Vector Math) и переключим их в режим вычитания Subtract.
Нод Position мы можем использовать уже добавленный или добавить еще раз его копию, чтобы сделать дерево нодов менее запутанным.
Соединим векторные выходы нодов Position и Sample Index для каждого нода Vector Math.
Итак, сейчас на каждую точку меша у нас есть два абстрактных вектора, которые выходят из начала координат и направлены соответственно прилегающим к этой точке ребрам.
Значение угла между этими векторами мы можем теперь легко получить при помощи математики. Угол между векторами определяется как арккосинус скалярного произведения этих двух векторов после нормализации.
Нормализация (приведение к единичной длине) векторов нам нужна, чтобы избавиться при расчётах от влияния длин этих векторов.
Добавим еще два нода Vector Math, переключим их в режим Normalize и соединим с нашими векторами.
Теперь, когда наши вектора имеют единичную длину, получим для них скалярное произведение.
Добавим еще один нод Vector Math и переключим его в режим Dot Product. Подадим на него наши нормализованные вектора.
Чтобы получить значение угла, возьмем арккосинус от полученного скалярного произведения.
Добавим нод Math (shift + a – Utilities – Math – Math) и переключим его в режим Arccosine. На выходе нода и будет наш искомый угол.
Теперь для каждой точки меша мы получили угол между двумя прилегающими к ней ребрами.
Добавим нод Viewer (shift + a – Output – Viewer), подадим на него полученный результат и активируем просмотр, нажав на “глазик”. В Overlays вьюпорта необходимо так же активировать чекбокс Attribute Text, чтобы видеть выводимые значения в окне вьюпорта.
Так как арккосинус выдает нам значения в радианах, для удобства просмотра переведем их в градусы, добавив дополнительный нод Math в режиме To Degrees в самый конец нашего нодового дерева.
Теперь мы можем удобно визуально контролировать угол прямо на экране вьюпорта.