在不同程度的贝塞尔曲线之间转换(顺序)

时间:2017-05-20 10:32:04

标签: c# unity3d unityscript bezier curves

我正在处理涉及Bezier曲线的个人项目。我已经看到许多实现单独处理二次曲线和三次曲线,但我希望创建一个更通用的算法,我可以通过增加和减少曲线的度数(顺序)来添加和删除控制点。

这不是我主要问题的一部分,但如果有人知道我可以看到的广义算法的例子,我将不胜感激,如果他们可以指出我的方向。

首先,我知道从低阶到高阶曲线的任何转换都是近似值,而不是等价的。我很满意计算和#34;足够接近"。

其次,我也明白从较高阶到较低阶曲线时,信息会丢失。这是不可避免的,因为高阶曲线有更多的弯曲"在曲线中,低阶曲线根本无法逼近。

我对这些限制很好,因为必须能够在曲线内添加和减去控制点以获得所需的功能。

我的第一个问题与大约5年前提出的问题有关: Convert quadratic curve to cubic curve

二次曲线有三(3)个控制点:

Vector3 Start;
Vector3 Control1;
Vector3 End;

转换为立方体我们引入了第四个控制点...

Vector3 Control2;

..."之间" Control1和End。然后我们相应地设置Control1和Control2:

Control2 = new Vector3(
    End.x + ((2.0f / 3.0f) * (Control1.x - End.x)), 
    End.y + ((2.0f / 3.0f) * (Control1.y - End.y)), 
    End.z + ((2.0f / 3.0f) * (Control1.z - End.z))
); 
Control1 = new Vector3(
    Start.x + ((2.0f / 3.0f) * (Control1.x - Start.x)), 
    Start.y + ((2.0f / 3.0f) * (Control1.y - Start.y)), 
    Start.z + ((2.0f / 3.0f) * (Control1.z - Start.z))
); 

我不确定这是否正确。在示例中,只有' x'组件已设置。我只是推断出' y'和' z'从中。如果这不正确,那么我很高兴知道什么是正确的。

此示例仅涵盖从二次曲线到三次曲线的转换。设置坐标时,控制值似乎是(2.0f / 3.0f)。那么,这是否意味着从立方到四次转换将是(2.0f / 4.0f)或(3.0f / 4.0f)或其他完全?对于任意曲线顺序,此转换的适当广义函数是什么?

我的项目也将使用样条线。我正在使用边对边方法来构造我的样条曲线,其中边被定义为从1(一条线)到n的任意有序曲线,其中控制点列表中的第一个和最后一个Vector3是起点和终点。边缘和连接边缘共享前一边缘的终点与下一个边缘的起点。

与贝塞尔曲线不同,我不添加和减去控制点。相反,我划分和组合边缘。将曲线细分为两条低阶曲线并且序数不低于2近似原始曲线的好方法是什么?同样,将两条曲线组合成单个高阶曲线的好方法是什么?

我意识到在一篇文章中要提出这个问题很多,但我认为最好将它放在一个主题中,而不是将其分开。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您需要阅读http://pomax.github.io/bezierinfo/#reordering了解如何将曲线提升到更高的顺序,这几乎是微不足道的:

enter image description here

这可能看起来很可怕,但如果你真的看看这三个术语中的每一个是什么,那三个都是愚蠢的小学数学。您通常只需要新的权重,因此将这些权重生成为新的坐标列表绝对是微不足道的,并在大约一分钟内完成。在Javascript中:

function getOneHigher(x, y):
  n = x.length;
  k = n + 1;
  s = n - 1;

  let nx = [], ny =[];
  nx[0] = x[0]; nx[n] = x[s];
  ny[0] = y[0]; ny[n] = y[s];

  for (let i=1; i<n; i++) {
    nx[i] = (n*x[i] + i*x[i-1]) / k;
    ny[i] = (n*y[i] + i*y[i-1]) / k;
  }

  return {nx, ny};
}

我们已经完成了。调用getOneHigher(x, y)将为同一曲线产生两个新坐标数组,表示为比我们输入的高一度的Bezier曲线。注意,这意味着我们保持曲线坐标集为相同(字面意思:函数是相同的)同时减少每个坐标处的切线(因为导数相同),有效地“减慢”沿着该曲线所经过的路径传播的任何东西。

您还可以在该部分中关注Sirver's Castle的链接,其中解释了how to do the lossy conversion down in a way that minimizes loss of information。这应该是多个问题:这是一个Q&amp; A网站,如果您没有提出具体问题,将来的访问者无法找到具体问题的答案,而是将一些技术上无关的问题合并在一个帖子中。