Взаимодействие ткани с внешними факторами

Введение.

Компьютерная  графика нашла широкое распространение и применение в повседневной жизни. Учёные используют компьютерную графику для анализа результатов моделирования. Инженеры и архитекторы используют трёхмерную графику для создания виртуальных моделей. Кинематографисты создают спецэффекты или полностью анимированные фильмы («Шрек», «История игрушек» и др.). В последние годы широкое распространение получили также компьютерные игры, максимально использующие трёхмерную графику для создания виртуальных миров.

Компьютерная графика  в настоящее время сформировалась как наука об аппаратном и программном  обеспечении для разнообразных  изображений от простых чертежей до реалистичных образов естественных объектов. Компьютерная графика используется почти во всех научных и инженерных дисциплинах для наглядности  и восприятия, передачи информации.

Данную работу я посвятила  реализации свойств ткани, взаимодействие ткани с внешними факторами, такими как сила тяжести, ветер, а  также взаимодействие с другими объектами (сферой).

При анимации некоторых сцен часто возникает необходимость сделать так, чтобы объекты подчинялись физическим законам, действующим в реальном мире.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ткани – это  объекты реального мира, оптическое моделирование и визуализация которых  являются особенно сложными. Сложность  задачи характеризуется огромным числом элементов ткани.

Задача моделирования  деформации тканей является важной для  ее реалистичного изображения, так  как ткань не может принимать  произвольную форму, поскольку все  ее деформации подчинены законам  физики.

Могут быть выделены два класса задач моделирования  деформации ткани:

• Деформация ткани без учета коллизий. Здесь  форму и деформацию ткани определяют обычно внешние силы, присутствующие в сцене, такие, например, как гравитация или ветер, и не принимаются во внимание другие объекты сцены.

• Деформация ткани с учетом коллизий. Здесь  вычисляются пересечения (без проникновения) ткани самой с собой, а также  с другими объектами, присутствующими  в сцене.

В общем случае все методы моделирования деформации ткани  можно разделить на два типа: геометрические (методы, основывающиеся на геометрических свойствах ткани) и физические (методы, основывающиеся на физических свойствах  ткани).

Геометрические методы не учитывают физические характеристики ткани, такие как масса, эластичность и пр. Они представляют ткань с  помощью геометрических уравнений. Эти методы подходят для моделирования  объектов, отдельных от всей остальной  сцены и имеющих простую форму.

Физические методы наоборот принимают во внимание физические характеристики рассматриваемой ткани. От метода к  методу могут учитываться масса, эластичность,  упругость материала. Ткань моделируется с применением  законов механики. Эти методы представляют объекты с помощью дифференциальных уравнений. Результаты моделирования  с помощью этого класса методов  обычно более реалистичны, чем результаты моделирования с помощью геометрических методов. Они также требуют большего времени вычисления.

 

Алгоритм построения ткани:

    1. Разбиваем ткань на точки, считаем их массы.
    2. Считаем силы, действующие на точки (внутренние + внешние).
    3. Зная силу и массу, вычисляем ускорение, скорость и, наконец,  перемещение

 

Насчет  массы, выше - это лишь конструктор. Есть функция, которая назначает  массу для каждой точки (исходя из плотности материала и линейных размеров, а также положения точки, в углу, на краю или же в середине). В результате на точки действует  сила тяжести, а после первой итерации начинают действовать внутренние силы и сила затухания.

Список  литературы:

  • http://cg.alexandra.dk/2009/06/02/mosegaards-cloth-simulation-coding-tutorial/
  • http://freespace.virgin.net/hugo.elias/models/m_cloth.htm
  • Б. Барладян. Моделирование освещенности в тканях с четкой фактурой нити.
  • http://www.opengl.org.ru/
  • Рэнди Дж. Рост "OpenGL Трехмерная графика и язык программирования"
  • Эйнджел, Эдвард. "Интерактивная компьютерная графика. Вводный курс на базе OpenGL"
  • http://gamedev.kz/?q=node/14

 

 

 

Решение:

Ткань состоит из маленьких  частичек  и связей. Частицы хоть и не имеют размеры, должны иметь  координаты (x, y, z), скорость (vx, vy, vz) и мгновенное ускорение (ax, ay, az). Все три величины векторы, поэтому имеют по 3 координаты. Рассчитываем ускорение каждой частицы по 2 закону Ньютона: F = m * a => a = F / m.

В системе существуют две  силы: сила тяжести F = m * g и сила притяжения, которая находится по закону Гука для связи частиц F = k * dl. Таким образом ускорение частицы будет получаться как a = g + k * dl / m.  Зная ускорение a, нужно изменить значения скорости и позиции: v = v + a * dt, x = x + v * dt. Эти действия выполняются каждый кадр.

Работа Вейла (Weil)

Вейлбыл первым, кто моделировал ткань каким-либо образом. Его работа 1986 года использовала простую геометрическую модель, произошедшую из теории кабеля. Он работал над специфической проблемой подвешивания тканей на конечном множестве точек (например, на трех или четырех точках).

Кабель под собственным  весом в устойчивом положении  формировал цепную кривую. Эта кривая описывалась уравнением: y = a cosh(x/b)

Ту же логику можно распространить на трехмерное пространство для ткани. Ткань, подвешенная на конечном числе  точек - логическое расширение цепной кривой в плоскости. Таким образом мы можем использовать систему цепных кривых, чтобы представить ткань.

Пусть, ткань подвешена  на точках. Располагаем цепные кривые между двумя диагоналями, которые, разумеется, пересекаются. Все,что нужно сделать - это найти результирующую кривую, но чтоб упростить работу - игнорируем нижнюю из двух кривых.

На данном этапе мы имеем  грубую каркасную модель формы ткани. Далеес следует улучшать форму, деля ткань на меньшие и меньшие треугольники и располагая в них цепные линии. В зависимости от требуемой точности моделируемой формы, определяется момент прекращения итераций.

В этом уроке я дам простое и интуитивно понятный объяснения о том, как кодировать тканью симулятор использованием второго закона Ньютона , Верле интеграции и итерационные удовлетворения ограничений . Я не ожидаю, что вы знаете этих терминов - или физике по этому вопросу. Учебник сопровождается легким для чтения исходного кода в объектно-ориентированных C + +. Я выбрал минимальную зависимость от внешних библиотек (OpenGL и перенасыщение)

Ткань состоит из частиц и ограничений    

Моделирование ткани, на самом деле о моделировании частиц с массой и взаимосвязей, называются ограничениями  или пружины, между этими частицами - думать о них как волокна в  ткани. Частицы перемещаться в пространстве за счет сил, которые влияют на них - например, ветер, гравитация, или пружины между частицами.

Частицы: от войска на позиции,

В качестве первого шага мы хотели бы иметь возможность влиять частиц с силами и подсчитать, сколько, что  сдвигает свои позиции - в течение  небольшого количества времени. Для этого мы должны использовать два куска знаний.

  1. Насилие можно "перевести" на ускорение через второй закон Ньютона: ускорение = сила / масса
  2. Ускорение может быть "переведены" в положение с помощью численного интегрирования - с позиции дважды дифференцировать равна ускорение.

Пункт 1 легко и просто переводит  в следующий способ (на частицу  класс):

void addForce(Vec3 f)

{

acceleration += f/mass;

}

Если  пункт № 2 не делает интуитивно смысл  для вас, подумайте о автомобиля, движущегося по дороге. Если построить график пройденного расстояния во времени, градиент в данный момент времени является скорость автомобиля. При печати скорость на график и принять кривизны в данный момент времени вы получите ускорение вашего автомобиля (изменение скорости / скорости). Для перехода от ускорения к позиции, которую мы должны сделать "обратную" дифференциации, а именно интеграции. Интеграция рутины мы будем использовать, называется Верле интеграции . Чистая integation Верле выглядит следующим образом (но обратите внимание, что мы будем изменять его ниже, чтобы включить затухание в исходном коде)

Vec3 temp = pos;

pos = pos + (pos-old_pos) + acceleration*TIME_STEPSIZE2

old_pos = temp;

Чтобы понять это интуитивно мне нравится думать о проблеме в геометрической прогрессии. Давайте начнем с частицей, которая не движется (POS old_pos и те же). Допустим, что мы хотели бы, чтобы подтолкнуть частицы, применяя некоторые вектора ускорения:

Интуитивно  понятно, что частица должна двигаться  в направлении вектора ускорения. С этим сценарием в виду, вышеприведенная формула интеграции Верле просто говорит, чтобы компенсировать текущее положение по вектору ускорения. (Смещение масштабируется с размером шага времени, чтобы объяснить тот факт, что частица должна двигаться меньше количества когда часть времени мало, и наоборот). В нашем конкретном сценарии consequense в том, что текущие изменения позиции, и старая позиция остается прежней.

Теперь давайте  предположим, что мы не влияют на частицы  с ускорением для следующего шага по времени. Интуитивно понятно, что частица должна двигаться в направлении, которое мы выдвинули его. Реализуется через срок (old_pos-POS), вектор из old_pos в положение, в формулу интегрирования Верле - неявно представляющие вектора скорости. Следующим шагом по времени, будут, следовательно выглядеть следующим образом:

Чтобы попасть  в окончательный код, используемый в проекте мы будем включать различные демпфирующие (эвристического объяснить постепенной потере скорости, например, из-за сопротивления воздуха). Самый простой способ сделать, это просто умножить вектор скорости (old_pos-полюсный) с суммой от 0 до 1. Ближе к нулю, делает частицы двигатель медленнее и медленнее каждом шаге по времени. Количество ближе к одному позволяет частицу двигаться неограниченно. Так как мы хотели бы указать на затухание, сумма, которую мы умножим на это (1,0-демпфирование). Это выписывает вот так:

pos = pos + (pos-old_pos)*(1.0-DAMPING) + acceleration*TIME_STEPSIZE2

Окончательный исходный код для нашего метода интегрирования Верле в частице класа

void timeStep()

{

if(movable)

{

Vec3 temp = pos;

pos = pos + (pos-old_pos)*(1.0-DAMPING) + acceleration*TIME_STEPSIZE2;

old_pos = temp;

acceleration = Vec3(0,0,0); // acceleration is reset since it HAS been translated into a change in position (and implicitely into velocity)

}

}

Ограничения: двигаться  частицы обратно на свои места!

Перемещение частиц вокруг прекрасно, если вы просто хотите простой системы частиц без  связей между ними, - но мы хотим большего! Мы хотели бы, чтобы ограничить движение частиц, так что они пытаются остаться в сетке. Более "эффективным" Мы находимся на возвращении всех частиц в той же относительной позиции, более жесткая ткань будет себя вести. Обратите внимание, что это не просто возможность «перезагрузить» все частицы к первоначальному Текущее местоположение, так как это противоречит нашим желанием влиять на ткани с других сил, таких как ветер и гравитация. Мы основываем наши соединения на ограничения расстояний между парами частиц. Таким образом, каждое ограничение между двумя частицами имеет расстояние, что он хотел бы вернуться, чтобы за тканью, чтобы быть в состоянии покоя - мы называем это расстояние rest_distance . В Verlet интеграции, как описано выше, частицы движутся вокруг, в результате чего частицы, которые находятся слишком далеко друг от друга или слишком близко друг к другу. Для этого мы вводимудовлетворения ограничений для изменения положения двух частиц, так что расстояние между ними вновь rest_distance.На следующих рисунках показаны две частицы слишком далеко друг от друга:

 

Удовлетворение  ограничений работает посредством  перемещения P1 и P2 по линии, соединяющей  их, так что они вновь придется на расстояние, равное rest_length. Для поддержания симметрии будут двигаться p1 и p2 на ту же величину (или друг к другу, или друг от друга, чтобы удовлетворить ограничение). Как оказалось, если мы найдем вектор (мы называем это corrrectionVectorHalf) для перемещения Р1, мы можем использовать тот же вектор в противоположном направлении двигаться Р2. Рассмотрим вектор от P1 до P2. Сам по себе он слишком длинный вектор смещения, которые будут использоваться на Р1 (было бы свести все это путь к Р2). Мы найдем фактора умножить это вектор с, чтобы удовлетворить P1 (половина) ограничения. Этот фактор в точности (1 - rest_distance / current_distance) * 0,5 . 0,5 исходит из того, что мы переходим p1 только половину так, чтобы удовлетворить условию (p2 перемещает вторую половину). Остальные коэффициент может быть интерпретировано как нахождение процент всей p1 вектор р2, что находится вне rest_length - то есть, мы берем 100%, и вычесть rest_distance как процент от всей дистанции. В целом метод satisfyConstraint на ограничении класса выглядит следующим образом:

void satisfyConstraint()

{

Vec3 p1_to_p2 = p2->getPos()-p1->getPos(); // vector from p1 to p2

float current_distance = p1_to_p2.length();

Vec3 correctionVector = p1_to_p2*(1 - rest_distance/current_distance);

Vec3 correctionVectorHalf = correctionVector*0.5;

p1->offsetPos(correctionVectorHalf);

p2->offsetPos(-correctionVectorHalf);

}

Тканевые: Создание ткани

Мы  подключим частицы в определенном порядке, чтобы сделать ткань  вести себя реально. Ткань должна оставаться как в виде сетки в плоскости ткани (структурных ограничений), сопротивление сдвига в плоскости ткани (сдвиг ограничения), а сопротивление изгиба (изгиб ограничение). Ниже показано как ограничения строятся для каждой частицы (в красном).Обратите внимание, что ток (красный) частица будет в конечном итоге ограничивает более чем показано поскольку этот образец ограничений повторяется для каждой частицы.

В сопровождающих исходный код наращивание ткани  соединений реализуется в ткань  конструктора с использованием частиц и ограничений.

Тканевые: дует ветер, гравитация и столкновения с мячом

Чтобы ткань есть интересное динамическое поведение мы добавим силы ветра и силу тяжести. Мы также будем обрабатывать столкновение с движущимся мячом. Добавление тяжести очень легко, мы просто добавляем вектор ускорения направлен вниз, чтобы все частицы (через ADDFORCE методом на ткани объекта). Обнаружение столкновения и обработку также относительно легко, и я не буду вдаваться в подробности. Мяч определяется центром и радиусом. Обнаружение столкновения делается посредством запроса ли частица находится в пределах радиуса шара, если да столкновений будет решена путем перемещения частиц из шара вдоль вектора от центра к частице так, что расстояние равно радиусу мяча .

Добавление  ветер немного сложнее, но дает очень  хороший эффект. Мы начнем, глядя на ткани в виде набора из трех треугольников каждой частице, и решить проблему добавлением ветра один треугольник за один раз - сложение сил в трех частиц состоит из треугольника. Ветер дует в определенном направлении, но силы должны быть добавлены только в направлении нормали треугольника (или отрицательных нормально), и количество силы, действующей на треугольнике должно быть пропорционально углу (скалярного произведения) между Треугольник и ветер. Это все сводится к простой формуле для одного треугольника:

void addWindForcesForTriangle(Particle *p1,Particle *p2,Particle *p3, const Vec3 direction)

{

Vec3 normal = calcTriangleNormal(p1,p2,p3);

Vec3 d = normal.normalized();

Vec3 force = normal*(d.dot(direction));

p1->addForce(force);

p2->addForce(force);

p3->addForce(force);

}

Добавление ветра

Добавление ветра на ткань  позволяет моделировать развевающиеся  флаги и другие ткани + ветер вида ситуаций. Эта модель не является абсолютно точным. Ветер влияет на ткань, но ткань не влияет на ветер, для этого потребуется огромное количество жидкости, динамический расчет. Тем не менее, она производит разумную глядя развевающиеся эффектов. Для этого вам необходимо будет моделирования ткани с массой.

Первая ткань  должна быть разбита на треугольники. Это легко сделать, так как ткань уже описан как массив точек. Воздействие ветра на ткань рассчитана на каждый из этих треугольников индивидуально. В каждой точке ткань, сумма воздействие ветра на окружающую треугольника вычисляется. 

Сила, действующая  на треугольник в связи с молекулами воздуха отскакивая он всегда будет в направлении вектора нормали этого треугольника. Вектор нормали для каждого треугольника, очевидно, должны быть рассчитаны для каждого кадра, поскольку он будет постоянно меняются. Сила будет пропорциональна площади поверхности треугольника, угол, под которым ветра попадает в треугольник, и скорости ветра. Просто так случилось, что при использовании векторного произведения расчета вектора нормали треугольника, длина этого вектора пропорциональна площади треугольника, который делает вещи немного проще. 

Псевдокодом рассчитать влияние ветра на ткань: 

VECTOR: force

VECTOR: normal

VECTOR: wind

 

set force vector to (0,0,0) on all points on cloth

 

loop through all triangles 

    force = unitvector(normal) * dotproduct(normal, wind)

    add force to all points making up this triangle

end of loop

 

loop through all points on cloth

    add gravity to force

    add force to velocity

end of loop

Объектом, на который падает ткань, в данном примере является сфера.

Команды, проводящие построение примитивов из библиотеки GLUT, реализованы  через стандартные примитивы  OpenGL и GLU. Для построения нужного примитива достаточно произвести вызов соответствующей команды.

  • void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
  • void glutWireSphere(GLdouble radius, GLint slices, GLint stacks)

Команда glutSolidSphere() строит сферу, а glutWireSphere() -каркас сферы радиусом radius. 

glutSolidSphere и glutWireSphere оказывать твердую или каркасный сфере соответственно.

Использование

радиус

Радиуса сферы.

Ломтики

Количество подразделений  вокруг оси Z (аналогично линии долготы).

стеки

Количество подразделений  вдоль оси Z (по аналогии с линиями  широты).

Описание

Оказывает сферы с центром в начале координат  моделирования указанного радиуса . Сфера подразделяется вокруг оси Z на ломтики и вдоль оси Z в стопки

Подключение клавиатуры.

Запуск и остановка анимации  осуществляется при нажатии пробела  на клавиатуре. Это совершается с  помощью функции:

void keyboard( unsigned char key, int x, int y )

{

switch ( key ) {

 

// Выход на ESC

case 27:   

exit ( 0 );

break; 

 

// Запуск и пауза на пробел

case 32:

started = !started;

lastUpdate = glutGet(GLUT_ELAPSED_TIME);

break;

}

}

 

glutGet(GLUT_ELAPSED_TIME) - Число миллисекунд

 

// использование распараллеливания

// нормали(хотя бы прочитать про них)

// в приложении картинку изначального положения ткани и исходный результат

Для себя:

Ре́ндеринг (англ. rendering — «визуализация») — термин в компьютерной графике, обозначающий процесс получения изображения по модели с помощью компьютерной программы.

Изначально  интегрирование Верле было разработано  для симуляции взаимодействий частиц. Если есть множество частиц, которые  взаимодействуют друг с другом по определенным законам, на которые действует  множество сил, то традиционные методы исчисления становятся слишком громоздкими  для программирования систем частиц. Метод Верле был разработан как  более эффективное и устойчивое решение.

Одна  из ключевых особенностей интегрирования Верле – то, что вы явно не используете  скорость объекта для определения  его положения. Вместо этого вы используете  его последнюю позицию. Когда  вам потребуется знание скорости объекта, вы вычитаете значение последней  позиции из текущей позиции. Таким  образом, каждый раз, когда вы перемещаете  объект, вы изменяете его скорость. Это упрощает многие вещи.

Другая  общая черта интегрирования Верле  – понятие связи между объектами. Два объекта могут быть соединены  друг с другом и поддерживать определенную дистанцию между собой. Если они  станут отдаляться или сближаться, то метод откорректирует их позиции, при этом, конечно, изменяя их скорость. Объекты могут иметь множественные  связи, когда один объект связан с многими. Метод Верле очень эффективен при обработке всех этих отношений и поддержания расстояния между взаимодействующими объектами. Это отличный инструмент для того чтобы создавать сложные структуры.


Взаимодействие ткани с внешними факторами