E
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");
}
//---------------------------------------------------------------------------