Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将SVG多段线转换为quickdraw stroke-3 numpy格式?_Python_Numpy_Svg - Fatal编程技术网

Python 如何将SVG多段线转换为quickdraw stroke-3 numpy格式?

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

我想将包含多段线的基本SVG文件转换为(和)使用的stroke-3格式

据我所知,stroke-3格式中的每个多段线点应为:

  • 存储为
    [delta\u x,delta\u y,pen\u up]
    ,其中
  • delta_x
    delta_y
    表示相对于 前一点和
  • pen\u up
    是一个位,当笔向上时为1 (例如,
    move_to
    operation a-la-turtle graphics)或当笔处于打开状态时为0 向下(例如,
    line\u至
    a-la操作)
我曾尝试编写函数并转换SVG,但在渲染stroke-3格式的测试时,我得到了一行额外的代码

我的输入SVG如下所示:


您的转换是正确的,错误在渲染代码中。它必须是
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:非常感谢你的额外奖励!