Автор Тема: Blender и векторная алгебра  (Прочитано 3820 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн sungreen

  • ...
  • Житель
  • Kostroma mon amour
    • sungreen.github.io
Blender и векторная алгебра
« : 26 Февраля 2012, 21:37:18 »
Было бы скучно если бы в 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)
« Последнее редактирование: 28 Февраля 2012, 06:53:27 от sungreen »
Для Кота

Оффлайн sungreen

  • ...
  • Житель
  • Kostroma mon amour
    • sungreen.github.io
Re: Blender и векторная алгебра
« Ответ #1 : 12 Августа 2012, 09:53:51 »
... при подготовке модели к печати мне нужно было провести несколько тестов меша на наличие пересечений файсов ...
... видимо отсутствие меха в рендере 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()
« Последнее редактирование: 12 Августа 2012, 10:24:13 от sungreen »
Для Кота

Оффлайн LanuHum

  • Житель
Re: Blender и векторная алгебра
« Ответ #2 : 28 Июня 2014, 20:13:39 »
sungreen, не ищи подвоха в моих вопросах, но объясни мне, что в блендере есть вектор, если, можно, конечно???
Я никак не вкурю.
Цитировать
Вектор в <Vector (1.0000, 4.0000, 1.0000)>
Что это? Я понимаю полигон с координатами - всё ясно. Куда засовывать векторы? К чему это понятие применимо, и, что даёт изменение векторов?
Серьёзно, сделал бы ты статейку про векторы. Я пишу аддоны, но, когда речь заходит о векторах и нормалях, мне кажется, что я ужасно тупой.
Очень хотелось бы на русском прочитать о том, что есть векторы применительно к Блендеру, к его объектам и их редактированию.
« Последнее редактирование: 28 Июня 2014, 20:21:22 от LanuHum »

Оффлайн sungreen

  • ...
  • Житель
  • Kostroma mon amour
    • sungreen.github.io
Re: Blender и векторная алгебра
« Ответ #3 : 28 Июня 2014, 22:10:47 »
... не то чтобы это 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
« Последнее редактирование: 28 Июня 2014, 22:34:53 от sungreen »
Для Кота

 

* По форуму

* Последние вложения

Sizes.jpg
Скачано: 9
Автор: Dmi3ryd
paticles.jpg
Скачано: 5
Автор: Dmi3ryd
Снимок 1.PNG
Скачано: 3
Автор: atmk
Снимок.PNG
Скачано: 3
Автор: atmk
Screw.jpg
Скачано: 8
Автор: Dmi3ryd