Koordinatensystem Sinnvoll einteilen
-
Hallo Community,
ich habe mal wieder eine Frage, die sich weniger auf die Ausführung sondern eher auf das wie wäre es Sinnvoll zu lösen hinausgeht.
In meinem Projekt messe ich verschiedene Frequenzspektrums z.B. von FM 88MHz bis 108MHz oder DAB von 174MHz bis 239MHz und 1468MHz bis 1490MHz. Da diese Frequenzspektums unterschiedlich groß sind, messe ich mit einem vom Benutzer einzustellenden Messschritt z.B. 1Mhz. Aus einer vom Benutzer zu bestimmenden Anzahl Messungen z.B. 20Mal, errechne ich mir dann die Standardabweichung, Varianz...
Soweit funktioniert das auch und ich kann auch für meine Messungen (mit Beispielwerten in dB/µV) Messungen in meine entsprechende Vectoren schieben.
Aus diesen Messwerten zeichne ich mir verschiedene Bitmaps um das ganze grafisch darzustellen.
Nun kommt mein Problem: Da ich Werte von 0,513MHz bis 2,48GHz habe muß ich je nach Messkomponente eine andere Skalierung wählen, die ich bis jetzt immer Starr für die jeweilige Komponente vergebe. Da ich aber die Messbereiche auf die Zukunft hin gesehen nicht Starr festlegen möchte sollte ich eine dynamische Anpassung an den gegebenen Messwert einbauen.
Wenn ich aber immer einen festen Wert für das Koordinatenkreuz eingebe(in X +10MHz/-10MHz), dann könnt ihr euch vorstellen, dass bei 2,48GHz kaum was zu erkennen ist, während bei 0,513MHz eine Skala rauskommt, die jenseits von gut und böse ist.
Nun ist das gerade so, dass auf meinem Bitmap auch ein Gitternetz gezeichnet wird, welches sich eben auch daran orientiert wie groß der Abstand von X und Y ist. Wenn ich nun einen anderen Wert eingebe, kann es sein, dass meine Y - Achse plötzlich in der Mitte meines Bitmaps gezeichnet wird, da der Y_Abstand eben auf dem Bitmap durch die variable Skalierung nur ein mal vorkommt.
Auf der einen Seite habe ich mir überlegt ob ich die Frequenz nicht einfach in feste Schritte einteile und eine Art Zoom Funktion einbaue (z.B. Durch die linke und rechte Maustaste Vertikale Marker setzen und den Bereich dazwischen zoomen, wenn das auf einem Bitmap geht? - muß ich erst nachlesen). Nur müßte ich dann auch auf den entsprechenden Bereich springen und bei DAB bekomme ich das kaum auf ein Bild, da das Spektrum so groß ist.
Und wie ich das dann jemals sinnvoll ausdrucken soll, wenn nicht gezoomt wird, weiß ich dann auch nicht.
Vielleicht hat mir jemand einen Tipp wie man das angehen könnte.
Zum Verständins ich habe mir 4 Funktionen geschrieben, die mir die Bildschirmkoordinaten in Weltkoordinaten und wieder zurück umrechnen.
Mit der Funktion "erzeugeImage" wird das Koordinatensystem wie bereits erwähnt Starr vergeben und durch die Funktion "zeichneKoordinaten" in der Bitmap Grafik eingezeichnet. Ebenso werden in "erzeugeImage" die Messwerte reingezeichnet.
Ich habe auf meinem Formular eine TImage Komponente platziert in der die jeweilige Grafik danach angezeigt werden kann.
Hier der Code:
void CDiagramm::erzeugeImage(int x_width, int y_height) { // Variablen Koordinatensystem anlegen double x0 = -30, y0 = -10, x1 = 900, y1 = 110; // Variablen X und Y anlegen int X = 0; int Y = 0; // Variablen Linienabstände double x_abst = 0; double y_abst = 0; // BEISPIEL NUR FÜR DAB if(Messung->getFertig("DAB") == 1) { // Neue Bitmap Grafik erzeugen Graphics::TBitmap *bmp = new Graphics::TBitmap; // Größe der Grafik bestimmen bmp->Width = x_width; bmp->Height = y_height; // Weltkoordinatensystem bestimmen (x0 bis x1 / y0 bis y1) x0 = 100; y0 = -10; x1 = 1500; y1 = 110; // Linienabstände bestimmen x_abst = 50; y_abst = 10; // Koordinatensystem zeichnen zeichneKoordinaten(bmp, x0, y0, x1, y1, x_abst, y_abst, Frequenzeinstellung.DAB.Eigenschaft.getMasseinheit()); // Linienfarbe rot wählen bmp->Canvas->Pen->Color = clRed; // Schleife bis DAB_Container 0 Ende for(unsigned int i=0; i<Messung->DAB_Container0.size(); i++) { // X Position bestimmen X = x_Bildschirm(Messung->DAB_Container0.at(i).getMAX(),x0,x1,bmp->Width); // Y Positon bestimmen Y = y_Bildschirm(100,y0,y1,bmp->Height); // Auf Punkt setzen bmp->Canvas->MoveTo(X,Y); // Y Position 0 bestimmen Y = y_Bildschirm(0,y0,y1,bmp->Height); // Linie zeichnen bmp->Canvas->LineTo(X,Y); } // Schleife bis DAB_Container 1 Ende for(unsigned int i=0; i<Messung->DAB_Container1.size(); i++) { // X Position bestimmen X = x_Bildschirm(Messung->DAB_Container1.at(i).getMAX(),x0,x1,bmp->Width); // Y Positon bestimmen Y = y_Bildschirm(100,y0,y1,bmp->Height); // Auf Punkt setzen bmp->Canvas->MoveTo(X,Y); // Y Position 0 bestimmen Y = y_Bildschirm(0,y0,y1,bmp->Height); // Linie zeichnen bmp->Canvas->LineTo(X,Y); } bmpVector.push_back(bmp); } }void CDiagramm::zeichneKoordinaten(Graphics::TBitmap* Image1, double x0, double y0, double x1, double y1, double x_abst, double y_abst, char Masseinheit[]) { // Hilfsvariablen anlegen double X = 0; // X double Y = 0; // Y char Mass[6]; // Masseinheit //-- Koordinatensystem zeichnen // Linienfarbe Schwarz wählen Image1->Canvas->Pen->Color = clBlack; // Koordinatensystem (Startpunkt bestimmen [X-min/Y-max]) X = x_Bildschirm(x0 + x_abst,x0,x1,Image1->Width); Y = y_Bildschirm(y1,y0,y1,Image1->Height); // Auf Startpunkt setzen Image1->Canvas->MoveTo(X,Y); // Pfeilspitze zeichnen (Y-Achse) Image1->Canvas->LineTo(X-3,Y+10); Image1->Canvas->LineTo(X+3,Y+10); Image1->Canvas->LineTo(X,Y); // Y-Achse Nullpunkt bestimmen Y = y_Bildschirm(0,y0,y1,Image1->Height); // Y-Achse zeichnen (Y-max zu Y-min) Image1->Canvas->LineTo(X,Y); // X-Achse Endpunkt bestimmen X = x_Bildschirm(x1,x0,x1,Image1->Width); // X-Achse zeichnen Image1->Canvas->LineTo(X,Y); // Pfeilspitze zeichnen (X-Achse) Image1->Canvas->LineTo(X-10,Y+3); Image1->Canvas->LineTo(X-10,Y-3); Image1->Canvas->LineTo(X,Y); //-- Gitterkreuz zeichnen und Beschriften // Linienfarbe grau wählen Image1->Canvas->Pen->Color = clGray; // Schleife start bei x0, Ende bei x1, Linie alle X_Abstände for(double dx = x0; dx <= x1; dx = dx + x_abst) { // Wenn dx größer x0 und kleiner x1 if(dx > x0 && dx < x1) { // Y-Achse Nullposition ermitteln Y = y_Bildschirm(0,y0,y1,Image1->Height); // X-Achse dx Position ermitteln X = x_Bildschirm(dx,x0,x1,Image1->Width); // dx als Text unter Koordinatensystem ausgeben Image1->Canvas->TextOutA(X, Y +15, dx); // Wieder auf (x/y) Position springen Image1->Canvas->MoveTo(X,Y); // Y-Achse 100 ermitteln Y = y_Bildschirm(100,y0,y1,Image1->Height); } // Wenn dx ungleich 0 und dx kleiner x1 if(dx!=0 && dx < x1) { // Linie zu (x/y) zeichnen Image1->Canvas->LineTo(X,Y); } } // X-Position für Beschriftung Y = y_Bildschirm(0,y0,y1,Image1->Height); X = x_Bildschirm(x1,x0,x1,Image1->Width); // Beschriftung X-Achse ("f/Masseinheit") strcpy(Mass,"f/"); strcat(Mass,Masseinheit); // Masseinheit in Koordinatensystem setzen Image1->Canvas->TextOutA(X -40, Y + Image1->Canvas->TextHeight("f/MHz") -10,Mass); // Auf (x/y) setzen Image1->Canvas->MoveTo(X,Y); // Schleife start bei y0, Ende bei y1, Linie alle Y_Abstände for(double dy = y0; dy <= y1; dy = dy + y_abst) { // Wenn dy größer 0 und kleiner y1 if(dy > 0 && dy < y1) { // Y-Achse Nullposition ermitteln Y = y_Bildschirm(dy,y0,y1,Image1->Height); // X-Achse dx Position ermitteln X = x_Bildschirm(x0 + x_abst,x0,x1,Image1->Width); // dy als Text neben Koordinatensystem ausgeben Image1->Canvas->TextOutA(X -20, Y, dy); // Wieder auf (x/y) Position springen Image1->Canvas->MoveTo(X,Y); // X-Achse Max ermitteln X = x_Bildschirm(x1,x0,x1,Image1->Width); } // Wenn dy ungleich 0 und dy kleiner y1 if(dy!=0 && dy < y1) { // Linie zu (x/y) zeichnen Image1->Canvas->LineTo(X,Y); } } // Y-Position für Beschriftung (Y-max) Y = y_Bildschirm(y1,y0,y1,Image1->Height); // X-Achse Endpunkt bestimmen X = x_Bildschirm(x0 +x_abst,x0,x1,Image1->Width); // Beschriftung Y-Achse Image1->Canvas->TextOutA(X -35,Y+Image1->Canvas->TextHeight("dB/uV"),"dB/uV"); } //---------------------------------------------------------------------------