如何在GraphicsPath PathPoints和PathTypes数组中确定Arcs的端点?

时间:2009-11-24 15:39:27

标签: gdi+ bezier graphicspath

我有以下PathPoints和PathTypes数组(格式:X,Y,Type):

-177.477900,  11021.670000, 1
-614.447200,  11091.820000, 3
-1039.798000, 10842.280000, 3
-1191.761000, 10426.620000, 3
-1591.569000, 10493.590000, 3
-1969.963000, 10223.770000, 3
-2036.929000, 9823.960000,  3
-2055.820000, 9711.180000,  3
-2048.098000, 9595.546000,  3
-2014.380000, 9486.278000,  3

这是GraphicsPath的实际外观。 2个弧是非常明显的: alt text

我知道这个GraphicsPath.PathData数组是由2个AddArc命令创建的。单步执行调试器中的代码,我看到第一个AddArc命令添加了前4个PathData值,第二个AddArc命令添加了剩下的6个点。

通过检查原始路径点/路径类型数组(之前不知道它是2个AddArc命令,所以我知道我有2个起点和终点),我想确定每个弧的起点和终点。 / p>

我已经尝试了几次Bezier计算来“重新创建”数组中的点,但我们不知道如何确定单独的起点和终点。似乎GDI +正在组合弧之间的起点/终点(它们是相同的点并且弧是连接的),并且我正在失去一个弧正在结束而另一个正在开始的事实。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

将GraphicsPathIterator类与GraphicsPath.SetMarkers方法结合使用。

例如:

dim gp as new GraphicsPath
gp.AddArc(-50, 0, 100, 50, 270, 90) 'Arc1
gp.SetMarkers()
gp.AddArc(0, 25, 100, 50, 270, 90) 'Arc2
Dim iterator as New GraphicsPathIterator(gp)
Dim i as Integer = 0
Dim MyPts(3) As PointF
Dim temp as New GraphicsPath
Do until i > 2
   iterator.NextMarker(temp)
   MyPts(i) = temp.PathPoints(0)
   MyPts(i + 1) = temp.GetLastPoint()
  i += 2
Loop

'Free system resources...
iterator.Dispose()

temp.Dispose()

Arc1 -> start: MyPts(0); end: MyPts(1)
Arc2 -> start: MyPts(2); end: MyPts(3)

希望这有帮助!

答案 1 :(得分:0)

查看PathPointType枚举(System.Drawing.Drawing2D)。 价值意义   0开始(路径)   1行   3 Bezier / Bezier3   7 PathType Mask  16破折号模式  32路径标记 128关闭子路径

答案 2 :(得分:0)

这个也让我烦恼不已!我在没有标记的情况下创建了无法控制的路径,无法找出曲线端点。

在这种情况下,您希望曲线从[i + 1]开始,但事实并非如此!事实证明,GDI结合路径点可能会使点数组更短。在这种情况下,曲线点为:[0], [1], [2], [3]

如果PathPointType.StartPathPointType.Line后跟PathPointType.Bezier,那么您必须将PathPontType.StartPath.PointType.Line视为您的第一点贝塞尔曲线,所以在你的例子中它应该是这样的:

 -177.47, 11021.67, 1  // Draw line to this point AND use it as a Bezier start!
 -614.44, 11091.82, 3  // Second Bezier point
-1039.79, 10842.28, 3  // Third Bezier point
-1191.76, 10426.62, 3  // Fourth Bezier point AND first point of the next Bezier!
-1591.56, 10493.59, 3  // Second Bezier point
-1969.96, 10223.77, 3  // Third Bezier point
-2036.92,  9823.96, 3  // Fourth Bezier point AND first point of the next Bezier!
-2055.82,  9711.18, 3  // Second Bezier point
-2048.09,  9595.54, 3  // Third Bezier point
-2014.38,  9486.27, 3  // Fourth Bezier point

因此,在逐点分析PathPoints数组时,您还必须检查当前以下的索引。 PatPointType上的文档可能会派上用场。在大多数情况下,您可能会忽略存储在前三位以外的位上的其他数据(这三项定义StartLineBezier)。唯一的例外是CloseSubpath,但如果您考虑下一个建议则无关紧要。

值得注意的是,如果你有一个由大量PathPoints组成的复杂路径,那么使用GraphicsPathIterator将路径分成块可能很方便。这简化了整个过程,因为PathPointType.CloseSubpath可以忽略 - 它始终是GraphicsPath块的最后一点。

如果您想更好地理解PointTypes数组,快速查看Reflector或here可能会有所帮助。