【问题标题】:How to compare shape of Bezier curves如何比较贝塞尔曲线的形状
【发布时间】:2015-04-19 19:35:02
【问题描述】:
【问题讨论】:
标签:
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】:
根据您提供的示例,我假设
如果旋转曲线不相同
-
N 个点采样曲线
- 只需逐步执行参数...
- 对于三次曲线,我将使用 16 到 32 个采样点
- 点越多,比较越精确
- 但是更大的运行时间...
-
计算每段的角度
-
比较这些数组
如果旋转相似的曲线应该是相同的
-
轮换
- 然后执行上述操作几圈(例如 0,10,20,...,350 度)
- 如果有,如果它们是相同的,则停止并返回 true
- 如果没有则返回 false
- 曲线的旋转实际上只是为其所有角度添加一个常数...
-
旋转不变性
- 如果您偏移两个比较曲线角度以从角度 0 开始
- 所以只需从曲线的所有角度中减去第一个角度
- 然后将两条曲线相互对齐,因此只需要 2 个位置进行比较
- 所以你比较一下
- 如果不相同,则在一条曲线上添加 180 度并再次比较
- 够了
[备注]