MyTetra Share
Делитесь знаниями!
Как задать массу мячику в Box2D
Время создания: 25.11.2017 14:45
Текстовые метки: box2d, мячик, тело, масса
Раздел: Компьютер - Программирование - Физические движки - Box2D
Запись: xintrea/mytetra_syncro/master/base/1511610352e02ws5y026/text.html на raw.github.com

Задание массы в явном виде


Похоже, что напрямую задать массу - весьма проблематичное занятие. Следующий код будет без ошибок компилироваться:


b2MassData massData;

massData.mass=1.0;

body->SetMassData(&massData);


Но в момент выполнения SetMassData произойдет прерывание выполнения программы с ошибкой:


b2Body.cpp:381: void b2Body::SetMassData(const b2MassData*): Проверочное утверждение «m_I > 0.0f» не выполнено.


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


body.massData.mass = 2.0f; // масса тела в кг

body.center.SetZero(); // центр массы в локальных координатах тела

body.I = 3.0f; // момет инерции в кг*м^2


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


Однако есть более простой и, главное, гарантированно работающий метод задания массы.



Задание массы через плотность


Более надежно работает способ задания массы через плотность. Обычно тело создается с помощью некоторого шейпа, например:


b2CircleShape shape;

shape.m_radius=radius;

body->CreateFixture(&shape, 1.0);


У метода CreateFixture два параметра - шейп и плотность (density). Именно плотностью и регулируется масса.


Зная форму шейпа, можно высчитать площадь area. Масса mass нам известна - это та масса, которую необходимо установить. Плотность высчитывается по формуле:


float density=mass/area;


То есть, задать массу тела можно так:


body->CreateFixture(&shape, mass/area);


Только перед такой записью надо вычислить area. Для круглого мячика вычисление площади производится, естественно, с помощью формулы площади круга:


float area=pi*r*r;


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



 
MyTetra Share v.0.59
Яндекс индекс цитирования