Blender > BLENDERMETRY (Блендерметрия)

Blender и векторная алгебра

(1/1)

sungreen:
Было бы скучно если бы в blender не было модуля mathutils
Этот модуль предоставляет доступ к таким классам как Color, Euler, Matrix, Quaternion, Vectors.

Если нам нужно сделать модификацию меша, то  модуль mathutils предоставит широкий набор возможностей.

Итак то что касается векторов:
Создать вектор можно задав три координаты (x,y,z)


--- Код: python ---import bpy
import mathutils

a = mathutils.Vector((0.0, 1.0, 2.0))
b = mathutils.Vector((1.0, 4.0, 1.0))
print("Вектор а",a)
print("Вектор в",b)

--- Конец кода ---


--- Цитировать ---Вектор а <Vector (0.0000, 1.0000, 2.0000)>
Вектор в <Vector (1.0000, 4.0000, 1.0000)>

--- Конец цитаты ---

Если нужно сделать нормализацию вектора:

--- Код: python ---b.normalize()
print("Нормализованный вектор",b)
print("Длина вектора",b.length)

--- Конец кода ---



--- Цитировать ---Нормализованный вектор <Vector (0.2357, 0.9428, 0.2357)>
Длина вектора 1.0000000707805132

--- Конец цитаты ---


Теперь о вкусностях!
операции над векторами :

--- Код: python ---c=a+b
print("a+b",c)

c=a-b
print("a-b",c)

c=a*b
print("a*b",c)

c=a*3.7
print("a*3.7",c)

--- Конец кода ---


--- Цитировать ---a+b <Vector (0.2357, 1.9428, 2.2357)>
a-b <Vector (-0.2357, 0.0572, 1.7643)>
a*b 1.4142136573791504
a*3.7 <Vector (0.0000, 3.7000, 7.4000)>

--- Конец цитаты ---

Угол между двумя векторами:


--- Код: python ---u=a.angle(b)
print("Угол между двумя векторами",u)

--- Конец кода ---


--- Цитировать ---Угол между двумя векторами 0.8860771059989929
--- Конец цитаты ---

Векторное произведение (cross product) и скалярное произведение (dot product):

--- Код: python ---c=a.cross(b)
print("Векторное произведение",c)

c=a.dot(b)
print("скалярное произведение",c)
--- Конец кода ---


--- Цитировать ---Векторное произведение <Vector (-1.6499, 0.4714, -0.2357)>
скалярное произведение 1.4142136573791504

--- Конец цитаты ---

Интерполяция между двумя векторами, где f - фактор интерполяции от 0 до 1

--- Код: python ---for i in range(11):
    f=i/10
    c=a.lerp(b,f)
    print(f,c)

--- Конец кода ---

--- Цитировать ---
0.0 <Vector (0.0000, 1.0000, 2.0000)>
0.1 <Vector (0.0236, 0.9943, 1.8236)>
0.2 <Vector (0.0471, 0.9886, 1.6471)>
0.3 <Vector (0.0707, 0.9828, 1.4707)>
0.4 <Vector (0.0943, 0.9771, 1.2943)>
0.5 <Vector (0.1179, 0.9714, 1.1179)>
0.6 <Vector (0.1414, 0.9657, 0.9414)>
0.7 <Vector (0.1650, 0.9600, 0.7650)>
0.8 <Vector (0.1886, 0.9542, 0.5886)>
0.9 <Vector (0.2121, 0.9485, 0.4121)>
1.0 <Vector (0.2357, 0.9428, 0.2357)>
--- Конец цитаты ---

Негатив, проекция вектора a на вектор b, отражение вектора:

--- Код: python ---c=a
c.negate()
print("негатив",c)

c=a.project(b)
print("проекция",c)

c=a.reflect(b)
print("отражение",c)
--- Конец кода ---


--- Цитировать ---негатив <Vector (-0.0000, -1.0000, -2.0000)>
проекция <Vector (-0.3333, -1.3333, -0.3333)>
отражение <Vector (0.6667, 1.6667, -1.3333)>

--- Конец цитаты ---

поворот вектора:
c=a.rotate(Euler or Quaternion or Matrix) для поворота нужно указать один из компонентов


модуль mathutils.geometry

Площадь треугольника
area_tri(v1, v2, v3)

Расстояние от точки до плоскости
distance_point_to_plane(pt, plane_co, plane_no)

Пересечение двух линий
intersect_line_line(v1, v2, v3, v4)

Пересечение лини и плоскости
intersect_line_plane(line_a, line_b, plane_co, plane_no, no_flip=False)

Пересечение линии сферы
intersect_line_sphere(line_a, line_b, sphere_co, sphere_radius, clip=True)

Пересечение двух планов
intersect_plane_plane(plane_a_co, plane_a_no, plane_b_co, plane_b_no)

Очень нужная вещь - тесселяция полигона
tesselate_polygon(veclist_list)

sungreen:
... при подготовке модели к печати мне нужно было провести несколько тестов меша на наличие пересечений файсов ...
... видимо отсутствие меха в рендере cycles настолько печалит, что входе этих экспериментов как-то само собой получил такое направление ...
... суть проста - для каждого фейса найти нормаль и откинуть от него пирамидку ...
... то есть если файс задан векторами p0, p1, p2 , тогда вектор нормали к поверхности фейса будет n = normal(p0,p1,p2), а вектор вершины пирамидки pn = pc + n, где собственно pc - это вектор центра фейса равный (p0+p1+p2)/3 ...
... коэффициент nkf определяет высоту пирамидки, мну взял 0.3 ...
... для каждого фейса это делает вот такая процедура:


--- Код: python ---def test(qverts,qedges,qfaces,nv,edges,nodes):
    nkf = 0.3

    p0 = nodes[nv[0]].co
    p1 = nodes[nv[1]].co
    p2 = nodes[nv[2]].co
    pc = (p0 + p1 + p2) / 3
    pn = pc + mathutils.geometry.normal(p0,p1,p2) * nkf
   
   
    last=len(qverts)
    qverts.extend([pn,p0,p1,p2])
    qfaces.extend([[last,last+1,last+2],[last,last+2,last+3],[last,last+3,last+1]])

--- Конец кода ---


... на рисунке 1 представлена Сюзанна, а на рисунках 2,3,4 она же с различными параметрами модификатора сглаживания, который определяет количество разбиений и следовательно количество фейсов и в итоге количество пирамидок ...
1


2   k = 1


3   k = 2


4   k = 3



... вот полный текст кода, а во вложении сам файл с моделью ...

--- Код ---
import bpy
import mathutils, math, struct


def make_mesh(name):
    me = bpy.data.meshes.new(name)
    ob = bpy.data.objects.new(name, me)
    bpy.context.scene.objects.link(ob)
    return ob

def add_data(ob,verts,edges,faces):
    me = ob.data
    me.name = ob.name +' mesh'
    me.from_pydata(verts,edges,faces)
    me.update()
   

def test(qverts,qedges,qfaces,nv,edges,nodes):
    nkf = 0.3

    p0 = nodes[nv[0]].co
    p1 = nodes[nv[1]].co
    p2 = nodes[nv[2]].co
    pc = (p0 + p1 + p2) / 3
    pn = pc + mathutils.geometry.normal(p0,p1,p2) * nkf
   
   
    last=len(qverts)
    qverts.extend([pn,p0,p1,p2])
    qfaces.extend([[last,last+1,last+2],[last,last+2,last+3],[last,last+3,last+1]])         

def main():
   
   
    obj = bpy.data.objects["Cube"]
    mesh = obj.to_mesh(bpy.context.scene, True, 'PREVIEW')
       
    faces = mesh.tessfaces
    edges = mesh.edges
    nodes = mesh.vertices
       
    print('%d' % len(edges))
    print(' %d\n' % len(faces))

    qverts=[]
    qedges=[]
    qfaces=[]


    for face in faces:
        vertices = face.vertices[:]
        if len(vertices) == 4:
            test(qverts,qedges,qfaces,(vertices[0], vertices[1], vertices[2]),edges,nodes)
            test(qverts,qedges,qfaces,(vertices[2], vertices[3], vertices[0]),edges,nodes)
        else:
            test(qverts,qedges,qfaces,vertices,edges,nodes)


    ob=make_mesh("Test")
    add_data(ob,qverts,qedges,qfaces)

main()
--- Конец кода ---

[вложение удалено Администратором]

LanuHum:
sungreen, не ищи подвоха в моих вопросах, но объясни мне, что в блендере есть вектор, если, можно, конечно???
Я никак не вкурю.

--- Цитировать ---Вектор в <Vector (1.0000, 4.0000, 1.0000)>
--- Конец цитаты ---
Что это? Я понимаю полигон с координатами - всё ясно. Куда засовывать векторы? К чему это понятие применимо, и, что даёт изменение векторов?
Серьёзно, сделал бы ты статейку про векторы. Я пишу аддоны, но, когда речь заходит о векторах и нормалях, мне кажется, что я ужасно тупой.
Очень хотелось бы на русском прочитать о том, что есть векторы применительно к Блендеру, к его объектам и их редактированию.

sungreen:
... не то чтобы это honeypot, но темы из Блендерметрии нацелены не столько на объяснение, сколько на поиск людей, которым это было бы интересно ...
... по шквалу ответов можно сделать выводы  ??? ...
... но нет особого отличия векторной алгебры в Blender или в токарном деле, вектор он и в Африке вектор ...

>> "Куда засовывать векторы? К чему это понятие применимо, и, что даёт изменение векторов?
... по сути это оснастка для манипулирования координатами вершин, нормалями, вычисления углов между векторами, площадей, матриц и т.п., оформленная в виде модуля со своими типами и процедурами, что облегчает написание скриптов ...
... то есть при необходимости из представления объекта как совокупности вершин, набора ребер и граней, можно перейти к представлению в векторной форме и далее в рамках дозволенного ...
... простой пример Фрактал Серпиского http://blender-3d.ru/forum/index.php/topic,327.0.html  в котором координаты вершин вычисляются в векторной форме v = (v1+v2)/2, что соответствует
x = (x1+x2)/2
y = (y1+y2)/2
z = (z1+z2)/2

еще
http://blender-3d.ru/forum/index.php/topic,602.msg6164.html#msg6164
http://blender-3d.ru/forum/index.php/topic,414.msg5190.html#msg5190
http://blender-3d.ru/forum/index.php/topic,421.msg4970.html#msg4970

sungreen:
Сделал небольшой макет из узлов геометрии для генерации соцветий https://www.youtube.com/watch?v=x5l1-cajRQ0 , .blend файл можно скачать по ссылке https://disk.yandex.ru/d/3P4BT5sA9fREog

Навигация

[0] Главная страница сообщений

Перейти к полной версии