简体   繁体   English

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

[英]Recursive bezier curve algorithm not working in C#

I copied the exact algorithm in this post but somehow it's not working in C# Recursive function of Bezier Curve python .我在这篇文章中复制了确切的算法,但不知何故它在贝塞尔曲线 python 的 C# 递归 function 中不起作用 Here's my code:这是我的代码:

        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();
        }

I tested the algorithm in the link above and it's working as expected, but after I rewrote it in C#, the function was always returning the first point in controlPoints .我在上面的链接中测试了算法,它按预期工作,但是在我用 C# 重写它之后, function 总是返回controlPoints中的第一个点。 I suspected the problem is because Vector2 is a value type, but that doesn't seem to be the case.我怀疑问题是因为Vector2是一种值类型,但似乎并非如此。

I think there are 2 issues here.我认为这里有两个问题。

  1. Your ranges don't look right.你的范围看起来不正确。
  2. You performing integer division, and it's not going to work out well.你执行 integer 除法,结果不会很好。

For the operands of integer types, the result of the / operator is of an integer type and equals the quotient of the two operands rounded towards zero... And, I know in the cockles of my heart you don't want this.对于 integer 类型的操作数, /运算符的结果是 integer 类型并且等于向零舍入的两个操作数的商......而且,我知道在我心中你不想要这个。

Given给定

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);

}

Note : I am using ReadOnlySpan , because well... why not, it's super efficient to slice and can use C# ranges.注意:我使用的是ReadOnlySpan ,因为嗯......为什么不呢,切片效率很高,可以使用 C# 范围。

Usage用法

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));

Disclaimer : I have never written python code in my life (and don't want to start:p), Also I have no idea of what a Recursive Bezier Curve Algorithm actually does, so I am not really sure if the ranges are right, or if there is anything else wrong with the code.免责声明:我一生中从未编写过 python 代码(也不想开始:p),而且我不知道递归贝塞尔曲线算法实际上是做什么的,所以我不确定范围是否正确,或者代码是否有其他问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM