如何在保持初始和最终导数相同的情况下缩放贝塞尔曲线 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 * 时间);
有很多关于缩放贝塞尔曲线位置的答案,但我想缩放它的 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 * 时间);