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.

    1. 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.
    2. 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



  • 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.


Anmelden zum Antworten