如何将 g 代码弧转换为 SVG 贝塞尔弧
How to convert g-code arcs to SVG bezier arcs
我正在尝试找出一种将 g 代码解释为 SVG 图像的方法。我可以想象轻松地使用坐标来绘制直线,但我正在努力处理弧线。我不知道如何将 I J 系统解释为 SVG 中的弧线。
(ORIGIN=BOTTOM LEFT)
(METRIC)
G71
(RELATIVE)
G91
M16
(PART 1)
G00X-74.7Y585.5
M15
G01X-1.0Y0.0
G02X-735.2Y736.2I0.4J735.6
G01X10.0Y0.0
G01X0.0Y75.0
G01X501.2Y0.0
G01X0.0Y-75.0
G01X10.0Y0.0
G03X215.0Y-215.0I214.4J-0.6
G01X0.0Y-10.0
G01X75.0Y0.0
G01X0.0Y-501.2
G01X-75.0Y0.0
G01X0.0Y-10.0
M16
(PARK)
这是我对上面代码的理解,它是相对的,所以我将从 -74,585 开始,然后移动 -1,0,然后开始一个弧,该弧结束 -735.2,736.2 远离弧的起点。圆弧中心将基于 I 和 J 信息。因为这是相对的,所以 I 和 J 是相对于圆弧的起点吗?
对于圆弧的中心,这将如何转换为 svg 圆弧?我认为对于 SVG 贝塞尔曲线 (Q),控制点位于曲线的 'outside' 上,而对于 g 代码,中心位于内部?
我可以解析我拥有的数据并生成以下 SVG:
<svg viewBox="-820 -35 4283 1441">
<path class="path" d="M-74,585 -75,585" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-75,585 Q -810 1321 -810 1321" style="fill:none;stroke:black;stroke-width:5"></path>
<path class="path" d="M-810 1321 -800,1321" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-800,1321 -800,1396" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-800,1396 -299,1396" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-299,1396 -299,1321" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-299,1321 -289,1321" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-289,1321 Q -74 1106 -74 1106 " style="fill:none;stroke:black;stroke-width:5"></path>
<path class="path" d="M-74 1106 -74,1096" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-74,1096 1,1096" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M1,1096 1,595" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M1,595 -74,595" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-74,595 -74,585" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-74,585 -74,585" style="stroke:red;stroke-width:10"></path>
</svg>
我没有添加用于生成此脚本的脚本(用 PHP 编写),因为它很冗长并且会从数据库中提取数据,因此不会真正有帮助。方向是错误的,但我可以通过对整个 SVG 进行转换来解决这个问题。负责圆弧的线中有 Q,它是控制点值,我无法根据 g 代码中点的 I J 值在数学上计算出我的生命。任何帮助或建议将不胜感激。
您不能将 G02
或 G03
命令描述的圆弧转换为 Q
命令描述的忠实二次贝塞尔曲线 - 它会在最好是一个近似值。除此之外真的没有必要。 SVG 路径命令包括描述椭圆弧的 A
命令。 Its syntax is:
A rx ry x-axis-rotation large-arc-flag sweep-flag x y (absolute notation)
a rx ry x-axis-rotation large-arc-flag sweep-flag x y (relative notation)
这比您需要的要复杂得多,因为 in 也可以描述旋转的椭圆弧。在您的情况下,描述椭圆半径的前两个参数相同,第三个参数为 0,因为旋转的圆不会改变。
首先你需要做的是从起点到旋转中心的距离确定圆的半径。中心坐标是相对于那个起点的,所以你可以简单地写
$r = hypot($I, $J)
需要大圆弧标志和扫描标志来区分绘制具有一定半径的圆弧的四种可能解决方案。大弧标志描述弧覆盖是否超过 180 度。如果我理解数控机械的限制权利,这是不可能的。因此,该值可能应该是 0
(false) - 如果我错了请纠正我。扫描标志描述弧是顺时针还是逆时针。因此,对于 G02
命令,它的值为 1
(真),对于 G03
命令,它的值为 0
(假)。
如果使用相对 a
命令,最终的 x 和 y 坐标与 X
和 Y
值完全相同。
一起,G-code命令
G02X-735.2Y736.2I0.4J735.6
可以写成路径命令d
属性
d="M-75,585 a 735.6001 735.6001 0 0 1 -735.2,736.2"
最后一点,如果你使用l
命令,你也可以用相对坐标写直线。 G01X-1.0Y0.0
可以写成
d="M-74,585 -75,585"
和
d="M-74,585 l -1,0"
根据您的要求,您甚至可以将多行合并到一个 <path>
元素中,如下所示:
d="M-74,585 l -1,0 m 0,0 a 735.6001 735.6001 0 0 1 -735.2,736.2 m 0,0 l 10,0 ..."
with m 0,0
表示新行应该从前一行结束的地方开始。或者你也可以画一条连续的多段线:
d="M-74,585 l -1,0 a 735.6001 735.6001 0 0 1 -735.2,736.2 l 10,0 ..."
我正在尝试找出一种将 g 代码解释为 SVG 图像的方法。我可以想象轻松地使用坐标来绘制直线,但我正在努力处理弧线。我不知道如何将 I J 系统解释为 SVG 中的弧线。
(ORIGIN=BOTTOM LEFT)
(METRIC)
G71
(RELATIVE)
G91
M16
(PART 1)
G00X-74.7Y585.5
M15
G01X-1.0Y0.0
G02X-735.2Y736.2I0.4J735.6
G01X10.0Y0.0
G01X0.0Y75.0
G01X501.2Y0.0
G01X0.0Y-75.0
G01X10.0Y0.0
G03X215.0Y-215.0I214.4J-0.6
G01X0.0Y-10.0
G01X75.0Y0.0
G01X0.0Y-501.2
G01X-75.0Y0.0
G01X0.0Y-10.0
M16
(PARK)
这是我对上面代码的理解,它是相对的,所以我将从 -74,585 开始,然后移动 -1,0,然后开始一个弧,该弧结束 -735.2,736.2 远离弧的起点。圆弧中心将基于 I 和 J 信息。因为这是相对的,所以 I 和 J 是相对于圆弧的起点吗?
对于圆弧的中心,这将如何转换为 svg 圆弧?我认为对于 SVG 贝塞尔曲线 (Q),控制点位于曲线的 'outside' 上,而对于 g 代码,中心位于内部?
我可以解析我拥有的数据并生成以下 SVG:
<svg viewBox="-820 -35 4283 1441">
<path class="path" d="M-74,585 -75,585" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-75,585 Q -810 1321 -810 1321" style="fill:none;stroke:black;stroke-width:5"></path>
<path class="path" d="M-810 1321 -800,1321" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-800,1321 -800,1396" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-800,1396 -299,1396" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-299,1396 -299,1321" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-299,1321 -289,1321" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-289,1321 Q -74 1106 -74 1106 " style="fill:none;stroke:black;stroke-width:5"></path>
<path class="path" d="M-74 1106 -74,1096" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-74,1096 1,1096" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M1,1096 1,595" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M1,595 -74,595" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-74,595 -74,585" style="stroke:black;stroke-width:5"></path>
<path class="path" d="M-74,585 -74,585" style="stroke:red;stroke-width:10"></path>
</svg>
我没有添加用于生成此脚本的脚本(用 PHP 编写),因为它很冗长并且会从数据库中提取数据,因此不会真正有帮助。方向是错误的,但我可以通过对整个 SVG 进行转换来解决这个问题。负责圆弧的线中有 Q,它是控制点值,我无法根据 g 代码中点的 I J 值在数学上计算出我的生命。任何帮助或建议将不胜感激。
您不能将 G02
或 G03
命令描述的圆弧转换为 Q
命令描述的忠实二次贝塞尔曲线 - 它会在最好是一个近似值。除此之外真的没有必要。 SVG 路径命令包括描述椭圆弧的 A
命令。 Its syntax is:
A rx ry x-axis-rotation large-arc-flag sweep-flag x y (absolute notation)
a rx ry x-axis-rotation large-arc-flag sweep-flag x y (relative notation)
这比您需要的要复杂得多,因为 in 也可以描述旋转的椭圆弧。在您的情况下,描述椭圆半径的前两个参数相同,第三个参数为 0,因为旋转的圆不会改变。
首先你需要做的是从起点到旋转中心的距离确定圆的半径。中心坐标是相对于那个起点的,所以你可以简单地写
$r = hypot($I, $J)
需要大圆弧标志和扫描标志来区分绘制具有一定半径的圆弧的四种可能解决方案。大弧标志描述弧覆盖是否超过 180 度。如果我理解数控机械的限制权利,这是不可能的。因此,该值可能应该是 0
(false) - 如果我错了请纠正我。扫描标志描述弧是顺时针还是逆时针。因此,对于 G02
命令,它的值为 1
(真),对于 G03
命令,它的值为 0
(假)。
如果使用相对 a
命令,最终的 x 和 y 坐标与 X
和 Y
值完全相同。
一起,G-code命令
G02X-735.2Y736.2I0.4J735.6
可以写成路径命令d
属性
d="M-75,585 a 735.6001 735.6001 0 0 1 -735.2,736.2"
最后一点,如果你使用l
命令,你也可以用相对坐标写直线。 G01X-1.0Y0.0
可以写成
d="M-74,585 -75,585"
和
d="M-74,585 l -1,0"
根据您的要求,您甚至可以将多行合并到一个 <path>
元素中,如下所示:
d="M-74,585 l -1,0 m 0,0 a 735.6001 735.6001 0 0 1 -735.2,736.2 m 0,0 l 10,0 ..."
with m 0,0
表示新行应该从前一行结束的地方开始。或者你也可以画一条连续的多段线:
d="M-74,585 l -1,0 a 735.6001 735.6001 0 0 1 -735.2,736.2 l 10,0 ..."