我正在尝试在项目中使用 Hermite 曲线,但对数学的实际工作方式的理解有限,而且我遇到了一些我不理解的行为。我已经用下面的最小代码示例证明了我的困惑,但基本上我希望沿着 Hermite 曲线的子曲线(即使用原始曲线上的点和切线定义的子曲线)来拟合原始曲线,但这似乎是假的。
下面的 c# 代码定义了一个 Hermite 曲线类,该类提供了用于计算沿曲线的某个比率的点的位置和切线的函数。我从互联网上的其他地方复制/粘贴了这两个函数的数学。
然后,一个小型测试工具执行我希望成功但没有成功的测试。我不清楚我的代码中是否存在错误,我的数学中是否存在错误,或者我是否误解了 Hermite 曲线的工作原理并且该测试实际上不应该通过。
任何见解都值得赞赏。
using System;
using System.Numerics;
class Program
{
class HermiteCurve
{
Vector2 start;
Vector2 startTangent;
Vector2 end;
Vector2 endTangent;
public HermiteCurve(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent)
{
this.start = start;
this.startTangent = startTangent;
this.end = end;
this.endTangent = endTangent;
}
public Vector2 GetPoint(float t)
{
var t2 = t * t;
var t3 = t2 * t;
return
( 2f*t3 - 3f*t2 + 1f) * start +
(-2f*t3 + 3f*t2) * end +
(t3 - 2f*t2 + t) * startTangent +
(t3 - t2) * endTangent;
}
public Vector2 GetTangent(float t)
{
var t2 = t * t;
return
(6f*t2 - 6*t) * start +
(-6f*t2 + 6*t) * end +
(3f*t2 - 4f*t + 1) * startTangent +
(3f*t2 - 2f*t) * endTangent;
}
}
static void Main(string[] args)
{
Vector2 p0 = new Vector2(0, 0);
Vector2 m0 = new Vector2(1, 0);
Vector2 p1 = new Vector2(1, 1);
Vector2 m1 = new Vector2(0, 1);
HermiteCurve curve = new HermiteCurve(p0, m0, p1, m1);
Vector2 p0prime = curve.GetPoint(0.5f);
Vector2 m0prime = curve.GetTangent(0.5f);
HermiteCurve curvePrime = new HermiteCurve(p0prime, m0prime, p1, m1);
Vector2 curvePoint = curve.GetPoint(0.75f);
Vector2 curveTangent = curve.GetTangent(0.75f);
Vector2 curvePrimePoint = curvePrime.GetPoint(0.5f);
Vector2 curvePrimeTangent = curvePrime.GetTangent(0.5f);
// Why does this check fail?
if (curvePoint != curvePrimePoint || curveTangent != curvePrimeTangent)
{
Console.WriteLine("fail");
Console.WriteLine("curvePosition - x: " + curvePoint.X + " y: " + curvePoint.Y);
Console.WriteLine("curvePrimePosition - x: " + curvePrimePoint.X + " y: " + curvePrimePoint.Y);
Console.WriteLine("curveTangent - x: " + curveTangent.X + " y: " + curveTangent.Y);
Console.WriteLine("curvePrimeTangent - x: " + curvePrimeTangent.X + " y: " + curvePrimeTangent.Y);
}
}
}
程序输出:
fail
curvePosition - x: 0.890625 y: 0.703125
curvePrimePosition - x: 0.96875 y: 0.71875
curveTangent - x: 0.8125 y: 1.3125
curvePrimeTangent - x: 0.25 y: 0.375