Thema: Delphi Lineare Interpolation

Einzelnen Beitrag anzeigen

Six

Registriert seit: 2. Jun 2005
42 Beiträge
 
#1

Lineare Interpolation

  Alt 19. Jul 2005, 17:58
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] = 'Anthen
      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
Miniaturansicht angehängter Grafiken
sound3_121.jpg   sound2_100.jpg  
  Mit Zitat antworten Zitat