如何在保持初始和最终导数相同的情况下缩放贝塞尔曲线 t 值?

How to scale a Bezier Curves t value while keeping its initial and final derivatives the same?

有很多关于缩放贝塞尔曲线位置的答案,但我想缩放它的 t 值。我找到了一个解决方案,但问题是一旦我缩放我的 t 值我的速度就会改变。

通过缩放 t 值,我的意思是将 t 的范围从 0,1 缩放到 0,n 我目前这样做的方式是将我使用的任何增量除以我需要的最大 t 值,并将其转换为范围为 0,1 的 t curT += 增量时间 t = curT/maxT

这导致我的导数不正确。因此,必须通过将它们除以 MaxT 的任意阶导数的幂来校正它们

D1 = d1 / MaxT^1
D2 = d2 / MaxT^2

这是由于速度和加速度的公式。 速度 = d/t 加速度 = d/t^2

我推导出初速度的公式为

Vi = 2P1 - 2P2

并且因为我有一些代数的初始速度我可以推导出 P2

P2 = Vi/2 - p1

我的问题是,这似乎缩放不正确。如果我改变我的 maxT 那么我的初始速度也会改变。 如何在更改比例因子的同时保持初始速度?

相关代码:

public partial struct AccelSimple : IJobEntity
{
    public float delta;
    void Execute(ref PhysicsVelocity velocity, ref BezierCurvePoints curve, ref Rotation rotation)
    {
        float t = curve.curTime / curve.timeScale;

        //calculate velocity at any point on curve
        velocity.Linear =
            (curve.p1 * (-2 + 2 * t) +
            curve.p2 * (2 - 4 * t) +
            curve.p4 * (2 * t)) / curve.timeScale;

        curve.curTime += delta;
    }
}
 var handle = Entities.WithAll<FinishedMovementTag>().WithoutBurst().ForEach((Entity e,
         ref BezierCurvePoints curve, ref PatrolIndex index, in DynamicBuffer<PatrolPoints> points,
          in Translation translation, in PhysicsVelocity velocity, in AccelerationSpeed acceleration) =>
        {
            Debug.Log(curve.p4 - translation.Value);

            if (index.value >= points.Length - 1) index.value = 0;
            else index.value++;

            //due to floating point and physics simulation errors cannot precalculate Curve
            //Starting Point of Curve
            curve.p1 = translation.Value;

            //Velocity of t=0
            curve.p2 = (curve.p1 + (velocity.Linear / 2));

            //end position of curve
            curve.p4 = points[index.value].Position;
            
            //rough approximation of length of curve //was hoping this would allow math hacks to get velocity scaling factor
            float mag = Vector3.Magnitude(curve.p1 - curve.p4);

            //Time it should take to get to end of curve
            curve.timeScale = mag / acceleration.value;
            curve.curTime = 0;

            ecb.RemoveComponent(e, typeof(FinishedMovementTag));
            ecb.AddComponent(e, typeof(SimpleAccelTag));
        }).Schedule(this.Dependency);

这是二阶贝塞尔曲线,我可以使用三阶贝塞尔曲线,但我并不真正关心退出时的速度,所以它似乎是一个不必要的约束。

我使用贝塞尔曲线是因为它们模拟了受位置导数影响的曲线,这对于物理路径来说似乎是理想的,因为它具有速度加速度急动等。内置。但是要使用曲线的物理特性,我需要按给定的程度向上或向下缩放。

我的公式在很大程度上完全符合我的要求,它只在连接 2 条曲线时失败,并且当曲线延伸到很远时速度变慢,这可能是由于我帐户中的公式不正确。

这不是一个笼统的答案,因为我相信我的用例非常独特。 长话短说,这是我没有考虑到的数学错误/因素。 我会根据时间适当地调整我的速度,但在这样做的同时我会显着降低我的速度。解决方案是将我的初始速度计算值乘以我按比例缩小的量。

时间 = Vector3.mag(p4-p1);

p2 = p1 + (initial-velocity * .5f * 时间);