拖动贝塞尔曲线以进行编辑。

6
如果您使用Gimp或Photoshop等图形编辑程序,您将理解我的意思。要在这些程序中编辑曲线(可能是Bezier曲线),我们可以单击曲线,拖动鼠标,曲线会相应地更改。我怀疑这个机制背后的所有东西都与向量有关,但我找不到任何提及如何做到这一点的文档。请问有人可以告诉我如何做到这一点吗?非常感谢。
[编辑]我的意思是选择曲线本身来更改(编辑)它(单击曲线,拖动曲线以编辑它)。通常情况下,我们选择控制点来更改曲线。我知道要更改曲线,我需要编辑控制点,但是如何将曲线上的更改解释为对控制点的更改呢?
6个回答

3
有许多方法可以实现您所看到的效果,具体取决于您希望它如何运作。我将解释一些简单的通过点对曲线进行修改的贝塞尔曲线方法。
首先要做的是确定用户在曲线上点击时的参数值(t)。这通常会是一个近似值。如果您正在进行像素或子像素渲染,则只需记录每个像素的t值并使用该值。如果您正在将其分割成线段,则查找最接近的线段,找到两个端点的t值,并根据沿线距离lerp t值。
一旦您有了t值,就可以将其插入到贝塞尔曲线方程中。您最终会得到以下形式的内容:
P = k0*P0 + k1*P1 + k2*P2 + k3*P3

其中P是曲线上的点,P0、P1、P2和P3是输入控制点,k0、k1、k2和k3是给定t的常数。我将称k值为“贡献”,更具体地说,是控制点对曲线上点P(t)的贡献。一个需要记住的好特性是k0+k1+k2+k3=1。

因此,假设您有一个向量V=P'-P,其中P'是新位置,P是原始位置。我们需要移动一些控制点以使P'到达所需位置,但我们可以灵活选择要移动哪个控制点。任何具有非零贡献的点都可以使用,或者是某些组合。

假设用户在t=0处单击曲线。在这种情况下,只有k0是非零的,因此

P0 := P0 + V

将会产生正确的结果。这也可以写成

P0 := P0 + k0 * V

在所有贡献都非零的一般情况下,您可以对每个点应用相同的变换,这将产生非常平滑、扩散的变形效果。
另一个选择是仅移动贡献最大的控制点整个距离。我认为要使用的方程式类似于:
Pmax := Pmax + 1/kmax * V

但无论如何,归根结底都是要查看给定t值的贡献,并移动控制点,使新点位于所需位置。这种方法相当通用,并适用于NURBS和大多数其他样条线,甚至曲面。还有另一种方法比较常见,使用格雷维尔纵坐标,它会固定尽可能多的点,但据我的经验,很容易出现振荡。

他所提到的k0、k1、k2和k3常数来自于Bézier曲线的多项式形式,具体如下:C(t) = (1-t)³ * P0 + 3*(1-t)²*t * P1 + 3*(1-t)*t² * P2 + t³ * P3 | 因此,k0 = (1-t)³ | k1 = 3.0 * (1-t)² * t | k2 = 3*(1-t)*t² | k3 = t³ | 每当t改变时,所有这些k值也会随之改变。(https://www.desmos.com/calculator/sx8vx9is7b) - R. Navega
请注意,这些常量的真实名称是每个Bezier项的“二项式系数”,通常以所谓的“n选择k”形式描述(即两个数字,一个在另一个上方,用高括号括起来)。 - Mike 'Pomax' Kamermans
是的,有很多方法可以引用常量 - 二项式系数是不错的选择,伯恩斯坦基、混合函数、凸组合系数。该方法也适用于其他类型的参数曲线和曲面(甚至子细分),这些曲线和曲面可能使用不同的基函数。 - tfinniga

1

编辑 - 回答您的问题后编辑

为了能够选择曲线本身以移动控制点,我建议贝塞尔曲线绝对不是正确的方法 - 您需要反向解方程才能找到正确的控制点位置。您还会发现,在某些情况下,移动控制点以使曲线走向所需位置实际上是不可能的。

如果您使用B样条,则可以在最接近用户单击位置的曲线上插入一个新的控制点,然后移动新的控制点。因此,实际上,您将添加一个新的控制点。

原始文本

假设您已经实现了贝塞尔曲线,给定一组控制点(通常为三个贝塞尔点,但可以是任意数量),可以生成一组要与显示设备上的线连接的点(通常使用0>= u <= 1参数方程式),那么这很容易。

您的控制点确定曲线的走向,因此您只需要在这些控制点上实现选择反馈和拖放即可。

如果你正在寻找精确的点匹配,贝塞尔曲线并不是理想的选择,因为它们只通过第一个和最后一个控制点。而且,你添加到曲线上的点越多,它们就越不准确。
B样条曲线会更好一些,实际上在Photoshop等软件中看到的就是这种曲线的变体。

我应该提到用贝塞尔曲线最接近匹配控制点的方法是创建一串由3个点组成的曲线。每条曲线的终点设置为下一条曲线的起点。然后,两个曲线连接点两侧的中点应该被设置为以连接点为中心进行镜像,强制它们之间平滑连接。但是,曲线仍然永远不会通过中点。 - Andras Zoltan

0

拖动只是改变贝塞尔曲线的控制点,曲线会相应地重新计算。请参阅维基百科,了解它们如何工作的良好解释。


0
请澄清您希望做什么?您想在应用程序中编辑贝塞尔曲线吗?您是否对其背后的数学原理感兴趣?
通常,您会操纵用于生成贝塞尔曲线的控制点。

0

0
请参见github.com/bootchk/freehandTool获取对象模型。
用户拖动。将拖动投影到最近的控制点或两个控制点之间的手臂上。将拖动解释为所述最近控制点的旋转和/或平移(变换)。注意复数:最近可能是两个线段的重合控制点(端点)或贝塞尔线段的手臂的控制点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接