递归贝塞尔曲线算法在 C# 中不起作用

Recursive bezier curve algorithm not working in C#

我在此 post 中复制了确切的算法,但不知何故它在 C# Recursive function of Bezier Curve python 中不起作用。这是我的代码:

        private static Vector2 GetPointByInterpolation(List<Vector2> controlPoints, float interpolation)
        {
            if (interpolation < 0 || interpolation > 1)
            {
                throw new ArgumentException("\'interpolation\' value can only range from 0 to 1");
            }
            if (controlPoints.Count == 0)
            {
                throw new ArgumentException("\'controlPoints\' doesn't contain any points");
            }
            if (controlPoints.Count == 1)
            {
                return controlPoints[0];
            }
            else
            {
                Vector2 p1 = GetPointByInterpolation(controlPoints.GetRange(0, controlPoints.Count - 1), interpolation);
                Vector2 p2 = GetPointByInterpolation(controlPoints.GetRange(1, controlPoints.Count - 1), interpolation);
                return (1 - interpolation) * p1 + interpolation * p2;
            }
        }

        private static void Main(string[] args)
        {
            List<Vector2> controlPoints = new List<Vector2>
            {
                new Vector2(0, 0),
                new Vector2(0, 100),
                new Vector2(100, 100)
            };
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(GetPointByInterpolation(controlPoints, 1 / 100 * i));
            }
            Console.Read();
        }

我测试了上面 link 中的算法并且它按预期工作,但是在我用 C# 重写它之后,该函数总是返回 controlPoints 中的第一个点。我怀疑问题是因为 Vector2 是一个值类型,但似乎并非如此。

我认为这里有两个问题。

  1. 您的范围看起来不正确。
  2. 您执行整数除法,结果不会很好。

对于整数类型的操作数,/运算符的结果是整数类型,等于两个操作数的商向零舍入......而且,我知道在我的心你不想要这个。

给定

private static Vector2 GetPointByInterpolation(ReadOnlySpan<Vector2> controlPoints, float interpolation)
{
   if (interpolation < 0 || interpolation > 1)
      throw new ArgumentException("value can only range from 0 to 1",nameof(interpolation));

   if (controlPoints.Length == 0)
      throw new ArgumentException("doesn't contain any points",nameof(controlPoints));

   if (controlPoints.Length == 1)
      return controlPoints[0];

   // first to last - 1
   var p1 = GetPointByInterpolation(controlPoints[0..^1], interpolation);
   // second to last
   var p2 = GetPointByInterpolation(controlPoints[1..], interpolation);
   var nt = 1 - interpolation;
   return new Vector2(nt * p1.X + interpolation * p2.X, nt * p1.Y + interpolation * p2.Y);

}

注意 :我正在使用 ReadOnlySpan,因为好吧......为什么不呢,切片和切片的效率非常高可以使用 C# 范围。

用法

var controlPoints = new[]
{
   new Vector2(0, 0),
   new Vector2(0, 100),
   new Vector2(100, 100)
};

// take special note of (float)100, we are now performing floating point division
for (int i = 0; i < 100; i++)
   Console.WriteLine(GetPointByInterpolation(controlPoints.AsSpan(), 1 / (float)100 * i));

免责声明 : 我这辈子从来没有写过 python 代码(也不想开始 :p ), 另外我不知道递归贝塞尔曲线算法实际上做了什么,所以我不确定范围是否正确,或者代码是否还有其他问题。