递归贝塞尔曲线算法在 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
是一个值类型,但似乎并非如此。
我认为这里有两个问题。
- 您的范围看起来不正确。
- 您执行整数除法,结果不会很好。
对于整数类型的操作数,/
运算符的结果是整数类型,等于两个操作数的商向零舍入......而且,我知道在我的心你不想要这个。
给定
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 ), 另外我不知道递归贝塞尔曲线算法实际上做了什么,所以我不确定范围是否正确,或者代码是否还有其他问题。
我在此 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
是一个值类型,但似乎并非如此。
我认为这里有两个问题。
- 您的范围看起来不正确。
- 您执行整数除法,结果不会很好。
对于整数类型的操作数,/
运算符的结果是整数类型,等于两个操作数的商向零舍入......而且,我知道在我的心你不想要这个。
给定
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 ), 另外我不知道递归贝塞尔曲线算法实际上做了什么,所以我不确定范围是否正确,或者代码是否还有其他问题。