沿贝塞尔曲线方向移动物体?

时间:2011-01-15 22:10:19

标签: c++ math 3d

我有一个物体,我想跟随一条bezier曲线,现在我有点失去了如何根据时间而不是构成曲线的点来做到这一点。

。:: 当前系统 ::。 场景图中的每个对象都是由位置,旋转和比例矢量组成的。这些矢量用于形成它们相应的矩阵:比例,旋转和平移。然后将其按该顺序相乘以形成局部变换矩阵。 然后将世界变换(通常是单位矩阵)与局部矩阵变换相乘。

class CObject
{
public:
 // Local transform functions
 Matrix4f GetLocalTransform() const;
 void SetPosition(const Vector3f& pos);
 void SetRotation(const Vector3f& rot);
 void SetScale(const Vector3f& scale);

    // Local transform
    Matrix4f m_local; 
    Vector3f m_localPostion;
    Vector3f m_localRotation; // rotation in degrees (xrot, yrot, zrot)
    Vector3f m_localScale;
}

Matrix4f CObject::GetLocalTransform()
{
    Matrix4f out(Matrix4f::IDENTITY);

    Matrix4f scale(), rotation(), translation();

    scale.SetScale(m_localScale);
    rotation.SetRotationDegrees(m_localRotation);
    translation.SetTranslation(m_localTranslation);

    out = scale * rotation * translation;
}

我遇到的最大问题是

1)如何将物体定向为面向贝塞尔曲线的切线?

2)如何将该对象沿曲线移动而不仅仅将对象位置设置为贝塞尔曲线上某点的位置?

到目前为止,概述了该功能

void CNodeControllerPieceWise::AnimateNode(CObject* pSpatial, double deltaTime)
{
    // Get object latest pos.
    Vector3f posDelta = pSpatial->GetWorldTransform().GetTranslation();

    // Get postion on curve
    Vector3f pos = curve.GetPosition(m_t);

    // Get tangent of curve
    Vector3f tangent = curve.GetFirstDerivative(m_t);

}

编辑:抱歉不太清楚。我一直在研究这个问题,这让我的大脑变得糊里糊涂。

我希望将对象附加到曲线并面向曲线的方向。

至于运动,我想反对根据时间跟随曲线,这样就可以在曲线上创造平滑的运动。

4 个答案:

答案 0 :(得分:2)

您需要曲线的参数化公式。

  

我遇到的最大问题是

     

1)如何将对象定位到   面对贝齐尔曲线的切线?

如果曲线具有参数形式,则切线方向是位置wrt的导数。

  

2)如何移动该对象   不仅设置对象的曲线   位置上的一个点   bezier cuve?

我不确定我是否接受了您的问题 - 您只需稍微增加参数形式的 t 并更新位置和方向。你仍然有一定的自由度,顺便说一句 - “向上”的方向不是从曲线中确定的,所以你也需要照顾它。

答案 1 :(得分:2)

你应该有参数形式的曲线,并使用导数矢量来评估物体的旋转(旋转角度=衍生角度),如@etarion所说。

要在具有所需速度的曲线上移动对象(我认为这是您想要的想法),每个模拟步骤都要估计该点在此步骤中应移动的距离。

最简单的估算是dist = derivative.length()*TIMER_STEP。当您知道应该在当前步骤和t0上遍历dist时,您可以简单地将t0增加一些小值epsilon并检查遍历距离是否小于估计值。重复此操作直到遍历的距离(增加t0)> =估计。这将是下一步的新当前参数t0

修改

首先没注意到你在3d。在3d空间中,即使您知道初始位置,也无法明确定义曲线上对象的位置。想象一下你的曲线就是一条线 - 物体仍然可以绕着线旋转。该角度不是由曲线定义的。

我会做这样的事情。让矢量绑定到对象,以便在移动开始时(例如,曲线参数t = 0),对象矢量方向与导数矢量一致。然后在运动期间,该矢量应该仍然与曲线的每个点的导数一致。因此,您将知道此对象矢量,并将能够根据此向量设置您的对象。但你仍然会有一个自由度。

例如,您可以说对象不会围绕此向量旋转。

了解对象矢量及其周围的旋转角度,您可以在3d世界中恢复对象方向。

PS:此类对象矢量及其周围的旋转角度称为四元数 - 因此您可以使用四元数数学(简单复制所需的公式)来计算对象旋转矩阵! 这是公式http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm

答案 2 :(得分:0)

我假设您拥有定义贝塞尔曲线所需的所有点。 然后,您可以计算该曲线上的每个点。计算一个合适的点,考虑到物体应该行进的速度,以及帧时间,你应该有一致的运动。

由最后一帧和当前帧构成的矢量可以用作大多数情况下切线的粗略估计;例如当曲线没有弯得太尖锐时。

编辑: 还可以看一下how to calculate the length of a bezier curve。您需要对其进行变换,以便计算给定长度的曲线上的点(或者更确切地说 t )。然后只需相对于时间均匀移动距离,你应该没问题。

答案 3 :(得分:0)

一种方法是计算点金字塔。底层是您转换的控制点。现在对于给定的t,并且对于每对相邻点,创建在该线段上由t加权的新点。这组新的点构成了金字塔中的下一层。重复,直到当前图层只有1个点。这一点是你的立场。请注意,顶部的第二层有2个点,并确定切线。