问题描述
我需要在 C# (Unity) 中以曲线的形式实现连接。我希望得到与 Miro.com 中的实现尽可能相似的结果(见截图)。
附加曲线后,我计算三次贝塞尔曲线的路径。对于第一段,使用锚点和它连接的对象的偏移量。在这个阶段没有问题。
问题:当通过单击并拖动线段的蓝点之一(见屏幕截图)将曲线分成线段时,它在中间被分成两部分。在两条新曲线的交汇处,形成了一个新的交互(可移动)点,其控制点的切线和坐标未知。每次交互点的位置发生变化(下图中的白点)时,我都需要找到这些控制点的位置。此外,曲线在分割时不应大幅改变其位置,不应形成循环,具有不同长度的控制点向量(我在这里不确定)并尽可能表现得足够好(就像在 Miro 的板上一样)。
我所说的控制点是指贝塞尔线段的 2 个不可见引导点。
我用黑色画了已知的控制点,用红色画了我需要找到的那些。 (Pn - 交互点,Cn - 控制点)
我试图找到它们的算法给出了不正确的控制点距离和方向。
测试了以下算法:
- 来自Tacent的插值 - 分离时曲线的跳跃,控制点的方向和缩进量不合适;
- Chaikin 算法 - 分离过程中曲线跳跃,创建循环;
- 基于猜测的“自定义”插值(考虑到线段起点和终点之间到线段中心的距离,以及起点和终点之间的方向)-具有相同的问题,但看起来比上面的略好。
我怀疑解决方案是使用 Catmull-Rom 样条对这些点进行弦插值,并将结果转换为 Bezier 曲线的点。但是,在实施方面仍然存在问题。
3DMax 的曲线看起来也非常相似。在他们的文档中,我发现只提到了参数曲线。
我没有使用(或不起作用)的方法:
- Catmull-Rom 插值;
- B 样条插值;
- 厄米插值;
- De Casteljau 的算法(虽然似乎不是为了这个)
如果能得到任何帮助,我将不胜感激,但我要求提供尽可能多的细节。
解决方法
为了做你想做的事,我会尝试使用 Catmull-Rom 方法,我认为它比 Bezier 方法简单得多,后者是 itween 资产中使用的方法,它是免费的,而且你实现了大量功能。
如果你想坚持使用贝塞尔曲线并找到控制点,我会告诉你我会怎么做才能找到它们。
对于2个控制点贝塞尔曲线的情况:
P = (1-t)P1 + tP2
要了解控制点 P1(x1,y1) 和 P2(x2,y2),您需要在曲线的已知点中应用该方程。考虑到 2D 方程是向量的,所以每个点提供 2 个方程,一个用于 x,一个用于 y,并且每个点有 4 个未知数,x 和 y。
因此对于曲线的第一个节点 (t=0),您将:
Px = (1-0)P1x + 0*P2x
Py = (1-0)P1y + 0*P2y
对于最后一点(t=1)
Px = (1-1)P1x + 1*P2x
Py = (1-1)P1y + 1*P2y
通过这 4 个方程,我将尝试实现控制点 P1 和 P2。您可以使用 t=0 和 t=1 来完成它,它们是您知道曲线的假设点以及由于 t 值而简化数学的那些点,但是只要您知道这些点,您就应该能够使用任何点确定 t 曲线中的坐标。
如果曲线是 3 个控制点的贝塞尔曲线,则需要 6 个方程来对应 3 个控制点,依此类推。
我认为最好的方法是复合三次曲线组合的曲线,并计算每个块的控制点,但我不确定这一点。
一旦理解了数学并实现了控制点,如果成功,我会尝试在代码中实现。