6

如果您使用 Gimp 或 Photoshop 等图形编辑程序,您就会明白我的意思。要在这些程序上编辑曲线(可能是贝塞尔曲线),我们可以点击曲线,拖动鼠标,曲线会相应地改变。我怀疑这个机制背后的所有东西都与向量有关,但我找不到任何文件提到如何做到这一点。谁能告诉我我该怎么做?非常感谢。

[编辑] 我的意思是选择曲线本身来改变(编辑)它(点击曲线,然后拖动曲线来编辑它)。通常,我们选择控制点来改变曲线。我知道要更改曲线,我需要编辑控制点,但是如何将曲线上的更改解释为对控制点的更改?

4

6 回答 6

3

There are a number of ways of accomplishing what you're seeing, depending on how you'd like it to behave. I'll explain some of the simpler methods of modifying a Bezier curve via point on curve manipulation.

The first thing to do is figure out the parameter value (t) where the user clicked on the curve. This is generally going to be an approximation. If you're doing pixel or sub-pixel rendering of the Bezier, then just record for every pixel what the t value was and use that. If you're tessellating into line segments, see which line segment is closest, find the t values of the two end points, and lerp the t value according to the distance along the line.

Once you have the t value, you can plug it into the Bezier curve equation. You'll end up with something of the form:

P = k0*P0 + k1*P1 + k2*P2 + k3*P3

where P is the point on the curve, P0, P1, P2, and P3 are the input control points, and k0, k1, k2, and k3 are constants for a given t. I'll call the k values 'contributions', or more specifically the contributions of control points to the point on the curve P(t). A nice property to remember is that k0+k1+k2+k3 = 1.

So, let's say you have a vector V = P' - P, where P' is the new position and P is the original position. We need to move some of the control points to get P' where it needs to go, but we have some flexibility about which of the control points we want to move. Any point with non-zero contribution can be used, or some combination.

Let's say the user clicks on the curve at t=0. In this case, only k0 is non-zero, so

P0 := P0 + V

will produce the correct result. This can also be written as

P0 := P0 + k0 * V

In the general case where all of the contributions are nonzero, you can apply the same transformation to each of the points, which will have the effect of a very smooth, spread-out deformation.

Another option is to simply move the control point with the maximum contribution the entire distance. I think the equation to use would be something like

Pmax := Pmax + 1/kmax * V

but either way it boils down to looking at the contributions at a given t value, and moving the control points so the new point lies in the desired location.

This approach is fairly general, and works for NURBS and most other splines, even surfaces. There is another method that's fairly common that uses Greville Abscissae, which pins as many points as possible, but in my experience it's too easy to get oscillation.

于 2010-02-24T21:08:53.080 回答
1

编辑 - 回应您的问题编辑

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

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

原文

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

您的控制点决定了曲线的走向,因此您只需实现选择反馈并在这些控制点上拖放。

但是,如果您正在寻找精确的点匹配,贝塞尔曲线并不理想,因为它们只通过第一个和最后一个控制点。添加到曲线上的点越多,它们变得越不准确。

B-Splines 会更好,这些变体是您在 Photoshop 等人中实际看到的。

于 2010-02-23T09:09:10.550 回答
0

好的,所以让我们假设您必须使用贝塞尔曲线,因为您正在使用将它们作为基元的渲染库。如果您完全赞同在曲线本身上使用控制点的想法,您可以使用此处概述的方法插入控制点:如何在 C# 中给定开始、结束和 2 个交点的 BezierSegment 找到控制点 - AKA 三次 Bezier 4 点插值

换句话说,对于曲线上的每组 4 个点,您将运行上述算法并获得绘制三次贝塞尔曲线所需的 4 个控制点。

于 2010-02-23T09:39:07.377 回答
0

拖动只是更改贝塞尔曲线的控制点,并相应地重新计算曲线。有关它们如何工作的详细说明,请参阅Wikipedia 。

于 2010-02-23T09:08:11.830 回答
0

请澄清你想做什么?您想在应用程序中编辑贝塞尔曲线吗?你对它背后的一般数学感兴趣吗?

通常,您操纵用于生成贝塞尔曲线的控制点。

于 2010-02-23T09:08:19.513 回答
0

有关对象模型,请参阅 github.com/bootchk/freehandTool

用户拖动。将拖动投射到最近的控制点或控制点之间的手臂上。将拖动解释为所述最近控制点的旋转和/或平移(变换)。注意复数:最近的可能是两个线段的重合控制点(端点),也可能是贝塞尔线段臂的控制点。

于 2012-05-25T09:00:17.683 回答