graphics und transform

20/03/2008 - 15:41 von Sven Becker | Report spam
Hallo NG,

für ein Projekt, welches XY-Diagramme ausgeben soll,
habe ich mit dem Transform-Befehl mein Koordinatensystem so umgestellt,
daß der Punkt 0,0 unten rechts ist und die positive Zàhlrichtung der Y-Achse
nach oben geht (wie man es eben gewohnt ist). Für die Ausgabe von Linien,
Punkten usw. funktioniert das bestens.

Dummerweise werden aber auch die Textausgaben mit transformiert, will heißen,
der Text ist nach oben gespiegelt.

Unter dem alten GDI war das kein Problem (Stichwort MapMode LO_METRIC).
Sollte es da unter GDI+ wirklich keine vernünftige Lösung geben?

Danke für jeden Tipp,
Sven
 

Lesen sie die antworten

#1 Karsten Sosna
21/03/2008 - 08:25 | Warnen spam
für ein Projekt, welches XY-Diagramme ausgeben soll,
habe ich mit dem Transform-Befehl mein Koordinatensystem so umgestellt,
daß der Punkt 0,0 unten rechts ist und die positive Zàhlrichtung der
Y-Achse
nach oben geht (wie man es eben gewohnt ist). Für die Ausgabe von Linien,
Punkten usw. funktioniert das bestens.

Dummerweise werden aber auch die Textausgaben mit transformiert, will
heißen,
der Text ist nach oben gespiegelt.

Unter dem alten GDI war das kein Problem (Stichwort MapMode LO_METRIC).
Sollte es da unter GDI+ wirklich keine vernünftige Lösung geben?



Hallo Sven,
AFAIK spielt es für GDI+ keine Rolle was ausgegeben wird. Wenn Du also so
skalierst das die Ordinate(Y-Achse) in der Richtung umgekehrt wird, wird
alles gespiegelt. Eine Möglichkeit besteht darin mit einem GraphicsContainer
zu arbeiten:
\\\
Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
'MyBase.OnPaint(e)
e.Graphics.TranslateTransform(0, Me.ClientSize.Height)
e.Graphics.ScaleTransform(1, -1)
For i As Integer = 0 To 10
e.Graphics.DrawLine(Pens.Black, 0, i * 15, Me.ClientSize.Width, i *
15)
Dim g_cont As Drawing2D.GraphicsContainer =
e.Graphics.BeginContainer
e.Graphics.ScaleTransform(1, -1)
e.Graphics.DrawString(i.ToString, Me.Font, Brushes.Blue, 0, -i * 15)
'Achte auf das Vorzeichen
e.Graphics.EndContainer(g_cont)
Next
End Sub
///

Ein GraphicsContainer speichert den Zustand des Graphics-Objekt und zwar
nicht nur die Transfomationsmatrix sondern auch solche Einstellungen wie
PageScale, PageUnit etc. . Natürlich würde es auch ausreichen einfach die
Transformationsmatrix zu sichern.
\\\
Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
'MyBase.OnPaint(e)
e.Graphics.TranslateTransform(0, Me.ClientSize.Height)
e.Graphics.ScaleTransform(1, -1)
For i As Integer = 0 To 10
e.Graphics.DrawLine(Pens.Black, 0, i * 15, Me.ClientSize.Width, i *
15)
Using m As Drawing2D.Matrix = e.Graphics.Transform
e.Graphics.ScaleTransform(1, -1)
e.Graphics.DrawString(i.ToString, Me.Font, Brushes.Blue, 0, -i *
15) 'Achte auf das Vorzeichen
e.Graphics.Transform = m
End Using
Next
End Sub
///

In beiden Fàllen muss ber die Y-Koordinate des Textes negiert werden. Wenn
es keine trifftigen Grund gibt würde ich auf die Skalierung verzichten und
nur die Translation einsetzen. Letzendlich brauchst Du dann nur _alle_
Y-Koordinaten negieren und erhàltst das gleiche Ergebnis.
\\\
Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
'MyBase.OnPaint(e)
e.Graphics.TranslateTransform(0, Me.ClientSize.Height)
For i As Integer = 0 To 10
e.Graphics.DrawLine(Pens.Black, 0, -i * 15, Me.ClientSize.Width, -i
* 15)
e.Graphics.DrawString(i.ToString, Me.Font, Brushes.Blue, 0, -i * 15)
Next
End Sub
///

Abschließend. Bedenke die Skalierung wirkt sich auch auf andere Formen aus,
hier ein GraphicsPath. Das Mànnchen wurde so erstellt, dass es unter der
"Normalskalierung" steht(grün).
\\\
Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
'MyBase.OnPaint(e)
Using gp As Drawing2D.GraphicsPath = CreateFigure()
e.Graphics.DrawPath(Pens.Green, gp)
End Using

e.Graphics.TranslateTransform(0, Me.ClientSize.Height)
e.Graphics.ScaleTransform(1, -1)
Using gp As Drawing2D.GraphicsPath = CreateFigure()
e.Graphics.DrawPath(Pens.Red, gp)
End Using
End Sub

Private Function CreateFigure() As Drawing2D.GraphicsPath
Dim GP As New Drawing2D.GraphicsPath
GP.AddArc(New RectangleF(-6.25, 81.25, 12.5, 12.5), -68.1295, 316.259)
GP.AddLine(-2.5, 80, -2.5, 80)
GP.AddArc(New RectangleF(-17.5, 67.5, 10, 10), 103.2917, 62.8736)
GP.AddArc(New RectangleF(-22.5, 50, 5, 5), 166.1653, 193.8347)
GP.AddLine(-12.5, 70, -10, 47.5)
GP.AddArc(New RectangleF(-15, 0, 7.5, 5), 177.1671, 177.4198)
GP.AddLine(0, 37.5, 0, 37.5)
GP.AddArc(New RectangleF(7.5, 0, 7.5, 5), -174.5868, 177.4198)
GP.AddLine(10, 47.5, 12.5, 70)
GP.AddArc(New RectangleF(17.5, 50, 5, 5), 180, 193.8347)
GP.AddArc(New RectangleF(7.5, 67.5, 10, 10), 13.8347, 62.8736)
GP.AddLine(2.5, 80, 2.5, 80)
GP.CloseAllFigures()
Using m As New Drawing2D.Matrix
m.Translate(30, 100)
m.Scale(1, -1)
GP.Transform(m)
End Using
Return GP
End Function
///
Gruß Scotty

Ähnliche fragen