【问题标题】:Drag a bezier curve to edit it拖动贝塞尔曲线进行编辑
【发布时间】:2010-02-23 09:01:04
【问题描述】:

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

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

【问题讨论】:

    标签: edit bezier curve


    【解决方案1】:

    有多种方法可以完成您所看到的内容,具体取决于您希望它的行为方式。我将解释一些通过点对曲线操作来修改贝塞尔曲线的更简单方法。

    首先要做的是找出用户点击曲线的参数值(t)。这通常是一个近似值。如果您正在对 Bezier 进行像素或子像素渲染,那么只需记录每个像素的 t 值并使用它。如果要细分成线段,看哪条线段最近,找到两个端点的 t 值,根据沿线的距离调整 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 和大多数其他样条线,甚至是曲面。还有另一种相当常见的方法,它使用 Greville Abscissae,它尽可能多地固定点,但根据我的经验,它太容易产生振荡。

    【讨论】:

    • 他所指的 k0、k1、k2 和 k3 常数如下,取自贝塞尔曲线的多项式形式: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 值也会发生变化。 (desmos.com/calculator/sx8vx9is7b)
    • 请注意,这些常数的真实名称是每个贝塞尔项的“二项式系数”,并且通常以所谓的“n 选择 k”形式描述(即两个数字,一个在另一个之上, 在高括号中)
    • 是的,有很多方法可以引用常数 - 二项式系数很好,伯恩斯坦基,混合函数,凸组合系数。该方法也适用于可能使用不同基函数的其他类型的参数曲线和曲面(甚至是 subds)
    【解决方案2】:

    编辑 - 回应您的问题编辑

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

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

    原文

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

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

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

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

    【讨论】:

    • 我应该提到,使用贝塞尔曲线最接近匹配控制点的是创建一串 3 点曲线。每条曲线的终点设置为等于下一条曲线的起点。然后,两条曲线连接点两侧的两个中点应设置为围绕连接点镜像,从而强制它们之间平滑连接。然而,曲线仍然永远不会通过中点。
    【解决方案3】:

    拖动只是改变了贝塞尔曲线的控制点,并相应地重新计算曲线。请参阅Wikipedia,了解它们的工作原理。

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        好的,所以让我们假设您必须使用贝塞尔曲线,因为您使用的是一个将它们作为基元的渲染库。如果您完全赞同在曲线本身上使用控制点的想法,您可以使用此处概述的方法插入控制点:How to find control points for a BezierSegment given Start, End, and 2 Intersection Pts in C# - AKA Cubic Bezier 4-point Interpolation

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

        【讨论】:

          【解决方案6】:

          请参阅 github.com/bootchk/freehandTool 了解对象模型

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-10
            • 2018-11-01
            相关资源
            最近更新 更多