【问题标题】:How to compare shape of Bezier curves如何比较贝塞尔曲线的形状
【发布时间】:2015-04-19 19:35:02
【问题描述】:

我想比较 2 条贝塞尔曲线。我知道端点和控制点的坐标,但是对于 2 条比较曲线,这个坐标可能不一样。我需要比较这条曲线的形状。要“真实”,形状必须大致相同。

我使用 javascript 和 paper.js。

请看图片:

https://habrastorage.org/files/825/6e5/36c/8256e536c9ce4f01bf12d792473038d5.png

出路在哪里?谢谢。

【问题讨论】:

    标签: javascript algorithm vector-graphics image-recognition paperjs


    【解决方案1】:

    首先通过计算 T(转换)矩阵 (-P0) 尝试 X 轴对齐三次曲线,P0 是曲线的第一个控制点。和一个 R(otation) 矩阵(旋转角度需要将最后一个控制点 P3 降落在轴上,你可以算出)。

    一旦曲线与轴对齐,您只需要担心曲线的核心(P1 和 P2)。您可以将它们与另一条曲线的值进行比较,以获得自定义的预定义错误阈值,并查看两条曲线是否匹配。

    【讨论】:

      【解决方案2】:

      三次贝塞尔样条曲线由任意四个点定义:start、control-1、control-2 和 end,我将其编号为 0、1、2、3。现在我们假设这四个点是不同,而且没有三个在一条直线上。

      曲线可以采取三种根本不同的形式,取决于线 0--1 和 1--2 之间、1--2 和 2--3 之间的转弯方向,以及 0--1 和2--3交叉。

      在类型 1 中,两个转弯都在右侧,或者都在左侧,并且 0--1 不与 2--3 交叉。在提问者的例子中,这给出了一条曲线,如 a、b 或 c。在类型 2 中,第一个转向左侧,第二个转向右侧,或反之亦然,给出类似于提问者示例中的 d 的曲线,带有一个扭结。在类型 3 中,两个转弯的方向相同,但线 0--1 和 2--3 交叉,形成带环的曲线。

      我们可以首先将单个三次样条分类为三种类型之一,给它们一个类型字符串:普通('' - 空字符串),扭结('K')和循环('L')。

      但是,示例 e 由两个平滑连接的三次样条组成。为了处理这样的序列,我们遍历它们并创建一个字符串,为每个扭结曲线附加一个 K,为每个循环曲线附加一个 L。我们还为两条样条线之间的每个连接添加一个 K,其中连接之前的转弯与之后的转弯相反:先左后右,或先右后左。

      这为我们提供了类型字符串“K”,例如 e,根据需要将其与 d 匹配。

      我们还允许一种类型字符串与另一种类型字符串相反的匹配:因此 'KL' 匹配 'LK'。

      【讨论】:

        【解决方案3】:

        根据您提供的示例,我假设

        • 大小不相关
        • 形状可以扭曲到一个点

        如果旋转曲线不相同

        1. N 个点采样曲线

          • 只需逐步执行参数...
          • 对于三次曲线,我将使用 16 到 32 个采样点
          • 点越多,比较越精确
          • 但是更大的运行时间...
        2. 计算每段的角度

          • 使用 atan2 或 atanxy
          • 将这些角度存储在数组中
        3. 比较这些数组

          • 正确执行此操作的最佳和最简单的方法是correlation coefficient
          • 如果相关系数接近+1,则形状相似或相同

        如果旋转相似的曲线应该是相同的

        1. 轮换

          • 然后执行上述操作几圈(例如 0,10,20,...,350 度)
          • 如果有,如果它们是相同的,则停止并返回 true
          • 如果没有则返回 false
          • 曲线的旋转实际上只是为其所有角度添加一个常数...
        2. 旋转不变性

          • 如果您偏移两个比较曲线角度以从角度 0 开始
          • 所以只需从曲线的所有角度中减去第一个角度
          • 然后将两条曲线相互对齐,因此只需要 2 个位置进行比较
          • 所以你比较一下
          • 如果不相同,则在一条曲线上添加 180 度并再次比较
          • 够了

        [备注]

        • 您应该在相关之前对所有角度进行归一化(使其达到区间<0.0,2.0*PI>
        • 更多想法请看这里How to compare two shapes?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-10
          • 2016-10-05
          • 1970-01-01
          • 2013-01-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多