Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.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
Svg 确定复合Bezier形状中实体/孔的算法_Svg_Graphics_Bezier - Fatal编程技术网

Svg 确定复合Bezier形状中实体/孔的算法

Svg 确定复合Bezier形状中实体/孔的算法,svg,graphics,bezier,Svg,Graphics,Bezier,我正在使用该库渲染一个复合Bezier形状,但该库没有告诉我缠绕方向,即复合形状中每个子路径的坚固度/孔度 假设所有路径都不相交,那么给定子路径的贝塞尔点,什么数学算法可以告诉我哪个子路径是实心的,哪个是孔 我可以计算每个子路径的面积,按面积排序,以及实体和孔之间的替换,但这仅在路径形成子集链时有效,因此无法绘制此复合形状 该算法是SVG定义中描述的算法。从一个点开始,画一条无限远的任意光线(好吧,一条在你需要考虑的区域外结束的线),然后用描述的两种方法之一非零和偶数计数路径交叉 强>确定交叉计

我正在使用该库渲染一个复合Bezier形状,但该库没有告诉我缠绕方向,即复合形状中每个子路径的坚固度/孔度

假设所有路径都不相交,那么给定子路径的贝塞尔点,什么数学算法可以告诉我哪个子路径是实心的,哪个是孔

我可以计算每个子路径的面积,按面积排序,以及实体和孔之间的替换,但这仅在路径形成子集链时有效,因此无法绘制此复合形状


该算法是SVG定义中描述的算法。从一个点开始,画一条无限远的任意光线(好吧,一条在你需要考虑的区域外结束的线),然后用描述的两种方法之一非零和偶数计数路径交叉

<>强>确定交叉计数:< /强>不要尝试在一个路径中对子路径进行此操作,而是单独考虑每个路径段。多数人的计数为零,这很好。例如,具有一个用于计算三次贝塞尔曲线和直线之间交点的函数。看看源代码,它有很好的文档记录。(尽管作者对版权持何种立场尚不清楚。)

确定路径方向:只需确定线段的起点和终点是光线的左侧还是右侧

  • 如果两者在同一侧,则从左到右和从右到左各数一次。(非零规则:0,偶数-奇数规则:+2)
  • 如果起点为左,终点为右,则从左到右计算一次(+1),或者,对于具有三个交叉点的立方贝塞尔,从左到右计算两次,从右到左计算一次。(非零规则:+1,偶数规则:+3)
  • 如果起点为右,终点为左,则对于一个交叉点(非零规则:-1,偶数规则:+1)或三个交叉点(非零规则:-1,偶数规则:+3)
  • 如果光线仅在某个分段点穿过子路径,则必须避免两次计算交叉。避免错误的最佳方法是将两个线段视为一个线段进行处理,从添加的交叉点计数中减去一个线段,并仅确定整个起点/终点的边

最后,对于非零,如果最终计数总和不为零,则一个点位于内部。对于偶数奇数,如果最终计数总数为奇数,则它位于内部。

该算法是SVG定义中描述的算法。从一个点开始,画一条无限远的任意光线(好吧,一条在你需要考虑的区域外结束的线),然后用描述的两种方法之一非零和偶数计数路径交叉

<>强>确定交叉计数:< /强>不要尝试在一个路径中对子路径进行此操作,而是单独考虑每个路径段。多数人的计数为零,这很好。例如,具有一个用于计算三次贝塞尔曲线和直线之间交点的函数。看看源代码,它有很好的文档记录。(尽管作者对版权持何种立场尚不清楚。)

确定路径方向:只需确定线段的起点和终点是光线的左侧还是右侧

  • 如果两者在同一侧,则从左到右和从右到左各数一次。(非零规则:0,偶数-奇数规则:+2)
  • 如果起点为左,终点为右,则从左到右计算一次(+1),或者,对于具有三个交叉点的立方贝塞尔,从左到右计算两次,从右到左计算一次。(非零规则:+1,偶数规则:+3)
  • 如果起点为右,终点为左,则对于一个交叉点(非零规则:-1,偶数规则:+1)或三个交叉点(非零规则:-1,偶数规则:+3)
  • 如果光线仅在某个分段点穿过子路径,则必须避免两次计算交叉。避免错误的最佳方法是将两个线段视为一个线段进行处理,从添加的交叉点计数中减去一个线段,并仅确定整个起点/终点的边

最后,对于非零,如果最终计数总和不为零,则一个点位于内部。对于偶数奇数,如果最终计数总数为奇数,则它位于内部。

技术说明:“bezier多边形”不存在。多边形是由直线段组成的路径,而Bezier是曲线。这可能是吹毛求疵,但你问的是一个技术主题,所以正确的术语会有很大的不同。至于“有算法吗?”答案取决于你的库。有些库将顺时针/逆时针视为填充/剪切,有些库遵循“相反方向表示相反填充规则”。然而,没有一种算法可以告诉你什么是完全基于路径的填充/剪切,因为这不是路径的属性。@Mike'Pomax'Kamermans捕捉得很好,谢谢。还添加了所有路径都不相交的假设,因此我认为现在应该很好地定义这一点。nanovg将CCW视为填充,CW视为剪切。您可以指定svg填充规则吗?如果是这样的话,把它设为偶数/奇数,这样你就可以不用做任何工作了。如果没有,请在nanosvg生成您的文件之后,使用第二个UTL(甚至字符串替换)设置它。为什么不将SVG添加为代码,以便我们可以看到您真正得到了什么(遗憾的是,so/SE不支持SVG和PCX图像)。技术说明:“bezier多边形”不存在。多边形是由直线段组成的路径,而Bezier是曲线。这可能是吹毛求疵,但你问的是一个技术主题,所以正确的术语会有很大的不同。至于“有算法吗?”答案取决于你的库。有些库将顺时针/逆时针视为填充/剪切,有些库遵循“相反方向表示相反填充规则”。然而,没有一种算法可以告诉你什么是b