通过三点的贝塞尔曲线

发布于 2024-10-14 19:26:54 字数 312 浏览 9 评论 0原文

我已经阅读了类似的主题以找到解决方案,但没有成功。 我想做的是使该工具与 CorelDraw 中的工具相同,名为“钢笔工具”。我通过连接贝塞尔三次曲线来做到这一点,但仍然缺少一个功能,即拖动曲线(而不是控制点)以编辑其形状。

我可以成功确定曲线上应开始拖动的“t”参数,但不知道如何重新计算该曲线的控制点。

在这里,我想强调一些与 CorelDraw 的 PenTool 行为相关的内容,这些行为可用作约束。我注意到,当严格垂直或水平拖动曲线时,该贝塞尔曲线的控制点会相应地表现,即它们分别在垂直或水平方向上移动。

那么,如何在曲线拖动时重新计算控制点的位置呢?

I have read similar topics in order to find solution, but with no success.
What I'm trying to do is make the tool same as can be found in CorelDraw, named "Pen Tool". I did it by connecting Bezier cubic curves, but still missing one feature, which is dragging curve (not control point) in order to edit its shape.

I can successfully determine the "t" parameter on the curve where dragging should begin, but don't know how to recalculate control points of that curve.

Here I want to higlight some things related to CorelDraw''s PenTool behaviour that may be used as constaints. I've noticed that when dragging curve strictly vertically, or horizontally, control points of that Bezier curve behave accordingly, i.e. they move on their verticals, or horizontals, respectively.

So, how can I recalculate positions of control points while curve dragging?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陈独秀 2024-10-21 19:26:54

我刚刚查看了 Inkspace 源代码并找到了这样的代码,可能对您有帮助:

// Magic Bezier Drag Equations follow!
// "weight" describes how the influence of the drag should be distributed
// among the handles; 0 = front handle only, 1 = back handle only.
double weight, t = _t;
if (t <= 1.0 / 6.0) weight = 0;
else if (t <= 0.5) weight = (pow((6 * t - 1) / 2.0, 3)) / 2;
else if (t <= 5.0 / 6.0) weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
else weight = 1;

Geom::Point delta = new_pos - position();
Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta;
Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta;

first->front()->move(first->front()->position() + offset0);
second->back()->move(second->back()->position() + offset1);

在您的情况下,“first->front()”和“second->back()”意味着两个控制点

Ive just look into Inkspace sources and found such code, may be it help you:

// Magic Bezier Drag Equations follow!
// "weight" describes how the influence of the drag should be distributed
// among the handles; 0 = front handle only, 1 = back handle only.
double weight, t = _t;
if (t <= 1.0 / 6.0) weight = 0;
else if (t <= 0.5) weight = (pow((6 * t - 1) / 2.0, 3)) / 2;
else if (t <= 5.0 / 6.0) weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
else weight = 1;

Geom::Point delta = new_pos - position();
Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta;
Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta;

first->front()->move(first->front()->position() + offset0);
second->back()->move(second->back()->position() + offset1);

In you case "first->front()" and "second->back()" would mean two control points

濫情▎り 2024-10-21 19:26:54

贝塞尔曲线只不过是两个多项式:X(t), Y(t)

三次:

x = ax*t^3 + bx*t^2 + cx*t + dx
                               0 <= t <= 1
y = ay*t^3 + by*t^2 + cy*t + dy

所以如果你有一条曲线 - 你就有了多项系数。如果您移动点并且知道它的 t 参数 - 那么您可以简单地重新计算多边形的系数 - 它将是一个由 6 个系数线性方程组成的系统(对于每个点)。该系统被细分为两个系统(x 和 y),并且可以精确求解或使用一些数值方法 - 它们也不难。

因此,您现在的任务是在知道曲线的显式方程后计算曲线的控制点。

也可以带入线性系统。我不知道如何处理广义贝塞尔曲线,但对于三次或二次曲线来说并不难。

通过控制点的三次曲线:

B(t) = (1-t)^3*P0 + 3(1-t)^2*t*P1 + 3(1-t)*t^2*P2 + t^3*P3

您所要做的就是生成标准多项式形式(只需打开括号)并使系数相等。这将提供最终的控制点系统!

The bezier curve is nothing more then two polynomials: X(t), Y(t).

The cubic one:

x = ax*t^3 + bx*t^2 + cx*t + dx
                               0 <= t <= 1
y = ay*t^3 + by*t^2 + cy*t + dy

So if you have a curve - you have the poly coefficients. If you move your point and you know it's t parameter - then you can simply recalculate the poly's coefficients - it will be a system of 6 linear equations for coefficients (for each of the point). The system is subdivided per two systems (x and y) and can be solved exactly or using some numerical methods - they are not hard too.

So your task now is to calculate control points of your curve when you know the explicit equation of your curve.

It can be also brought to the linear system. I don't know how to do it for generalized Bezier curve, but it is not hard for cubic or quadric curves.

The cubic curve via control points:

B(t) = (1-t)^3*P0 + 3(1-t)^2*t*P1 + 3(1-t)*t^2*P2 + t^3*P3

Everything you have to do is to produce the standard polynomial form (just open the brackets) and to equate the coefficients. That will provide the final system for control points!

像极了他 2024-10-21 19:26:54

当您点击曲线时,您已经知道当前控制点的位置。因此,您可以计算从该点到鼠标位置的偏移 X 和偏移 Y。如果鼠标移动,您将能够借助 X/Y 偏移重新计算新的控制点。

对不起我的英语

When you clicks on curve, you already know position of current control point. So you can calculate offset X and offset Y from that point to mouse position. In case of mouse move, you would be able to recalculate new control point with help of X/Y offsets.

Sorry for my english

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文