Python 如何将SVG多段线转换为quickdraw stroke-3 numpy格式?
我想将包含多段线的基本SVG文件转换为(和)使用的stroke-3格式 据我所知,stroke-3格式中的每个多段线点应为:Python 如何将SVG多段线转换为quickdraw stroke-3 numpy格式?,python,numpy,svg,Python,Numpy,Svg,我想将包含多段线的基本SVG文件转换为(和)使用的stroke-3格式 据我所知,stroke-3格式中的每个多段线点应为: 存储为[delta\u x,delta\u y,pen\u up],其中 delta_x,delta_y表示相对于 前一点和 pen\u up是一个位,当笔向上时为1 (例如,move_tooperation a-la-turtle graphics)或当笔处于打开状态时为0 向下(例如,line\u至a-la操作) 我曾尝试编写函数并转换SVG,但在渲染stroke
- 存储为
,其中[delta\u x,delta\u y,pen\u up]
,delta_x
表示相对于 前一点和delta_y
是一个位,当笔向上时为1 (例如,pen\u up
operation a-la-turtle graphics)或当笔处于打开状态时为0 向下(例如,move_to
a-la操作)line\u至
您的转换是正确的,错误在渲染代码中。它必须是is_down=data[i][2]==0
而不是draw\u stroke3
中的is_down=data[i-1][2]==0
此错误不会与其他路径一起显示,因为在所有情况下,新路径都从上一条路径的末尾开始,只有两种情况除外。在另一种情况下,如果您真的移动到一个新的起点,则附加的线与已绘制的线重合
更新和更正:
我注意到,我错误地解释了向上笔划的含义:事实上,它表明,在绘制当前笔划后,笔将被提起,而不是像我最初认为的那样,针对当前笔划。因此,渲染代码似乎正常,错误出现在stroke3文件生成中。
我想您可以通过记录每个操作的结束点以及当前操作的操作代码(
1
=move,0
=draw)来简化操作。转换为numpy阵列后,我们可以通过计算前两列的差值,然后使用op代码将第三列向后移动一个位置,轻松地将这些绝对位置转换为相对位移:
def svg_to_stroke3(svg_string):
doc = ET.fromstring(svg_string)
paths = doc.findall('.//{http://www.w3.org/2000/svg}path')
strokes = [[0,0,0]]
for path in paths:
stroke = parse_path(path.attrib['d'])
for op in stroke:
if isinstance(op, Move):
strokes.append([op.start.real, op.start.imag, 1])
if isinstance(op, Line):
strokes.append([op.end.real, op.end.imag, 0])
strokes_np = np.array(strokes, dtype=np.int16)
# convert x,y columns to relative displacements
strokes_np[1:,:2] -= strokes_np[:-1,:2]
# shift back op codes
strokes_np[:-1,2] = strokes_np[1:,2]
# remove [0,0,0]s and set previous op to 0
m = (strokes_np == 0).all(1)
strokes_np[np.argwhere(m)-1,2] = 0
return strokes_np[~m]
这提供了一个相当紧凑的表示(示例立方体为49行),并使用您的原始代码和David Ha的
draw_strokes()
(如果您按照惯例以draw_strokes()。不过我还是有点困惑。我用这个方法渲染了相同的数据,但我仍然得到了对角线,这就是为什么我感到困惑的原因。我添加了这个测试。请注意cube\u gp
(我的SVG解析版本)、cube\u dh
(然后将SVG转换为行)…..和cube\u dh\u mod
之间的区别,其中一个版本的cube\u dh
我手动编辑以删除冗余的[0,0]
条目(将上一个笔划从1位修改为0位以保持钢笔向下)。此方法的总笔划数最少/在数据方面似乎最干净。我以编程方式执行另一个清理过程,但是您如何建议在一个清理过程而不是两个清理过程中生成清理版本?(如果这有点多,很抱歉,如果有帮助的话,我可以单独问这个问题。)PS:如果您的工作簿中matplotlib输出太小,您可以在plt.figure(figsize=(15,15))
之前执行plt.imshow(dbg)
这太神奇了!非常感谢您的故障,感谢您花时间进行测试并提供如此优雅的解决方案。(需要等待24小时,直到我能为你的额外努力奖励你额外的分数。)@GeorgeProfenza:非常感谢你的额外奖励!