物理引擎探究(10)

您所在的位置:网站首页 转动动量怎么求 物理引擎探究(10)

物理引擎探究(10)

2023-08-14 12:33| 来源: 网络整理| 查看: 265

  0.简介

上次一我实现了球碰撞后的运动轨迹计算,这回要实现球的旋转。

1.角动量

我觉得这里应该用到角动量了,当球与球碰撞之后,球自身会因为碰撞点有摩擦力,导致球旋转的,主要就是来求这个旋转的速度,这里就是角速度,所以在形状类中我添加了两个新的属性。

//旋转速度 vec3 angular_velocity = vec3(0,0,0); //旋转角度 vec3 angular = vec3(0, 0, 0);

然后就是计算角速度了,现在还没有引进摩擦力,所以现在就简要模拟有摩擦力的情况。然后利用物体相撞计算动量守恒的方法,计算角动量。

这里就暂且认为摩擦力会造成另一个物体旋转,来源于,若空间中一个圆圈,当受到一个非对心的推力的时候,会产生旋转。圆圈怎么能看出旋转呢,这里加了一个区分标记。并且利用旋转矩阵。同样在显示的时候也添加了矩阵变换。

void Object::update(float time) { updatePosition(time); updateVelocity(time); //修改旋转矩阵 angular += angular_velocity; axis = EulerAngle::getMat(angular); force = vec3(0,0,0); } 标记

计算角动量这里根据角动量公式来计算。

关于角动量公式的链接 角动量公式讲解

我是先将圆圈本身的角动量分离出线速度,然后再和圆圈运动方向的线速度叠加,之后将这个速度转换到角动量。由于假设有摩擦力,力的作用是相互的,所以输出的动量同样也会返回给自己,这里还可以考虑利用冲量来计算。

void generate() { //没有碰撞就不计算 if (A == nullptr || B == nullptr) return; //以下生成的都是碰撞产生的力 //两个物体都存在说明产生碰撞力 if (A != nullptr && B != nullptr) { vec3 vecA = normalize(A->obj->getPos() - cPoint); vec3 vecB = normalize(B->obj->getPos() - cPoint); //碰撞点在两个型心连线上 if (dot(vecA, vecB) < 0.0001) { float speedA = length(A->obj->velocity); float speedB = length(B->obj->velocity); float cosa = dot(vecA, normalize(A->obj->velocity)); float cosb = dot(vecB, normalize(B->obj->velocity)); if (speedA == 0) cosa = 1; if (speedB == 0) cosb = 1; //两个物体的速度分解,碰撞点到连心线上的分解 vec3 rA = momentumCalc(A->obj->mass, B->obj->mass, speedA * cosa*vecA, speedB * cosb*vecB); vec3 rB = momentumCalc(B->obj->mass, A->obj->mass, speedB * cosb*vecB, speedA * cosa*vecA); vec3 AC = vecA * speedA * cosa; vec3 BC = vecB * speedB * cosb; vec3 AR = A->obj->velocity - AC; vec3 BR = B->obj->velocity - BC; AC = rA; BC = rB; A->obj->velocity = (AC + AR); B->obj->velocity = (BC + BR); //先将物体原有旋转动量转换 float Ra = length(A->obj->getPos() - cPoint); float Rb = length(B->obj->getPos() - cPoint); vec3 roA = cross(A->obj->angular_velocity, vecA)*0.5f;//这里是损失的角动量 vec3 roB = cross(B->obj->angular_velocity, vecB)*0.5f; //计算动量后并且将角速度转换成线速度 vec3 troA = momentumCalc(A->obj->mass, B->obj->mass, roA, roB)*A->obj->mass*Ra; vec3 troB = momentumCalc(B->obj->mass, A->obj->mass, roB, roA)*B->obj->mass*Rb; //将运动速度转换成动量,这里暂不明,就是效果好, 我推算一个公式看看的 rA = AR*A->obj->mass* A->obj->mass; rB = BR*B->obj->mass* B->obj->mass; vec3 all = rA - rB; //计算A和B角动量 vec3 dA = (all+troA-troB); vec3 dB = (-all+troB-troA); A->obj->angular_velocity += -cross(dA, vecA * length(A->obj->getPos() - cPoint))/(A->obj->mass*Ra*Ra); B->obj->angular_velocity += -cross(dB, vecB * length(B->obj->getPos() - cPoint))/(B->obj->mass*Rb*Rb); } } }

这里去掉了受力计算,受力计算已经在速度update的之前计算好了,所以这里的受力计算是多余的。

2.效果 一些效果 一些效果 3.源码

release0.05



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3