![]() |
Entfernung zwischen zwei Pixelkoordinaten
Liste der Anhänge anzeigen (Anzahl: 1)
Hi, ich möchte die entfernung zwischen 2 pixelpunkten in einem Panel berechnen lassen, und das wie folgt.
in unserem Hörsaal haben wir ca 30 PCs. Ich möchte ein Programm schreiben, mit dem man ein Surroundsound für diese PCs erstellen kann. Dafür hab ich mir eine Oberfläche (im Anhang) erstellt und möchte jetzt für jeden PC die Lautstärke in Abhängigkeit zur Entferung eines Punktes(welcher sich mit dem Mauszeiger bewegt) berechnen. Dazu habe ich folgende Funktion aufgestellt und sie funktioniert auch reibungslos. hier erstmal der code
Delphi-Quellcode:
Problem ist nur, dass sie viel zu viel Performace nimmt, vor allem wenn ich diese Funktion 30 mal jede Viertelsekunde durchlaufen lassen muss.
procedure TForm1.Timer1Timer(Sender: TObject); //Timerintervall auf 250
var topx:real; entfernung:integer; leftx:real; shape1top, shape1left:integer; begin shape1Top:=shape1.Top;shape1left:=shape1.Left; //PC031 topx:=abs(PC031.Top-shape1Top); leftx:=abs(PC031.left-shape1left); entfernung:=(250*trunc(ntewurzel(2,trunc(power(leftx,2)+power(topx,2))))); if entfernung>65000 then entfernung:=65000 else; SetMasterVolume(MasterVolumeControl,65000-entfernung); {Lautstärke des PCs}:=floattostr(65000-entfernung); //6500 als maximaler Lautsärkewert so lange rede kurzer sinn, habt ihr eine einfachere Lösung mit der ich die Entfernung zweier Punkte ausrechnen kann? sie sollte allerdings noch möglichst genau sein schonmal thx für die Antwort, lg cRayZo |
Re: Entfernung zwischen zwei Pixelkoordinaten
Zitat:
Ansonsten: Entfernung := Wurzel(X*X+Y*Y) Wobei X und Y der X- und Y-Abstand sind. Als Wurzel kannst du SQRT aus der Math.pas nehmen |
Re: Entfernung zwischen zwei Pixelkoordinaten
joa also Bild ist jetzt im Anhang^^
zu deinem Tipp:
Delphi-Quellcode:
ist ja nichts anderes als
Entfernung := Wurzel(X*X+Y*Y)
Delphi-Quellcode:
so wie ich es benutzt habe
power(x,2)+power(y,2)
der Rest in meiner Gleichung rundet den Wert ja nur und rechnet diesen in die Lautstärke um so wie ich es gemacht habe, ich hab die Änderung von dir trotzdem mal ausprobiert..die performance wird noch miserabler^^ Will garned dran denken wies dann aussieht, wenn das Senden der Lautstärke an die PCs performancemäßig noch gehen soll^^ |
Re: Entfernung zwischen zwei Pixelkoordinaten
Evtl. bringt der Einsatz von Threads schon einmal etwas.
|
Re: Entfernung zwischen zwei Pixelkoordinaten
Zitat:
Problem ist nur, ich weiß nicht wie ich einen Thread erstelle, noch nie gebraucht^^ |
Re: Entfernung zwischen zwei Pixelkoordinaten
Delphi-Quellcode:
das kann man aber deutlich schöner machen.
topx:=abs(PC031.Top-shape1Top);
leftx:=abs(PC031.left-shape1left); entfernung:=(250*trunc(ntewurzel(2,trunc(power(leftx,2)+power(topx,2))))); if entfernung>65000 then entfernung:=65000 else; SetMasterVolume(MasterVolumeControl,65000-entfernung); {Lautstärke des PCs}:=floattostr(65000-entfernung); //6500 als maximaler Lautsärkewert a) die 65000 als Konstante deklarieren, reine Zahlen haben im Code eigentlich nichts zu run.
Delphi-Quellcode:
:shock: was macht das else? nimm doch einfach entfernung := min(entfernung, 65000);
if entfernung>65000 then entfernung:=65000 else;
Delphi-Quellcode:
wie wäre es mit
entfernung:=(250*trunc(ntewurzel(2,trunc(power(leftx,2)+power(topx,2)))));
Delphi-Quellcode:
selbstgeschriebene Funktionen sind wohl kaum schneller als das eingebaute sqrt, das sicherlich aufs höchste optimiert ist.
entfernung = trunc(250*sqrt(leftx*leftx+topx*topx));
|
Re: Entfernung zwischen zwei Pixelkoordinaten
Hallo,
nur mal eine Verständnisfrage, warum berechnest Du die Entfernungen in einem TimerIterval von 250ms? Die Berechnungen müßen doch nur dann durchgeführt werden, wenn der Punkt verschoben wurde und nicht permanent. Grüße Klaus |
Re: Entfernung zwischen zwei Pixelkoordinaten
Wenn ich mich richtig erinnere, ist sqrt sogar eine FPU-Operation und somit um einiges schneller als jede mögliche andere Implementierung. Achja, und so nebenbei, power(x, 2) ist um einiges langsamer als x*x. Naja, jedenfalls theoretisch, praktisch gesehen wird der Compiler es wahrscheinlich sowieso wegoptimieren und in x*x übersetzen, aber x*x ist immer noch schöner.
|
Re: Entfernung zwischen zwei Pixelkoordinaten
hmm ich hab grad nen test gemacht:
Delphi-Quellcode:
ist ca 36 mal so schnell wie
Y := X*X
Delphi-Quellcode:
und dein ntewurzel kenne ich nicht :/
Y := Trunc(Power(X, 2));
ich würde das so machen:
Delphi-Quellcode:
edit:
entfernung := 250 * round(SQRT(leftx * leftx + topx * topx));
ich seh grad, der vorschlag von Nikolas ist genauer, da er zuesrt *250 nimmt und dann die nachkommststellen abschneidet... ansonsten kannst du ja noch runden xD
Delphi-Quellcode:
entfernung := round(250 * SQRT(leftx * leftx + topx * topx));
|
Re: Entfernung zwischen zwei Pixelkoordinaten
Zitat:
joa also muss ich mich dann owhl erstmal in Threads probieren, anders wirds wohl kaum gehen, wenn ich mehr performance erreichen will.. oder hat jemand noch eine andere idee? |
Re: Entfernung zwischen zwei Pixelkoordinaten
du solltest erst einmal suchen was genau am längsten in deiner procedure dauert.
-das berechnen der entfernung? -das verändern der lautstärke (SetMasterVolume)? wie sieht bis jetzt deine Timerprozedur aus (also hast du was verändert)? |
Re: Entfernung zwischen zwei Pixelkoordinaten
nicht viel aber ich kann sie dir ja mal vollständig mit Funktionen kopieren:
[code=delphi]function _VolumeControl(Mixer: hMixerObj; var Control: TMixerControl): MMResult; var Line : TMixerLine; Controls : TMixerLineControls; begin ZeroMemory(@Line, SizeOf(Line)); Line.cbStruct := SizeOf(Line); Line.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; Result := mixerGetLineInfo(Mixer, @Line, MIXER_GETLINEINFOF_COMPONENTTYPE); if Result = MMSYSERR_NOERROR then begin ZeroMemory(@Controls, SizeOf(Controls)); Controls.cbStruct := SizeOf(Controls); Controls.dwLineID := Line.dwLineID; Controls.cControls := 1; Controls.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME; Controls.cbmxctrl := SizeOf(Control); Controls.pamxctrl := @Control; Result := mixerGetLineControls(Mixer, @Controls, MIXER_GETLINECONTROLSF_ONEBYTYPE); end; end; procedure SetMasterVolume(Mixer: hMixerObj; Value: Word); var MasterVolume : TMixerControl; Details : TMixerControlDetails; UnsignedDetails : TMixerControlDetailsUnsigned; Code : MMResult; begin Code := _VolumeControl(Mixer, MasterVolume); if Code = MMSYSERR_NOERROR then begin with Details do begin cbStruct := SizeOf(Details); dwControlID := MasterVolume.dwControlID; cChannels := 1; // set all channels cMultipleItems := 0; cbDetails := SizeOf(UnsignedDetails); paDetails := @UnsignedDetails; end; UnsignedDetails.dwValue := Value; Code := mixerSetControlDetails(Mixer, @Details, MIXER_SETCONTROLDETAILSF_VALUE); end; if Code <> MMSYSERR_NOERROR then raise Exception.CreateFmt('SetMasterVolume failure, '+ 'multimedia system error #%d',
Code:
vll geht die Lösung des Problems so leichter ;)
);
end; /////////////////////////////////////////////////function end//////////////////////// procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Shape1.Left:= X-4 {1}; Shape1.Top := Y-4 {2}; end; procedure TForm1.Timer1Timer(Sender: TObject); var leftx,topx: real; shape1top, shape1left,entfernung: integer; begin shape1Top:=shape1.Top;shape1left:=shape1.Left; if Edit1.Text='' then Edit1.Text:='500'; try Timer1.Interval:=strtoint(edit1.Text) except end; //PC001 topx:=abs(PC001.Top-shape1Top); leftx:=abs(PC001.left-shape1left); entfernung:=trunc(250*sqrt(leftx*leftx+topx*topx)); if entfernung>65000 then entfernung:=65000; SetMasterVolume(MasterVolumeControl,65000-entfernung); lbPC001.Caption:=floattostr(65000-entfernung); lg cRayZo |
Re: Entfernung zwischen zwei Pixelkoordinaten
das hier:
Delphi-Quellcode:
solltest du anders lösen... zB im OnChange des Edits oder du spendierst noch nen Button bei dem du das änderst.
if Edit1.Text='' then Edit1.Text:='500'; try Timer1.Interval:=strtoint(edit1.Text) except end;
Versuchs mal so:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var X, Y, entfernung: Integer; begin Y := abs(PC001.Top - shape1.Top); X := abs(PC001.left - shape1.left); entfernung := min(round(250 * sqrt(X * X + Y * Y)), 65000); SetMasterVolume(MasterVolumeControl, 65000 - entfernung); lbPC001.Caption := IntToStr(65000 - entfernung); end; |
Re: Entfernung zwischen zwei Pixelkoordinaten
Die Zeit wird eher beim lautstärke setzen und nicht bei der entfernungsberechnung verbraten.
Du könntest zum einen das Mouse-move Event nehmen und nur was machen, wenn sich die Maus bewegt hat, (vgl. Klaus), oder du merkst dir die aktuelle lautstärke undveränderst sie nur, wenn der neue Wert mehr als 5% davon abweicht. Stoppe doch einfach mal die Zeit um 10000 mal die Entfernung zu berechnen und um 10.000 Mal eine neue Lautstärke zu setzen und schreibe hier mal die Zeiten hin. Wenn du etwas optimieren willst, solltest du schon wissen, wo die Zeit bleibt. |
Re: Entfernung zwischen zwei Pixelkoordinaten
ja es ist auf jeden Fall die Lautstärke, (ich meine das sieht man ja eig schon)
aber das Problem ist (was ich eig sonst nicht mache, aber ich war halt faul) der code is ned von mir, und ich versteh ihn nicht^^ Es gibt auch keine einfachere Lösung für die Änderung der Soundlautstärke oder? //edit: ich habe für die Frage im Soundbereich die Frage gestellt, das Problem mit der Entfernung ist ja jetzt gut gelöst, thx nochmal ;) |
Re: Entfernung zwischen zwei Pixelkoordinaten
Zitat:
Da kann ich doch gleich zum ServicePoint der DB direkt neben dem Station Store gehen und mir ein Ticket kaufen, um nach England auszuwandern. Was hat dir die deutsche Sprache getan, dass du sie so behandeln musst? :shock: Nu mal sinnvoll: Die Frage ist doch, warum du diesen Code sooft ausführst. Greif dir doch einmal mal ein memo und trage bei jedem Aufruf deiner Funktion dort den neuen Wert ein. Ich wette, dass du ziemlich scrollen musst, um unterschiedliche Werte zu finden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:42 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