我想参考世界框架来模拟由扭矩T = {1,1,1}施加的物体。物体的质量为1Kg,其惯性张量的对角元素为{2,1,1}。但是bullet2.7和bullet2.8给了我完全不同的结果
#include <btBulletDynamicsCommon.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
using namespace std;
/// This is a Hello World program for running a basic Bullet physics simulation
int main(int argc, char** argv)
{
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a differnt dispatcher
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
///the default constraint solver. For parallel processing you can use a different solver
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
///instantiate the dynamics world
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
///sets the gravity
dynamicsWorld->setGravity(btVector3(0, 0, 0));
btCollisionShape* Shape = new btSphereShape(1);
//The btTransform class supports rigid transforms with only translation and rotation
btDefaultMotionState* MotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 50, 0)));
btScalar mass = 1;
btVector3 Inertia(2, 1, 1);
btVector3 torque(1, 1, 1);
btVector3 angularVelocity(0, 0, 0);
///when bodies are constructed, they are passed certain parameters. This is done through a special structure Bullet provides for this.
///rigid body is dynamic if and only if mass is non zero, otherwise static
btRigidBody::btRigidBodyConstructionInfo RigidBodyCI(mass, MotionState, Shape, Inertia);
btRigidBody* RigidBody = new btRigidBody(RigidBodyCI);
dynamicsWorld->addRigidBody(RigidBody);
ofstream outfile("data.csv", ios::out);
for (int i = 0; i < 300; i++) {
RigidBody->applyTorque(torque);
dynamicsWorld->stepSimulation(1 / 60.f, 10);
angularVelocity = RigidBody->getAngularVelocity();
outfile << angularVelocity.getX() << "," << angularVelocity.getY() << "," << angularVelocity.getZ() << endl;
}
outfile.close();
delete Shape;
delete dynamicsWorld;
delete solver;
delete dispatcher;
delete collisionConfiguration;
delete broadphase;
printf("Press a key to exit\n");
getchar();
}
子弹2.78:
子弹2.83:
答案 0 :(得分:0)
物理引擎当然会给出不同的结果 他们计算它们的方式是不同的。这就是你注意到的。
物理引擎,它们是互动的,或者是实时的&#34; (如Box2D和Bullet),通常并不意味着给出100%准确的结果。他们意味着提供足够好的结果&#34;。这通常意味着足以在视频游戏环境中提供物理感。这是因为他们可以使用快捷方式来更快地计算结果。
来自Box2D FAQ:
Box2D使用近似方法有几个原因。
- 性能
- 一些微分方程没有已知的解决方案
- 无法确定某些约束
这些近似值和在现实主义方面的权衡取舍,不同的引擎制造,可能和确实在引擎之间有所不同。如果引擎使用迭代求解器,那么任何差异都可以放大差异。发动机也会对诸如碰撞余量之类的事情做出不同的选择,使发动机的苹果对比比较困难。
由于这些近似,即使物理引擎如何计算因重力等力而计算速度也会有所不同。为了深入了解Box2D和轨迹的牛顿物理学之间的差异,请看看iforce2d在Projected trajectories tutorial中解释了什么。
有些事情可以做,可以提高这类引擎的准确性。然而,这些都是以牺牲性能为代价的。比如使用更小的时间步长,更高的迭代次数或更高精度的数字类型(例如从使用float
切换到使用double
)。
我发现的资源比较ODE 0.11,PhysX和Newton 3.11可能会让您更深入了解:A comparison between 3 physics engines。然而,我并没有讨论差异的原因,但我已经解释了这些差异。在How can I increase the physical realism of my simulation?
还有关于增加“物理学”中现实主义的讨论希望这有帮助!