Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Abfragen ob sich Maus in Kreis befindet (https://www.delphipraxis.net/126229-abfragen-ob-sich-maus-kreis-befindet.html)

Onkelrossie 20. Dez 2008 12:43


Abfragen ob sich Maus in Kreis befindet
 
Hallo DP Freunde,

ich habe mal wieder ein kleines Problem.
Wie kann ich herrausfinden ob sich die Maus innerhalb eines Kreises befindet?

Ich habe dazu schon folgeden Code geschrieben was aber nur für ein Viereck funktioniert.
Also ich durchlaufe die Zeilen von oben links nach unten rechts und frage ab ob sich die Maus
an den jeweiligen Coordinaten befindet. Aber ein Kreis ist ja Rund und nun stehe ich vor dem problem
wie ich das bewerkstelligen soll. Mit 2 geschachtelten For-Schleifen komme ich da nicht weiter oder?

Hier erstmal was ich geschrieben habe:

Delphi-Quellcode:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  x1, y1: Integer;
begin
  for x1 := Shape1.Left to Shape1.Left + Shape1.Width -1 do
  for y1 := Shape1.Top to Shape1.Top + Shape1.Height -1 do
  if ((x1 = X) and (y1 = Y)) then
  begin
    //Maus in Shape also nicht nur in Kreis
    break;
  end;
end;
Vielen Dank schonmal im Voraus!


Mit freundlichen Grüßen
Onkelrossie

DeddyH 20. Dez 2008 12:44

Re: Abfragen ob sich Maus in Kreis befindet
 
Nur so ein Gedanke: mit CreateEllipticRgnIndirect eine runde Region mit den passenden Koordinaten erstellen und mit PtInRegion abfragen.

[edit] Source dazu aus meiner Button-Komponente:
Delphi-Quellcode:
function TGDIPlusRoundButton.PointInRgn: Boolean;
var rHandle: THandle;
    p: TPoint;
begin
  Result := True;
  rHandle := CreateEllipticRgnIndirect(Rect(0,0,Self.Width,Self.Height));
  if rHandle <> 0 then
    begin
      p := Self.ScreenToClient(Mouse.CursorPos);
      Result := PtInRegion(rHandle,p.X,p.Y);
      DeleteObject(rHandle);
    end;
end;
[/edit]

Uwe Raabe 20. Dez 2008 13:10

Re: Abfragen ob sich Maus in Kreis befindet
 
Eigentlich sollte der Code auch für ein Rechteck nicht funktionieren, da das Shape einen eigenen MouseMove-Event hat und das MouseMove des Forms gar nicht aufgerufen wird, wenn die Maus über dem Shape ist.

So sollte es aber funktionieren:

Delphi-Quellcode:
procedure TForm33.Shape1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  Inside: Boolean;
  R: Extended;
begin
  if Shape1.Width < Shape1.Height then
    R := Shape1.Width/2
  else
    R := Shape1.Height/2;
  Inside := Sqr(X - R) + Sqr(Y - R) <= Sqr(R);
  ...
end;

Onkelrossie 20. Dez 2008 13:44

Re: Abfragen ob sich Maus in Kreis befindet
 
Danke für eure schnellen Atnworten.
Hat funktioniert.


Gruß
Onkelrossie

SirThornberry 20. Dez 2008 13:49

Re: Abfragen ob sich Maus in Kreis befindet
 
Mein Gedanke wäre einfach zu überprüfen wie weit die Maus vom Mittelpunkt entfernt ist (Radius) und dann zu schauen ob der Radius kleiner dem des Kreises ist.

Uwe Raabe 20. Dez 2008 13:55

Re: Abfragen ob sich Maus in Kreis befindet
 
Zitat:

Zitat von SirThornberry
Mein Gedanke wäre einfach zu überprüfen wie weit die Maus vom Mittelpunkt entfernt ist (Radius) und dann zu schauen ob der Radius kleiner dem des Kreises ist.

Dann hatte ich deinen Gedanken in meiner Antwort bereits in Code umgesetzt...

DeddyH 20. Dez 2008 13:58

Re: Abfragen ob sich Maus in Kreis befindet
 
Mein Gedanke war, Windows für mich rechnen zu lassen :mrgreen:. Gerade wenn es kein Kreis, sondern eine Ellipse ist, kann man ja nicht mehr einfach mit einem fixen Radius rechnen.

Onkelrossie 20. Dez 2008 15:02

Re: Abfragen ob sich Maus in Kreis befindet
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, ich habe das nun wie folgt umgesetzt:

Delphi-Quellcode:
unit Unit4;

interface

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

type
  TForm4 = class(TForm)
    shp1: TShape;
    shp2: TShape;
    procedure shp2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure shp1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
    procedure Simulate (X, Y: Integer);
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);
begin
  Doublebuffered := True;
end;

procedure TForm4.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Simulate(X, Y);
end;

procedure TForm4.shp1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Simulate(shp1.Left + X, shp1.Top + Y);
end;

procedure TForm4.shp2MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Simulate(shp2.Left + X, shp2.Top + Y);
end;

function PointInRgn(R: TRect): Boolean;
var rHandle: THandle;
    p: TPoint;
begin
  Result := True;
  rHandle := CreateEllipticRgnIndirect(R);
  if rHandle <> 0 then
    begin
      p := Form4.ScreenToClient(Mouse.CursorPos);
      Result := PtInRegion(rHandle,p.X,p.Y);
      DeleteObject(rHandle);
    end;
end;

procedure TForm4.Simulate (X, Y: Integer);
var
  rKreis1, rKreis2: Integer;
  Kreis1posX, Kreis1posY: Integer;
  Kreis2posX, Kreis2posY: Integer;
  R: TRect;
begin
  Refresh;

  rKreis1 := shp1.Width div 2;
  rKreis2 := shp2.Width div 2;

  Kreis1posX := shp1.Left + rKreis1;
  Kreis1posY := shp1.Top + rKreis1;
  Kreis2posX := shp2.Left + rKreis2;
  Kreis2posY := shp2.Top + rKreis2;

  R.TopLeft := Point(shp2.Left - rKreis1, shp2.Top - rKreis1);
  R.BottomRight := Point(shp2.Left + shp2.Width + rKreis1 +2, shp2.Top + shp2.Height + rKreis1 +2);
  Canvas.MoveTo(Kreis1posX, Kreis1posY);

  Canvas.Ellipse(X + rKreis1, Y + rKreis1, X - rKreis1, Y - rKreis1);
  Canvas.LineTo(X, Y);

  if PointInRgn(R) then
  begin
    Canvas.LineTo(5 * rKreis2 * (X - Kreis2posX)
      , 5 * rKreis2 * (Y - Kreis2posY));
    Canvas.MoveTo(Kreis2posX, Kreis2posY);
    Canvas.LineTo(-(5 * rKreis2 * (X - Kreis2posX))
      , -(5 * rKreis2 * (Y - Kreis2posY)));
  end;

end;
end.
Der Reflextionspunkt des großen Kreises wird auch richtig angezeigt aber der des kleinen leider nicht. Hat jemand eine Lösung um den Ausfallswinkel der kleinen Kugel zu berechnen und anzeigen zu lassen? Weiterhin hätte ich noch das Problem das ich mit der Maus außen den großen Kreis streifen muss damit die exakte Richtung angezeigt wird. Sobald ich mit der Maus in den großen Kreis gehe wird mir alles falsch berechnet. Ich habe mir überlegt das ich die Linie die vom kleines Kreis aus geht als Kollisionsabfrage benutze d.h. sobald die Linie auf den großen Kreis trifft wird mir die neue Richtung beider Kreise angezeigt. Leider bin ich noch nicht so gut was das Programmieren in Delphi anbelangt und die Suche konnte mir auch nicht weiterhelfen. Ich habe zwar ein paar Interessante Lösungsansätze gefunden nur basieren die alle auf Billardspiele bzw. Kugeln. Die mathematische Seite um das zu berechnen ist mir soweit klar aber ich habe keine Ahnung wie ich das in Delphi umsetzen soll.

Bitte um Hilfe!

Vielen Dank schonmal im Voraus.


Gruß
Onkelrossie

Onkelrossie 5. Jan 2009 20:29

Re: Abfragen ob sich Maus in Kreis befindet
 
Hallo DP,

erstmal allen ein erfolgreiches und vorallem gesundes neues Jahr!

Ich war nun 2 Wochen über die Feiertage bei Verwandten in Hamburg geblieben und
bin gestern abend erst wieder zurück gekommen.

Stehe wie vor 2 Wochen noch immer vor dem gleichen Problem und komme einfach nicht weiter.
So langsam gebe ich auch auf was mein Erfindungsgeist anbelangt.

Kann mir denn keiner bei meinem Problem helfen oder waren alle über die Feiertage verreist?

Vielen Dank schonmal.


Gruß
Onkelrossie


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:15 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