我有一个固定的svg形状集(每个都有一个),每个形状包含一个<path>
。想象一下,任何数量的这些形状都放在新文档的任何位置。然后,我根据需要对每个形状应用以下任何操作:
然后将这些操作呈现为新路径(不使用任何svg操作,如transform属性)。基本上,它是adobe illustrator save-as-svg的输出。
鉴于任意此类文档,我想找到一种算法,将其反向工程为形状和操作列表,如
可以强制说明文档中的形状是使用图层ID以各自的“原始”形状命名的,但我希望尽可能避免这种形状。
我的第一个想法是为形状识别它们制作某种形式的散列(可以是x个散列,每个镜像操作一个),然后在形状中使用两个参考点来找到旋转。其中一个版本可以是测量形状中各点之间所有距离的绝对值,并用此除以点之间的每个距离,以获得唯一的散列。虽然Scale x / y要求似乎让这个想法变得非常糟糕。不幸的是,我不能放弃这个要求。
答案 0 :(得分:1)
你对形状所做的是affine transformation,你的问题是找到可以通过仿射变换相互映射的形状。假设点的顺序保持不变,这不是太难。
仿射变换可以写成线性映射:(1)P'_k = A P_k+b
。 P_k
是原始点,写为包含x和y分量的2向量:P_k = (x, y)
。 P'_k
是映射点。 A
是一个未知的2x2矩阵。 b
是2x1向量。当且仅当存在A
和b
时,两个形状彼此对应,以便可以使用(1)将来自一个形状的点映射到另一个形状的点。 A
有2x2 = 4个值,b
有2个值,因此它们共有6个值。这些值可以通过将上述等式写成至少3个点来确定:P'1 = A P1+b
; P'2 = A P2+b
; P'3 = A P3+b
;每个都是二维矢量方程,因此这3个矢量方程可以写成6个标量方程。这6个标量方程形成一个线性方程组,可以求解A
和b
的系数。因此,一般位置的三个点(即不在直线上)足以确定A
和b
的元素。当您拥有这些值时,您可以检查其余点是否也适合该地图(1),如果是这种情况,则形状相互对应。
更健壮的方法是为形状中的所有点写入(1),得到over-determined linear equation system。我不会详细介绍,但你基本上必须找到least-square solution,并检查该解决方案的准确性。如果残差足够低,则形状彼此对应。这更加强大,因为你平等对待所有点,而不是选择三个点。