Hallo!
Also es geht um lineare Interpolation (zumindest glaube ich das
).
Ich zerbreche mir über das Problem nun schon seit längerer Zeit den Kopf und finde es eigentlich beschähment, nicht selber auf die Lösung zu kommen, aber was solls. Ich hoffe ihr könnt mir weiterhelfen.
Mein Problem: Ich möchte sowas wie in Bild 1 hinbekommen (Anhang). Ihr seht dort einen Ausschnitt aus einem Audioprogramm. Es geht aber eigentlich nur um die Abstände und Länge der Balken.
Wie ihr seht, werden die Balken und deren Abstände untereinander immer schmaler und genau so etwas versuche ich zu programmieren.
Es gibt als Vorgabe also nur eine Anfangsfrequenz (im Beispiel 5 Hz) und eine Endfrequenz (im Beispiel 20 Hz), sowie eine beliebige Zeitvorgabe. Nun soll zwischen den beiden Werten, wie gezeigt interpoliert werden.
Auch soll es absteigend möglich sein, also z.B. von 20 Hz auf 10 Hz und gleichbleibend (also für eine gewisse Zeit 5 Hz, dann wieder ansteigen auf 10 Hz absteigen auf 2 Hz etc.).
Was mir bislang gelungen ist, seht ihr in Bild zwei. Leider stimmen die Abstände in manchen Fällen nicht, wie zum Beispiel der dünne Streifen in der Mitte oder auch die beiden rechten Streifen. Ich glaube übrigens nicht, das dies an der "Auflösung" liegt.
Hier ist der zuständige Sourcecode:
Delphi-Quellcode:
procedure TForm1.XYZTest(P1x, P1y, P2x, P2y: integer);
var
GesamtzahlEinheiten, AbstandAnfang, AktuellerAbstand,
AnzahlDurchlaeufe: integer;
Steigung, m: double;
i, n: integer;
begin
Steigung := ABS((P2y - P1y) / (P2x - P1x));
AbstandAnfang := P1y;
AktuellerAbstand := AbstandAnfang;
for i := P1x to P2x do
begin
if i mod AktuellerAbstand = 0 then
begin
JvStringGrid2.Cells[1, Tabellenzeiger] := IntToStr(i);
if Aus then
JvStringGrid2.Cells[0, Tabellenzeiger] := 'Aus'
else
JvStringGrid2.Cells[0, Tabellenzeiger] := 'An';
JvStringGrid2.InsertRow(JvStringGrid2.RowCount + 1);
Aus := not Aus;
n := Round(P1y - (Steigung * P1x));
m := Steigung;
AktuellerAbstand := Round(m * i + n);
Inc(Tabellenzeiger);
end;
end;
// Tabelle Umsetzen
JvStringGrid2.RemoveRow(JvStringGrid2.RowCount - 1);
for i := 1 to JvStringGrid2.RowCount do
begin
PaintBox1.Canvas.Brush.Color := clblack;
PaintBox1.Canvas.Brush.Style := bssolid;
if JvStringGrid2.Cells[0, i] = 'An' then
PaintBox1.Canvas.Rectangle(StrToInt(JvStringGrid2.Cells[1, i - 1]), 0,
StrToInt(JvStringGrid2.Cells[1, i]), PaintBox1.Height);
end;
end; // XYZ (TForm1)
Ich hoffe das ganze ist einigermaßen verständlich. Es wird quasi erst eine Tabelle mit den Werten erstellt und "An" und "Aus" bedeutet dann eben Balken zeichnen oder nicht.
das sieht dann z.B. so aus:
An 0
Aus 10
An 20
Aus 29
An 38 usw.
Diese Tabelle wird dann in die Zeichnung auf der Paintbox umgesetzt (Das geschieht alles nur zu Testzwecken, daher ist der Code auch noch unsauber, unschön etc.
).
Aufgerufen wurde das ganze für das Beispiel hiermit:
procedure TForm1.Button7Click(Sender: TObject);
begin
TabellenZeiger := 0;
Aus := False;
XYZTest(0, 5, 250, 10);
end;
Also, wie ihr seht versuche ich das ganze mit Hilfe einer Linearen Funktion zu lösen. Aufgrund der Aussetzer (wie oben beschrieben) bezweifele ich allerdings mittlerweile, das dies der Richtige Weg ist. Auch wenn ich die Richtung ändere, also beispielsweise von 10 auf 5 Hz RUNTER möchte, produziert die Funktion nur undefinierbaren "Müll". Das Problem ließe sich zwar mit einer anfänglichen Abfrage lösen, aber wie gesagt, ich bin überhaupt im Zweifel und vielleicht besteht ja auch nur ein klitzekleiner Fehler, etwas, dass ich übersehen habe...
Ich hoffe ihr versteht mein Problem.
Wäre toll, wenn ihr mir helfen könntet
Six