从位置矢量得到速度矢量

Getting the velocity vector from position vectors

本文关键字:速度 位置      更新时间:2023-10-16

我看了一堆类似的问题,我似乎找不到一个特别回答我的问题。我正在编写一个简单的3d游戏,我试图让玩家在我的地图上捡起和移动实体。我想要得到一个速度向量,将物理物体"推"到离玩家眼睛一定距离的地方。这是另一款游戏中的例子(玩家在眼前举着一个椅子实体)。

为了做到这一点,我找到了玩家的视角,然后从角度中获得前进向量,然后计算物体的速度。这是我的工作代码:

void Player::PickupOtherEntity( Entity& HoldingEntity )
{
    QAngle eyeAngles = this->GetPlayerEyeAngles();
    Vector3 vecPos = this->GetEyePosition();
    Vector3 vecDir = eyeAngles.Forward();
    Vector3 holdingEntPos = HoldingEntity.GetLocation();
    // update object by holding it a distance away
    vecPos.x += vecDir.x * DISTANCE_TO_HOLD;
    vecPos.y += vecDir.y * DISTANCE_TO_HOLD;
    vecPos.z += vecDir.z * DISTANCE_TO_HOLD;
    Vector3 vecVel = vecPos - holdingEntPos;
    vecVel = vecVel.Scale(OBJECT_SPEED_TO_MOVE);
    // set the entity's velocity as to "push" it to be in front of the player's eyes
    // at a distance of DISTANCE_TO_HOLD away
    HoldingEntity.SetVelocity(vecVel);
}

这些都很好,但我想把我的数学转换成可以应用脉冲。而不是为物体设置一个全新的速度,我想"添加"一些速度到它现有的速度。假设我有它当前的速度,我需要怎样的数学来"加"速度?这本质上是一个游戏物理问题。谢谢你!

一个非常简单的实现可以像这样:

velocity(t+delta) = velocity(t) + delta * acceleration(t)
acceleration(t) = force(t) / mass of the object

速度、加速度和力是矢量。T, δ和质量标量

这只适用于较小且等距的delta。你要做的就是用经典力学模拟物体

脉冲在技术上是F∆t对于常数F,这里我们可能想要假设∆t,因为质量是无关紧要的。如果你想让一个脉冲动起来,你必须决定速度的变化应该是多少,它需要多长时间。事情很快就会变得复杂。

老实说,一时冲动并不是正确的做法。相反,最好设置一个恒定的pick_up_velocity(人们不倾向于使用脉冲捡起东西),并在每次物体上升速度时刷新位置。Y,直到达到正确的水平:
while(entPos.y < holdingEntPos.y)
{
    entPos.y += pickupVel.y;
   //some sort of short delay
}

对于漂浮在玩家眼前的物体,设置一个eyemomoventevent,它也会将正确的位置变化发送给玩家所持有的任何实体。

如果我遗漏了什么,你们已经在做了,记住,当人类施加脉冲时,它通常是在很短的时间内非常高的加速度,比一帧要短得多。你不会在游戏中看到它。

基本牛顿/达朗贝尔物理学规定:

derivate(position)=velocity
derivate(velocity)=acceleration

和反向:

integrate(acceleration)=velocity
integrate(velocity)=position

所以对于你的引擎,你可以使用:

矩形求和代替积分(积分的数值解)。定义时间常数dt [seconds],它是更新之间的间隔(计时器或1/fps)。因此更新代码(必须在每个dt中周期性地调用):

vx+=ax*dt;
vy+=ay*dt;
vz+=az*dt;
 x+=vx*dt;
 y+=vy*dt;
 z+=vz*dt;

地点:

  • a{x,y,z} [m/s^2]是实际加速度(在您的情况下,方向矢量缩放为a=Force/mass)
  • v{x,y,z} [m/s]为实际速度
  • x,y,z [m]为实际位置

    1. 这些值必须初始化a,v为零,x,y,z为初始化位置
    2. 所有对象/玩家……有自己的变量
    3. 句号由v=0; a=0;
    4. 完成
    5. 对象的驱动仅通过改变a
    6. 来完成
    7. 碰撞时镜像v矢量由碰撞normal

    并可能乘以一些k<1.0(例如0.95)来计算撞击时的能量损失

你可以添加重力或任何其他力场通过添加g矢量:

vx+=ax*dt+gx*dt;
vy+=ay*dt+gy*dt;
vz+=az*dt+gz*dt;

也可以添加摩擦和其他任何你需要的

p。角度也是一样,用angle/omega/epsilon/I代替x/a/v/m

以角度I表示(pitch,yaw,roll)绕质心旋转