2009-11-24 39 views
1

我有以下PathPoints和PathTypes陣列(格式:X,Y,類型):如何確定GraphicsPath PathPoints和PathTypes數組中的弧的端點?

-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 http://i45.tinypic.com/2agj1gl.jpg

我知道這個GraphicsPath.PathData數組是由2個AddArc命令創建的。在調試器中遍歷代碼,我看到前4個PathData值由第一個AddArc命令添加,其餘6個點由第二個AddArc命令添加。

通過檢查原始pathpoints/pathtype數組(先前不知道它是2 AddArc命令,所以我知道我有2個開始和結束點),我想確定每個弧的開始和結束點。

我已經嘗試了幾次貝塞爾計算來'重新創建'數組中的點,但是在確定如何確定單獨的開始點和結束點時處於不知所措的狀態。看起來,GDI +正在結合弧線之間的起點/終點(它們是相同的點和弧線連接),並且我失去了一個弧線正在結束而另一弧線正在起跑的事實。

任何想法?

回答

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) 

希望這有助於!

+0

只要實際上可以在創建路徑時添加標記,這可能會有所幫助。但這並不總是可能的。看看[這個答案](http://stackoverflow.com/questions/1790862/how-to-determine-endpoints-of-arcs-in-graphicspath-pathpoints-and-pathtypes-arra/17339215#17339215)更好地理解如何在內部構造'GraphicsPath'。 – SiliconMind 2013-06-27 09:24:41

0

看看PathPointType Enum(System.Drawing.Drawing2D)。 值含義0 啓動(路徑) 第1行 3貝塞爾/ Bezier3 7 PathType面膜 16短跑模式 32路徑標記 128關閉子路徑

+0

這就是我上面列表中的第三個數字(PathPointType)。我遇到的問題是上面的數組中有2個Bezier/Bezier3(PathPointType = 3)曲線。我需要弄清楚如何確定在哪裏分割數組。我知道我以編程方式添加弧,'-1191.761000,10426.620000,3'值是第一個弧的終點和第二個弧的起點。但是,我需要弄清楚如何以編程方式確定。 – 2009-12-04 14:12:16

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