我正在寻找使用向量创建逼真的汽车运动


12

我已经仔细检查了如何执行此操作,并找到了此http://www.helixsoft.nl/articles/circle/sincos.htm我已经尝试了一下,但是显示的大多数功能都无法正常工作,我只是出错了因为它们不存在。我看过cos和sin函数,但不了解如何使用它们或如何使用矢量使汽车运动正常工作。我没有代码,因为我不确定该怎么办。

任何帮助表示赞赏。

编辑:

我有一些限制,必须在我的游戏中使用TL引擎,不允许添加任何形式的物理引擎。必须使用c ++编程。这是我尝试遵循我提供的链接中所做的操作后得到的示例。

if(myEngine->KeyHeld(Key_W))
    {
        length += carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_S))
    {
        length -= carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_A))
    {
        angle -= carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_D))
    {
        angle += carSpeedIncrement;
    }

    carVolocityX = cos(angle);
    carVolocityZ = cos(angle);

    car->MoveX(carVolocityX * frameTime);
    car->MoveZ(carVolocityZ * frameTime);

检查本网站了转向行为:red3d.com/cwr/steer
MichaelHouse

您需要定义“现实的汽车运动”
Maik Semder 2012年

1
我认为您的角度可能来自方向盘。长度应为速度的大小。因此,最后一个代码段可能是:carVecloityX = length* cos(angle);carVelocityZ = length *sin(angle);之外的内容,请告诉您输入的内容以及汽车的运行方式。现在,它应该在地平面中转向,但是再次,这根本不普遍。在那里,你只是做我们粗欧拉积分步骤..
teodron

Answers:


23

创建一个不错的汽车运动并不难(但是这篇文章会很长)。您需要“模拟”几个基本力才能使汽车在物理上看起来合理。

(所有代码示例都是伪代码。)

加速

首先,您显然需要加速。就像下面的代码行一样简单:

acceleration_vector = forward_vector * acceleration_input * acceleration_factor
  • forward_vector —指向与汽车相同方向的向量。
  • acceleration_input —输入应在[-1,1]范围内。
  • acceleration_factor —加速度的值(像素/秒^ 2,或任何单位)。

操舵

转向也很简单。原则上,您要做的是旋转汽车的前向矢量,使其指向其他方向。

steer_angle = steer_input * steer_factor
new_forward_vector = rotate_around_axis(forward_vector, up_vector, steer_angle)

但是,您可能会在这里遇到麻烦。如果通过键盘输入,则其值将为-1或1,这意味着您的汽车将立即转弯。您可以使用非常简单的线性插值(公差)来解决此问题:

 amount = time_since_last_frame * steer_lerp_factor
 forward_vector = lerp(forward_vector, new_forward_vector, amount)

数量应取决于时间,以使您的移动不取决于帧频。该值应在[0,1]之间,并且该值越小,新旧矢量之间的过渡越平滑。

(在这一点上,你会发现,该车将引导即使是站着不动。为了防止这种情况,乘steer_anglecurrent_speed / max_speed,这里max_speed是由您定义的常量。)

移动

现在,我们将应用加速度,并根据其速度,加速度和转向将汽车移动一定数量的像素。我们还将希望限制汽车的速度,以使其最终不会无限快地行驶。

current_speed = velocity_vector.norm()
if (current_speed < max_speed)
{
    velocity_vector += acceleration_vector * time_since_last_frame
}

position_vector += velocity_vector * time_since_last_frame

你的车现在在滑

如果我是对的,那么当您转弯时,您的汽车现在似乎应该在滑行,就像在冰上一样。这是因为没有摩擦。在真实的汽车上,存在很大的侧向摩擦力(由于车轮无法横向旋转:P)。

您将需要降低横向速度。通过不完全减小它,您还可以使汽车看起来正在漂移。

 lateral_velocity = right_vector * dot(velocity_vector, right_vector)
 lateral_friction = -lateral_velocity * lateral_friction_factor 

既然我们在谈论摩擦,您可能还希望有一个(摩擦)力来降低速度,这样当您停止加速时,您的汽车最终将停止。

 backwards_friction = -velocity_vector * backwards_friction_factor

您的汽车行驶代码现在应如下所示:

// Friction should be calculated before you apply the acceleration
lateral_velocity = right_vector * dot(velocity_vector, right_vector)
lateral_friction = -lateral_velocity * lateral_friction_factor
backwards_friction = -velocity_vector * backwards_friction_factor
velocity_vector += (backwards_friction + lateral_friction) * time_since_last_frame


current_speed = velocity_vector.norm()
if (current_speed < max_speed)
{ 
    velocity_vector += acceleration_vector * time_since_last_frame
}

position_vector += velocity_vector * time_since_last_frame

结束语

我提到您应该如何将套环应用于转向;我认为您可能需要对加速和转向角做同样的事情(您将必须存储前一帧的值,并从前一帧起跳)。同样,相对于汽车的所有矢量(前,右,上)都应为长度1。

而且,摩擦比我在这里显示的要复杂一些。您应始终确保其长度不大于使轿厢停止所需的加速度的长度(否则摩擦会使轿厢向相反方向移动)。因此,您应该具有以下内容:

dt = time_since_last_frame
backwards_friction.resize(min(backwards_friction.norm(), velocity_vector.norm() / dt))
lateral_friction.resize(min(lateral_friction.norm(), lateral_velocity.norm() / dt))

哇,这是一个很好的答案!
ezolotko

0

从您的问题来看,我将假设您是编程的新手(顺便说一句!)。我建议使用现有框架,因为逼真的汽车模拟是物理学中最难正确的方面之一。

您没有提到2D / 3D限制,因此我将继续建议您下载Havok SDK(非商业用途免费)并获得一个简单的演示并运行(它们实际上具有一些现成的演示[get在您的系统上编译,所有代码都在这里],您无需执行任何操作即可进行编译...只需打开项目并点击构建即可)。

一旦您对汽车物理的幕后知识有了一些了解(虽然您看不到物理的实际实现,但是隐藏了,您将看到界面),我相信您会处于一个更好的位置当您自己开始时,将其正确设置。

我不久前也问过类似的问题。那里的链接也可能有帮助。而这里的另一个链接


看完您的编辑后,您似乎只是想根据计算出的角度简单地改变汽车的速度(顺便说一句,这是不现实的,因此您应该更改原始问题以反映该问题)。如果角度是问题的一部分(不能更改),并且必须使用角度来计算新的速度,那么请使用@teodron在注释中添加的内容。

另一种方法是仅使用向量。使用向量有多种方法,我将介绍一种。

速度是方向*大小(其中大小是速度,方向是归一化矢量)。计算汽车的当前速度和方向。沿方向并向垂直方向添加一个矢量(我们称其为D')。这将改变汽车的速度。没有角度可弄乱(尽管您可以使用角度来确定垂直矢量的长度,这可以作为转弯因子 [见下文])

如何计算D':要找到垂直矢量,请以原始速度的方向为准,将其与朝向屏幕的方向矢量相交,然后沿与矢量相交的顺序确定垂直矢量的方向。然后将这个垂直系数​​乘以某个转弯系数,从而确定汽车转弯的速度。


我可以,但是我不允许使用物理引擎,游戏是3D的,我需要更改的只是X和Z向量,我只需要弄清楚它们是什么。
bobthemac 2012年

@bobthemac:这是一个家庭作业问题吗?如果是,请编辑您的问题以指出您的限制,并可能发布一些相关代码,以便我们有所建树。顺便说一句,就理解功能而言,最后一个链接可能就是您要寻找的东西。
Samaursa'4

我已经添加了您要求的信息,并查看了提供的链接,但仍然不理解。
bobthemac 2012年

@bobthemac:见我的编辑
Samaursa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.