Расчет тензоров инерции


10

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

Короткая версия: существует ли общая формула c ++ / physx для вычисления тензоров инерции на основе формы объекта?

Длинная версия: Для нашей физики нам нужно указать тензоры инерции x, y и z. В настоящее время способ, которым мы это делаем, - это просто соотношение, основанное на массе. Поэтому, если объект длинный по оси X и тонкий по Y и Z, а масса равна 10000, мы установим Z и Y на 7000, а X на 3000. (Это не точно, но просто для того, чтобы дать представление)

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

Я работаю над функцией, которая берет ограничивающую рамку объекта и, надеюсь, вычисляет относительно точные тензоры. Я взял некоторую математику из http://en.wikipedia.org/wiki/List_of_moment_of_inertia_tensors и сделал функцию, которая в основном работает следующим образом для аналогичных вращений ниже.

Твердый кубоид шириной w, высотой h, глубиной d и массой m введите описание изображения здесь

Или, если вращение заканчивается, вот так:

введите описание изображения здесь введите описание изображения здесь

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

NxVec3 CalculateInertiaTensor( VisBoundingBox_cl boundingBox, float m )
{
    float width = boundingBox.GetSizeX();
    float height = boundingBox.GetSizeZ();
    float depth = boundingBox.GetSizeY();

    float xTensor = 0.083f * m*(height*height + depth*depth);
    float yTensor = 0.083f * m*(width*width + depth*depth);
    float zTensor = 0.083f * m*(width*width + height*height);

    return NxVec3(xTensor, yTensor, zTensor);
}

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


3
Если вы можете разложить ваш объект на тетраэдры, то вы должны иметь возможность использовать линейность тензора вместе с базовой формулой для момента инерции тетраэдра (вы можете найти это, например, с помощью Wolfram Alpha), чтобы вычислить точный тензор. Моя проблема с методом ограничивающего прямоугольника заключается в том, что он действительно зависит от того, сколько вашего BB объект заполняет; представьте, например, разницу между толстым эллипсоидом и тонкой спиральной пружиной.
Стивен Стадницки

Спасибо за вклад. И вы правы, моя главная проблема возникает, когда, скажем, есть объект в форме «А», ВВ заставит тензоры возвращаться неправильно. Я проверю вашу информацию, спасибо!
Мунгоид

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

Если бы вы захотели, это было бы здорово! Я пытался выяснить это некоторое время, но я все еще немного зарождаюсь в этой области, поэтому я все больше и больше путаюсь = -)
Mungoid

Ответы:


7

Я собирался предположить, что это сложная проблема, потому что обычные формулировки, основанные на использовании теоремы Грина для преобразования объемных интегралов в поверхностные интегралы, не применимы, и поэтому вам действительно нужно обеспечить тетраэдрическое разложение вашей фигуры - но это оказывается что это не правильно. Пока ваша форма имеет равномерную плотность (что является приблизительным значением, которое вы уже делаете, по-видимому, и вполне разумным для большинства обстоятельств), то интегралы объема можно упростить до поверхностных интегралов, а последние упростить еще больше. Еще лучше, кажется, есть довольно красивый алгоритм и код для этого в сети; взгляните на http://www.cs.berkeley.edu/~jfc/mirtich/massProps.html, Страница Брайана Миртича, описывающая его алгоритмы вычисления моментов и центра масс. Это должно покрыть почти все ваши потребности на этом фронте. Обратите внимание, что это то, что вы захотите сделать один раз, либо как инструмент для экспорта фигуры, либо во время импорта, но не то, что вам нужно будет делать каждый кадр; просто сохраните тензор инерции относительно центра масс вместе с остальной информацией о форме, и если вам когда-нибудь понадобится найти тензор для моментов инерции относительно некоторой другой оси, то вы можете использовать стандартные теоремы для его получения.

Надеюсь, это должно охватить то, что вам нужно - если есть еще что-то, с чем я могу помочь, просто дайте мне знать!


4

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

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


0

Для большинства игровых приложений (т. Е. Для «взрывающихся вещей») достаточно просто использовать приведенное выше уравнение для прямоугольного тела. При условии, что объект выровнен по оси, а не по диагонали поперек ограничительной рамки, это должно работать. Некоторые движки игровой физики, такие как ODE, используют только термины на главной диагонали тензора инерции. Для них ваши объекты должны быть по крайней мере примерно выровнены по оси, чтобы работать правильно.

Я использовал алгоритм Миртича в «Падающих телах» еще в 1997 году. Он работает хорошо, но вы должны иметь чистую геометрию - топологически правильную замкнутую несамопересекающуюся сетку. Если есть дыры, вычисление инерции даст совершенно поддельные результаты. Я использовал только выпуклую геометрию, поэтому я сначала запустил QHull, чтобы получить выпуклую оболочку в целях столкновения, а затем вычислил инерцию из этого.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.