Определить угол между двумя соседними ребрами меша необходимо, например, при поиске слишком острых выступающих элементов на модели, или же наоборот, недостаточно острых.
Для определения угла между двумя прилегающими к одной точке ребрами меша, удобнее всего использовать структуру bmesh.
Создадим объект bmesh и загрузим в него геометрию текущего активного меша сцены. Сразу приведем индексацию вертексов и ребер в соответствие с индексацией исходного меша.
1 2 3 4 5 6 7 |
import bmesh bm = bmesh.new() bm.from_mesh(bpy.context.object.data) bm.verts.ensure_lookup_table() bm.edges.ensure_lookup_table() |
Возьмем точку с индексом 0. К ней прилегают два ребра, между которыми мы хотим определить угол.
1 |
vert = bm.verts[0] |
Получить оба ребра, прилегающие к точке, можно через ее свойство link_edges:
1 2 |
edge0 = vert.link_edges[0] edge1 = vert.link_edges[1] |
Отталкиваясь теперь уже от ребер, определим их общую точку
1 |
vert0 = edge0.verts[0] if edge0.verts[0] in edge1.verts else edge0.verts[1] |
и две оставшиеся точки
1 2 |
vert1 = edge0.other_vert(vert0) vert2 = edge1.other_vert(vert0) |
Теперь по этим трем точкам мы можем построить два вектора, соответсвующее двум ребрам меша:
1 2 |
vec0 = vert0.co - vert1.co vec1 = vert0.co - vert2.co |
Чтобы определить угол между двумя векторами, мы можем вычислить их скалярное произведение (dot product) или же воспользоваться функцией angle объекта Vector из модуля mathutils, который делает то же самое.
1 |
angle = vec0.angle(vec1) |
На самом деле между двумя векторами существуют два угла. Чаще всего при расчетах нам нужен внутренний (меньший) из них. Функция angle вычисляет угол между векторами в правосторонней системе координат т.е. по часовой стрелке. Соответственно, мы не знаем, какой именно угол получим в результате. Однако мы можем просто сравнить угол со 180 градусами, и если он больше – значит найден внешний (больший) угол. Чтобы получить внутренний, нужно и 360 градусов отнять полученное значение.
Обратите внимание, что функция angle возвращает результат в радианах. Чтобы оперировать привычными градусами, нам нужно не забывать делать преобразования.
1 2 3 |
from math import radians, degrees angle = angle if angle < radians(180) else (radians(360) - angle) |
В результате мы получаем нужный нам угол
1 2 3 |
print(degrees(angle)) # 116.832 |