Come determinare gli endpoint di archi in graphicspath PathPoints e PathTypes array?
-
22-09-2019 - |
Domanda
Ho le seguenti PathPoints e PathTypes array (formato: 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
Ecco ciò che questo GraphicsPath appare fisicamente simile. I 2 Archi sono molto distinguibili:
So che questa matrice GraphicsPath.PathData è stato creato da comandi 2 AddArc. Facendo un passo attraverso il codice nel debugger, ho visto che i primi 4 valori PathData sono stati aggiunti dal primo comando AddArc, ed i restanti 6 punti sono stati aggiunti dal comando 2 ° AddArc.
Esaminando le prime PathPoints / array pathtype (senza prima sapere che era 2 comandi AddArc quindi vorrei sapere che ho 2 punti iniziale e finale), desidero determinare iniziare e punto finale di ciascun arco.
Ho provato diversi calcoli Bezier a 'ricreare' i punti della matrice, ma sono in perdita per determinare come determinare i punti iniziale e finale separati. Sembra che GDI + è combinare il punto di inizio / fine tra gli archi (sono lo stesso punto e gli archi sono collegati), e sto perdendo il fatto che un arco sta finendo e altro sta iniziando.
Tutte le idee?
Soluzione
Utilizzare la classe GraphicsPathIterator in combinazione con il metodo GraphicsPath.SetMarkers.
Ad esempio:
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)
Spero che questo aiuti!
Altri suggerimenti
Date un'occhiata al PathPointType Enum (System.Drawing.Drawing2D). valore Significato 0 Start (percorso) 1 linea 3 Bezier / Bezier3 7 PathType Mask Modalità 16 Dash 32 Path Marker 128 Chiudi sottotracciato
Questo mi è stato bugging molto anche! Avevo percorso creato oltre il mio controllo senza marcatori e non riuscivo a capire endpoint curva.
In questo caso ci si aspetta che la curva inizia alle [i + 1]
ma non lo è! Si scopre che GDI combina i punti di percorso probabilmente per rendere la matrice punti più breve. In questo caso i punti della curva sono: [0], [1], [2], [3]
Sembra che se PathPointType.Start
o PathPointType.Line
è seguita da PathPointType.Bezier
, poi si deve trattare il PathPontType.Start
o Path.PointType.Line
come primo punto della curva di Bézier, così nel tuo esempio che dovrebbe essere simile a questo:
-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
Così, quando si analizzano PathPoints
punto array punto, si controlla anche attuali e seguenti indici. La documentazione sul PatPointType potrebbe tornare utile. Nella maggior parte dei casi si può probabilmente ignorare i dati aggiuntivi memorizzati su bit diversi i primi tre (questi tre definire Start
, Line
e Bezier
). L'unica eccezione è CloseSubpath
ma è irrilevante se si considera il consiglio successivo.
E 'anche interessante notare che se si dispone di un percorso complesso che si compone di enorme numero di PathPoints
allora potrebbe essere utile per dividere il percorso in pezzi utilizzando GraphicsPathIterator . Questo semplifica l'intera procedura come PathPointType.CloseSubpath
può essere ignorato -. Sarà sempre l'ultimo punto del pezzo GraphicsPath
Un rapido sguardo in riflettore o qui potrebbe essere utile se si vuole capire meglio matrice PointTypes
.