Kartesisches Koordinatensystem zeichen
-
Mahlzeit allerseits,
ich versuche mich gerade darin eine Klasse zum zeichen eines Kooridnatensystems zu schreiben.
Aufgerufen wird das ganze Beispielsweiße so:
PointF[] points = { new PointF(-3, -3), new PointF(5, 5) }; coordinateSystem c = new coordinateSystem(pictureBox1, points); c.dotMatrix(); c.lineMatrix(); c.drawAxis(Color.DarkBlue, 1); pictureBox1.Image = c.showCoords();
Hinter 2 Problemen steige ich nicht ganz durch.
- Große Schwirigkeiten habe ich mit der Beschriftung.
Diese ist auf der Y-Achse vertauscht.
Ich habe den Startwert mal auf das Maximal gelegt und runterzählen lassen,
doch war das nur eine Verschlimm-besserung. - meistens werden da mehr Linien angezeigt, als es eigentlich soll.
Nicht tragisch, aber unnütz und dadurch platzverschwendung.
Der Code ist nicht wirklich komplex, daher denke ich, man steigt da augenblicklich durch.
PS: Cool wäre es, wenn ein C#-Crack den code einmal durchpflügen könnte.
Ich hab da bestimmt einige Fehler drinn oder sachen unperformant gelöst.using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Drawing; using System.Windows.Forms; namespace Grind { class coordinateSystem { private Bitmap _bitmap; private Graphics _graphics; public int _dimension = 20; private int _margin = 0; private PointF[] _points; private PointF _min = new PointF(); private PointF _max = new PointF(); private int _xmargin = 0; // Übergabe der pictureBox und der Kooridinaten public coordinateSystem(PictureBox pictureBox, PointF[] points) { this._bitmap = new Bitmap(pictureBox.Width, pictureBox.Height); this._graphics = Graphics.FromImage(this._bitmap); this._points = points; this._min = points[0]; // sonst ist 0 immer das minimal this._max = points[0]; foreach (var item in points) { this._min.X = Math.Min(this._min.X, item.X); this._min.Y = Math.Min(this._min.Y, item.Y); this._max.X = Math.Max(this._max.X, item.X); this._max.Y = Math.Max(this._max.Y, item.Y); } this._dimension = this.getDimension(); this._margin = (this._dimension / 2) + this._xmargin; this._graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; } // "aufrunden" passt vielleicht nicht ganz :D // 14.01f -> 15 | -14.01 -> -15 private int roundUp(float floatvalue) { int intval = (int)floatvalue; if (intval == 0) { return 0; } if (floatvalue / intval != 1) { return intval < 0 ? intval - 1 : intval + 1; } return intval; } // ruft nur die getSpace methode auf. // Das ganze mache ich nur, um an den kleinsten Abstand zu kommen. // Hier finde ich die richtigen Abstände für die Lines/dots raus private int getDimension() { int spaceX = this.getSpace(this._min.X, this._max.X); int spaceY = this.getSpace(this._min.Y, this._max.Y); return spaceX < spaceY ? spaceX : spaceY; } // s.o. für die "Auflösung" private int getSpace(float pmin, float pmax) { int min = roundUp(pmin); int max = roundUp(pmax); int dif = (max - min); MessageBox.Show("Max: " + max + " | Min: " + min + " -> " + dif); if ((this._bitmap.Width / dif) > this._dimension) { this._xmargin += this._bitmap.Width % dif; return (this._bitmap.Height - (this._bitmap.Width % dif)) / dif; } else { MessageBox.Show("X Dimension läge unter Grenzwert"); return 5; } } // zeichnet eine Punktmatrix public void dotMatrix(Color? dotColor = null, byte dotSize = 4) { // Parameterkontrolle SolidBrush brush = new SolidBrush(dotColor.HasValue ? dotColor.Value : Color.LightGray); int curY = this._margin; int curX = this._margin; int dotMid = dotSize / 2; while (curY < this._bitmap.Height) { curX = this._margin; while (curX < this._bitmap.Width) { this._graphics.FillEllipse(brush, curX-dotMid, curY-dotMid, dotSize, dotSize); curX = curX + this._dimension; } curY = curY + this._dimension; } } // zeichnet eine Strichmatrix public void lineMatrix(Color? lineColor = null, byte lineSize = 1) { // Parameterkontrolle Pen pen = new Pen(new SolidBrush(lineColor.HasValue ? lineColor.Value : Color.LightGray)); // zeichne x int curY = this._margin; while (curY < this._bitmap.Height) { this._graphics.DrawLine(pen, 0, curY, this._bitmap.Width, curY); curY = curY + this._dimension; } // zeichne y int curX = this._margin; while (curX < this._bitmap.Width) { this._graphics.DrawLine(pen, curX, 0, curX, this._bitmap.Height); curX = curX+ this._dimension; } } // zeichnet die Achsen + Beschriftung public void drawAxis(Color? lineColor = null, byte lineSize = 1) { // Parameterkontrolle Color col = lineColor.HasValue ? lineColor.Value : Color.Black; Pen pen = new Pen(new SolidBrush(col)); pen.Width = lineSize; Font drawFont = new Font("Microsoft Sans Serif", 9); SolidBrush drawBrush = new SolidBrush(col); float startX = this._min.X; float startY = this._max.Y - 1; int curX = this._margin; int curY = this._margin; // zeichne Abszisse - x int midY = curY + (int)(Math.Abs(this._min.Y) * this._dimension); this._graphics.DrawLine(pen, 0, midY, this._bitmap.Width, midY); // zeichne Ordinate - y int midX = curX + (int)(Math.Abs(this._min.X) * this._dimension); this._graphics.DrawLine(pen, midX, 0, midX, this._bitmap.Height); int lineWidth = 18 / 2; // X-Achsen Beschriftung while (curX < this._bitmap.Width) { this._graphics.DrawLine(pen, curX, midY - lineWidth, curX, midY + lineWidth); this._graphics.DrawString(startX.ToString(), drawFont, drawBrush, curX - 6, midY - 30); startX++; curX = curX + this._dimension; } // Y-Achsen Beschriftung while (curY < this._bitmap.Height) { this._graphics.DrawLine(pen, midX - lineWidth, curY, midX + lineWidth, curY); this._graphics.DrawString(startY.ToString(), drawFont, drawBrush, midX - 30, curY-10); startY--; curY = curY + this._dimension; } } public Bitmap showCoords() { return this._bitmap; } } }
Eine schöne Nacht wünsche ich!
qino
- Große Schwirigkeiten habe ich mit der Beschriftung.
-
Also ich weiss nicht wie es anderen geht die diesen Post lesen.
Aber dein Code ist mehr als unlesbar. Was mir direkt ins Auge faellt ist die fehlende Einhaltung der C# Code-Konventionen.
Wenn du ein Problem hast, dann Poste doch bitte nur die jeweiligen Problemstellen. Du kannst nicht einfach dein Code hinwerfen und verlangen das wir den ueberarbeiten.
-
Wenn du ein Problem hast, dann Poste doch bitte nur die jeweiligen Problemstellen. Du kannst nicht einfach dein Code hinwerfen und verlangen das wir den ueberarbeiten.
Die Gründe, warum ich die gesamte Klasse reingestellt habe, waren:
1. Andere können den Code praktisch einsetzen
2. Nur so eine insgesamte Beurteilung möglich ist.Eine überarbeitung verlangt habe ich niemals!
Wie dem auch sei ... ich werde mal versuchen alles übersichtlicher zu gestalten.
-
Falls das nicht nur der Übung dient, solltest Du Dir mal ZedGraph anschauen:
http://zedgraph.sourceforge.net/samples.html
-
Hallo µ,
das ist natürlich ne super Lösung.
Doch mache ich das ganze zu Übungszwecken.Hier einmal was ich rausbekomme:
http://s1.directupload.net/images/120312/z8pwlki2.png
Links das Fenster soll eigentlich die Werte von -2 bis 2 anzeichen (siehe obigen Textboxen), doch werden -2 bis 3 angezeigt.Ich finde weder ein Schema noch die Stelle an der es falsch läuft.
Meiner Meinung nach liegt es an den beiden Funktionen in Zeile 80-100.
Wissen tue es ich überhaupt nicht.Hoffentlich kann mir jemand helfen
Hab den Quelltext mal kommentiert;
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Drawing; using System.Windows.Forms; namespace Grind { class coordinateSystem { // Schriftgröße private int axisFontSize = 8; // Schriftgröße der Skalenbeschriftung // Canvas und Werte private PictureBox canvas; private int width, height; private PointF[] CoordPoints; private PointF minimalValues = new PointF(); private PointF maximalValues = new PointF(); private int xmargin = 0; // Image and Graphics private Bitmap image; private Graphics g; private int margin; // Schrittweite der Skala private int xScale; private int yScale; // Übergabe der pictureBox und der Kooridinaten public coordinateSystem(PictureBox pictureBox, PointF[] points) { // Setzen der allgemeint benötigten Werte this.width = pictureBox.Width; this.height = pictureBox.Height; this.image = new Bitmap(this.width, this.height); this.g = Graphics.FromImage(this.image); this.CoordPoints = points; // Alle Kooridnaten befinden sich nun in points //Hier werden die minimale und maximale X und Y - Werte gespeichert this.minimalValues = points[0]; this.maximalValues = points[0]; // Die kleinsten und größten X/Y-Werte werden nun ermittelt foreach (var item in points) { this.minimalValues.X = Math.Min(this.minimalValues.X, item.X); this.minimalValues.Y = Math.Min(this.minimalValues.Y, item.Y); this.maximalValues.X = Math.Max(this.maximalValues.X, item.X); this.maximalValues.Y = Math.Max(this.maximalValues.Y, item.Y); } xScale = this.getDimension(); yScale = xScale; // Die Abstände sind nun immer quadratisch } // Reset - übermalt den Canvas public void ClearBitmap() { g.FillRectangle(new SolidBrush(Color.White), 0, 0, this.width, this.height); // Clear background } public void AntiAlias() { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; } private int roundToExtreme(float floatvalue) { // 14.01 > 15 | -14.01 > -15 return floatvalue < 0 ? (int)Math.Floor(floatvalue) : (int)Math.Ceiling(floatvalue); } // Hier rechne ich die optimalen Abstände für die Skala aus private int getSpace(float pmin, float pmax) { int min = roundToExtreme (pmin); int max = roundToExtreme (pmax); // Habe ich Beispielsweiße auf der X-Achse ein Wertebereich von -2 bis 3 liegen, int dif = (max - min); // so rechne ich erst die Differenz dazwischen aus (6, da: -2, -1, 0, 1, 2, 3). // Die X-Skala muss also in 6 Werte unterteilt werden ... // ... und zurück bekomm ich den passenden Abstand der Linien in Pixel return (this.height - (this.width % dif)) / dif; // So jedenfalls die Theorie. } private int getDimension() { // A die Skalen Quadrate bilden sollen (wie ein Karopapier) // muss ich den kleineren Wert nehmen, der möglich ist. int xlabelspace = this.getSpace(this.minimalValues.X, this.maximalValues.X); int ylabelspace = this.getSpace(this.minimalValues.Y, this.maximalValues.Y); return xlabelspace < ylabelspace ? xlabelspace : ylabelspace; } /* * Uninteressant - zeichnet bei jeder X und Y-Linien Kreuzung ein Punkt hin public void dotMatrix(Color? dotColor = null, byte dotSize = 4) { // Parameterkontrolle SolidBrush brush = new SolidBrush(dotColor.HasValue ? dotColor.Value : Color.LightGray); int curY = this._margin; int curX = this._margin; int dotMid = dotSize / 2; while (curY < this.image.Height) { curX = this._margin; while (curX < this.image.Width) { this.g.FillEllipse(brush, curX-dotMid, curY-dotMid, dotSize, dotSize); curX = curX + this._dimension; } curY = curY + this._dimension; } } */ // Zeichnet die Linien in das Koordinatensystem, um Werte besser ablesen zu können public void lineMatrix(Color? lineColor = null, byte lineSize = 1) { // Parameterkontrolle Pen pen = new Pen(new SolidBrush(lineColor.HasValue ? lineColor.Value : Color.LightGray)); // zeichne x int curY = this.margin; while (curY < this.image.Height) { this.g.DrawLine(pen, 0, curY, this.image.Width, curY); curY = curY + this.yScale; } // zeichne y int curX = this.margin; while (curX < this.image.Width) { this.g.DrawLine(pen, curX, 0, curX, this.image.Height); curX = curX + this.xScale; } } // Und schließlich werden die Achsen gezeichnet public void drawAxis(Color? lineColor = null, byte lineSize = 1) { // Parameterkontrolle Color col = lineColor.HasValue ? lineColor.Value : Color.Black; Pen pen = new Pen(new SolidBrush(col)); pen.Width = lineSize; Font drawFont = new Font("Microsoft Sans Serif", 9); SolidBrush drawBrush = new SolidBrush(col); float startX = this.minimalValues.X; float startY = this.maximalValues.Y - 1; int curX = this.margin; int curY = this.margin; // zeichne Abszisse - x int midY = curY + (int)(Math.Abs(this.minimalValues.Y) * this.yScale); this.g.DrawLine(pen, 0, midY, this.image.Width, midY); // zeichne Ordinate - y int midX = curX + (int)(Math.Abs(this.minimalValues.X) * this.xScale); this.g.DrawLine(pen, midX, 0, midX, this.image.Height); int lineWidth = 18 / 2; // X-Achsen Beschriftung while (curX < this.image.Width) { this.g.DrawLine(pen, curX, midY - lineWidth, curX, midY + lineWidth); this.g.DrawString(startX.ToString(), drawFont, drawBrush, curX - 6, midY - 30); startX++; curX = curX + this.xScale; } // Y-Achsen Beschriftung while (curY < this.image.Height) { this.g.DrawLine(pen, midX - lineWidth, curY, midX + lineWidth, curY); this.g.DrawString(startY.ToString(), drawFont, drawBrush, midX - 30, curY - 10); startY--; curY = curY + this.yScale; } } public Bitmap showCoords() { return this.image; } } }
-
Was heißt hier, du weißt es überhaupt nicht? Hast du diesen komischen Code geschrieben? Wenn er von -2 bis 2 zeichnen soll und von -2 bis 3 zeichnet, dann stimmt deine Berechnung nicht und musst sie minimal anpassen. Das wirst du selber am schnellsten finden können. Ich werd mir jedenfalls nicht die Mühe machen, mich da reinzudenken.