Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Entfernung zwischen zwei Pixelkoordinaten (https://www.delphipraxis.net/102692-entfernung-zwischen-zwei-pixelkoordinaten.html)

cRayZo 2. Nov 2007 13:55


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:
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
Problem ist nur, dass sie viel zu viel Performace nimmt, vor allem wenn ich diese Funktion 30 mal jede Viertelsekunde durchlaufen lassen muss.

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

dominikkv 2. Nov 2007 14:03

Re: Entfernung zwischen zwei Pixelkoordinaten
 
Zitat:

Zitat von cRayZo
Dafür hab ich mir eine Oberfläche (im Anhang)

wo? :zwinker:
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

cRayZo 2. Nov 2007 14:12

Re: Entfernung zwischen zwei Pixelkoordinaten
 
joa also Bild ist jetzt im Anhang^^
zu deinem Tipp:
Delphi-Quellcode:
Entfernung := Wurzel(X*X+Y*Y)
ist ja nichts anderes als
Delphi-Quellcode:
power(x,2)+power(y,2)
so wie ich es benutzt habe
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^^

DeddyH 2. Nov 2007 14:16

Re: Entfernung zwischen zwei Pixelkoordinaten
 
Evtl. bringt der Einsatz von Threads schon einmal etwas.

cRayZo 2. Nov 2007 14:21

Re: Entfernung zwischen zwei Pixelkoordinaten
 
Zitat:

Zitat von DeddyH
Evtl. bringt der Einsatz von Threads schon einmal etwas.

ja da hast du auf jeden Fall recht, vorteil auf jeden Fall weil ich dazu noch einen dualcore hab. Nur mal so als Leistungsvergleich: wenn ich die Funktion so schnell wie möglich und so oft wie möglich 15 mal berechnen lass habe ich ne volle auslastung von einem Kern, der andere wird nicht benutzt.

Problem ist nur, ich weiß nicht wie ich einen Thread erstelle, noch nie gebraucht^^

Nikolas 2. Nov 2007 14:23

Re: Entfernung zwischen zwei Pixelkoordinaten
 
Delphi-Quellcode:
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
das kann man aber deutlich schöner machen.

a) die 65000 als Konstante deklarieren, reine Zahlen haben im Code eigentlich nichts zu run.

Delphi-Quellcode:
if entfernung>65000 then entfernung:=65000 else;
:shock: was macht das else? nimm doch einfach entfernung := min(entfernung, 65000);

Delphi-Quellcode:
entfernung:=(250*trunc(ntewurzel(2,trunc(power(leftx,2)+power(topx,2)))));
wie wäre es mit
Delphi-Quellcode:
entfernung = trunc(250*sqrt(leftx*leftx+topx*topx));
selbstgeschriebene Funktionen sind wohl kaum schneller als das eingebaute sqrt, das sicherlich aufs höchste optimiert ist.

Klaus01 2. Nov 2007 14:24

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

3_of_8 2. Nov 2007 14:26

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.

dominikkv 2. Nov 2007 14:31

Re: Entfernung zwischen zwei Pixelkoordinaten
 
hmm ich hab grad nen test gemacht:
Delphi-Quellcode:
Y := X*X
ist ca 36 mal so schnell wie
Delphi-Quellcode:
Y := Trunc(Power(X, 2));
und dein ntewurzel kenne ich nicht :/
ich würde das so machen:
Delphi-Quellcode:
entfernung := 250 * round(SQRT(leftx * leftx + topx * topx));
edit:
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));

cRayZo 2. Nov 2007 14:33

Re: Entfernung zwischen zwei Pixelkoordinaten
 
Zitat:

Zitat von Nikolas
selbstgeschriebene Funktionen sind wohl kaum schneller als das eingebaute sqrt, das sicherlich aufs höchste optimiert ist.

klar nur wenn ich diese Funktion nciht kenne versuche ich mir anders zu helfen ;)

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?

dominikkv 2. Nov 2007 14:46

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)?

cRayZo 2. Nov 2007 15:06

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:
);
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);
vll geht die Lösung des Problems so leichter ;)
lg cRayZo

dominikkv 2. Nov 2007 15:18

Re: Entfernung zwischen zwei Pixelkoordinaten
 
das hier:
Delphi-Quellcode:
if Edit1.Text='' then Edit1.Text:='500';  try Timer1.Interval:=strtoint(edit1.Text) except end;
solltest du anders lösen... zB im OnChange des Edits oder du spendierst noch nen Button bei dem du das änderst.
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;

Nikolas 2. Nov 2007 15:54

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.

cRayZo 2. Nov 2007 19:31

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 ;)

Nikolas 2. Nov 2007 21:17

Re: Entfernung zwischen zwei Pixelkoordinaten
 
Zitat:

Soundlautstärke
Wie viele Lautstärken kennst du eigentlich? TonLautstärke ist echt ein schönes Wort :wall:
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 08:59 Uhr.

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