Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Arrays skalieren/interpolieren (https://www.delphipraxis.net/156314-arrays-skalieren-interpolieren.html)

aphexx 27. Nov 2010 20:20

Arrays skalieren/interpolieren
 
Hallo Leute!

Ich hab mal eine kleine Frage zum Thema Arrays (Floats),die ich gerne skalieren würde.
Also von Länge A auf Länge B bringen und dabei die Zwischenpunkte interpolieren.
Ich denke, dass man den Skalierungfaktor B/A braucht, aber wie geht es dann weiter?
Muss nichts Hochkompliziertes wie kubische Interpolation sein; ein kleiner Tipp/Link wär schon super.

Würde mich sehr über eine Antwort freuen!

Peter1999 27. Nov 2010 21:05

AW: Arrays skalieren/interpolieren
 
Das einfachste wäre wohl eine lineare Interpolationsfunktion. Alternativ eignet sich auch ein Halbsinusübergang.
Das kommt aber auf den Verwendungszweck an: Akkustik, Audio, Betriebslasten, Messsignale (Dehnungen, Beschleunigungen, Kräfte) ???
Je nachdem, ob du die Abtastfrequenz erhöhst oder verringerst, musst du natürlich das Shannon-Theorem beachten, also ggf. zuvor einen FFT-Tiefpass anwenden.

Die Variante "ganz einfach" gibt es also nicht, wenn es physikalisch sinnvoll bleiben soll.

Viele Grüße,
Peter

Bummi 27. Nov 2010 21:41

AW: Arrays skalieren/interpolieren
 
nur mal schnell hingeschludert
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TFarray=Array of Double;
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Procedure Interpolate(src,dest:TFarray);
//20101127 by Thomas Wassermann
var
  i,a,b:Integer;
  vh,ivh:Double;
begin
  vh := high(src) / high(dest);
  for I := low(dest) to High(dest) do
      begin
      a := Trunc(i * vh);
      ivh := (i*vh) - Trunc(i * vh);
      b := a + 1;
      dest[i]:=(src[a] * (1-ivh)) + (src[b] * ivh) ;
      end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   a,b:TFarray;
   i:INteger;
begin
   SetLength(a,11);
   for I := 0 to High(a) do a[i]:=i;
   SetLength(b,21);
   Interpolate(a,b);
   Showmessage('a');// als Debuggerbrechpunkt
end;

end.

Peter1999 27. Nov 2010 22:25

AW: Arrays skalieren/interpolieren
 
Das ist aber genau die Lösung, die nicht auf den Frequenzinhalt achtet und damit logischerweise die Spiegelfrequenzen nicht erfasst.
Physikalisch kann hier also totaler Unsinn entstehen!!

Bummi 27. Nov 2010 22:33

AW: Arrays skalieren/interpolieren
 
@Peter1999

Da der Threadersteller nicht geschrieben hat wofür er es benötigt, wollte ich einfach mal einen Ball ins Spiel bringen. Für grafische Darstellungen würde o.g. verwendbare Ergebnisse liefern.

Bei den von Dir angeschnittenen Themen kann ich ohnehin nicht mitreden.

Peter1999 27. Nov 2010 22:39

AW: Arrays skalieren/interpolieren
 
Das ist schon OK.
Als ersten Denkansatz ist deine Lösung auch zu verwenden.
Ich wollte auch nur darauf hinweisen, dass man sich deutlich mehr Mühe geben muss, wenn man mit den Daten dann auch tatsächlich arbeiten möchte (oder muss :wink: ).

aphexx 28. Nov 2010 11:09

AW: Arrays skalieren/interpolieren
 
Erstmal vielen Dank für die Vorschläge! Ich werd's gleich mal ausprobieren.

Um den usecase mal grob zu umreissen:
Ich arbeite (hobbymässig) an einer GUI für einen 3D-Renderer und steuere verschiedene Parameter mit Werten von 0 bis 1...
Nun hab ich mir gedacht, dass es ganz nützlich sein kann, wenn man bspw. eine Reihe von 200 Floats nun mal 1,33 multipliziert und bei 266 Einträgen landet, um beispielsweise eine (Parameter-) Animation zu strecken/stauchen.

Edit:
Deine Funktion klappt wunderbar, super!
Doch manchmal bekomme ich leider "Ungültige Gleitkommaoperation", wenn sich zu wenig Werte in den Arrays befinden (bspw. von 6 auf 3 runterskalieren),
aber das ist nicht weiter schlimm, da die Arrays i.d.R. wesentlich mehr Einträge beinhalten.
Ich werde nochmal schauen, ob ich einen Mini-Plotter einbaue, um das Ergebnis visuell zu überprüfen.
Zudem guck ich mal, ob ich es schaffe, die Interpolation auf Sin/Cos/Beziér abzuändern.

Danke nochmal! =)


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz