Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Zeichnen einer Linie im 45° Winkel (https://www.delphipraxis.net/59387-zeichnen-einer-linie-im-45%B0-winkel.html)

1ceman 21. Dez 2005 16:04


Zeichnen einer Linie im 45° Winkel
 
Ich hab nen kleines GrafikProgramm geschrieben, mit dem man Linien,Dreiecke,Rechtecke,Quadrate,
Ellipsen usw. zeichnen kann.Man kann die Objekte so aufziehen, also man sieht immer wie die Linie oder so
aussieht, während man sie zieht. So jetzt möchte ich, das wenn man shift drückt, während man nen Linie zieht,
dass die Linien nur um 45° Winkel gezeichnet werden(so wie bei Photoshop).
Das Zeichnen der Linie funktioniert so, man klickt irgendwo hin, was der Startpunkt ist und man lässt die Maus dann
gedrückt und zieht die Linie hinter sich her.
ich hab mir das dann so überlegt, das ich überprüfen muss, in welchem Winkel die Linie zum Startpunkt ist.

Delphi-Quellcode:
if ssShift in Shift
then begin
if (SP.X=X) or (radtodeg(ArcSin((X-SP.X)/(Y-SP.Y)))<=45)
then EP:=Point(SP.X,Y);
end
else EP:=Point(X,Y);
(SP=StartPunkt, der wird beim klick gesetzt(OnMouserDown))

das geht auch so schon nen bissl,wenn man vom Startpunkt aus die Maus senkrecht nach unten bewegt oder nen bissl
schräg recht nach unten.Das Problem ist nur, dass der wenn man die Maus zuweit
vom StartPunkt aus nach schräg rechts unten verschiebt nen Fehler 'Invalid Floating Point Operation' ausgibt.

//Edit: Ein Punkt an dem es net geht wäre (153/153) und als Startpunkt(48/48)

shmia 21. Dez 2005 16:43

Re: Zeichnen einer Linie im 45° Winkel
 
Winkelberechnungen sind hier fehl am Platz.
Du brauchst doch nur prüfen, ob der Abstand in X-Richtung = dem Abstand in Y-Richtung ist.
Dann hast du einen 45, 135, 225 oder 315 Grad-Winkel.
Delphi-Quellcode:
if Abs(X-SP.X)= Abs(Y-SP.Y) then

DGL-luke 21. Dez 2005 17:06

Re: Zeichnen einer Linie im 45° Winkel
 
damit kann man ja nur herausfinden, ob die linie im 45° Winkel ist.

aber wie kann man aus anfangs- und endpunkt eine machen, das ist die frage.

1ceman 21. Dez 2005 17:15

Re: Zeichnen einer Linie im 45° Winkel
 
Liste der Anhänge anzeigen (Anzahl: 1)
so ich hab mal eben nen bild gemacht.
der Rote Punkt ist der Startpunkt.
der linke rand des Bildes ist die Y-Achse und der obere die X-Achse.
die schwarzen Linien zeigen die Linien, die bei gedrückter shift Taste nur gezeichnet werden dürfen.
und die blaue linie ist ein beispiel für die Linie die als trennung dient, um zu sagen, in welchem
Bereich welche Linie gezeichnet werden soll.
Beispiel: ist der Cursor im bereich zwischen vom punkt aus senkrecht nach unte gehenden Linie und der blauen Linie, soll eine Linie
vom roten Punkt senkrecht nach unten bis zur y-Koordinate des aktuellen Punktes gezeichnet werden.


//Edit:
Im QuellCode oben ist übrigens ein Fehler es muss mit 22,5 und nicht mit 45 verglichen werden.

Delphi-Quellcode:
if ssShift in Shift
then begin
if (SP.X=X) or (radtodeg(ArcSin((X-SP.X)/(Y-SP.Y)))<=22.5)
then EP:=Point(SP.X,Y);
end
else EP:=Point(X,Y);

shmia 21. Dez 2005 17:23

Re: Zeichnen einer Linie im 45° Winkel
 
Zitat:

Zitat von DGL-luke
damit kann man ja nur herausfinden, ob die linie im 45° Winkel ist.
aber wie kann man aus anfangs- und endpunkt eine machen, das ist die frage.

Du meinst so eine Art "Snap-In" Einrast Funktion ?
Also erst mal schauen, in welchem Quadranten wir sind:
Delphi-Quellcode:
function Quadrant(p:TPoint):integer;
begin
   if (p.x=0) or (p.y=0) then
      result := 0
   else if p.x > 0 then
   begin
      if p.y > 0 then
         result := 1
      else
         result := 2;
   end
   else
   begin
      if p.y > 0 then
         result := 3
      else
         result := 4;
   end;
end;
Dann anhand des Quadranten den Zielpunkt rechnen.
Ich verwende hier nur die X-Koordinate; man könnte auch nur Y verwenden
oder mit Pythagoras die Länge errechnen.
Man muss alle 4 möglichen Fälle aufzeichnen, um die korrekten Vorzeichen rauszukriegen.
Delphi-Quellcode:
   case Quadrant(Point(X-SP.X,Y-SP.Y)) of
      1: EP := Point(X, X);
      2: EP := Point(X, -X);
      3: EP := Point(X, -X);
      4: EP := Point(x, X);

      0: EP := Point(X,Y); // sonderfall: Falls X oder Y gleich 0 darf man auch
        // auf den Achsen einrasten
    end;

1ceman 21. Dez 2005 17:30

Re: Zeichnen einer Linie im 45° Winkel
 
meinst du das so, das man einfach sagt, das der Startpnukt der Ursprung ist??

//Edit: du hast dich auch mit den Quadranten ein bissl vertan, unten bei der Abfrage müssen
3 und 4 vertauscht werden(ist aber net so schlimm).

1ceman 21. Dez 2005 17:37

Re: Zeichnen einer Linie im 45° Winkel
 
habs zwar noch net getestet, nur mal so theoretisch überlegt und müsste eigentlich gehen
schonmal vielen Danke und ist echt ne fette idee.

werds direkt mal einbauen.

1ceman 21. Dez 2005 17:45

Re: Zeichnen einer Linie im 45° Winkel
 
Liste der Anhänge anzeigen (Anzahl: 1)
schade, geht doch nicht so richtig.
guck dir nochmal das Bild an ,was ich geuppt habe, ich will ja nicht, das er immer wenn er im Quadranten 2 z.b ist,
das er dann dort ne linie im 45° Winkel zur y-Achse macht, sondern wenn der Cursor im grünen Bereich ist soll er ne senkrechte Linie zum roten Punkt zeichen und wenn er im orangen(gelben) bereich ist, soll er die schwarze Linie zeichnen, die an diesen orangen bereich grenzt.
Am besten ist es, das ihr wenn ihr Photoshop habt, mal ne Linie zeichnet und dabei shift drückt. Dann seht ihr was ich meine.

1ceman 21. Dez 2005 18:59

Re: Zeichnen einer Linie im 45° Winkel
 
so habs endlich geschafft:

Delphi-Quellcode:
if ssShift in Shift
then begin
          H.X:=X-SP.X;
          H.Y:=Y-SP.Y;
          if ((H.X<0) and (H.Y<0)) or ((H.X>0) and (H.Y>0))
          then begin
                      if (abs(H.X)<=abs(H.Y))
                      then begin
                                 if (SP.X=X) or (radtodeg(ArcSin(H.X/H.Y))<=22.5)
                                 then EP:=Point(SP.X,Y)
                                 else EP:=Point((SP.X+H.X),(SP.Y+H.X));
                      end
                      else begin
                                 if (SP.Y=Y) or (radtodeg(ArcSin(H.Y/H.X))<=22.5)
                                 then EP:=Point(X,SP.Y)
                                 else EP:=Point((SP.X+H.X),(SP.Y+H.X));
                           end;
                      end
          else begin
                      H.Y:=(SP.Y-Y);
                      if (abs(H.X)<=abs(H.Y))
                      then begin
                                 if (SP.X=X) or (radtodeg(ArcSin(H.X/H.Y))<=22.5)
                                 then EP:=Point(SP.X,Y)
                                 else EP:=Point((SP.X+H.X),(SP.Y-H.X));
                      end
                      else begin
                                 if (SP.Y=Y) or (radtodeg(ArcSin(H.Y/H.X))<=22.5)
                                 then EP:=Point(X,SP.Y)
                                 else EP:=Point((SP.X+H.X),(SP.Y-H.X));
                           end;
          end;
    end
else EP:=Point(X,Y);

Khabarakh 22. Dez 2005 10:59

Re: Zeichnen einer Linie im 45° Winkel
 
Mit Delphi-Referenz durchsuchenMath.ArcTan2 kannst du dir Einiges an Fallunterscheidungen sparen.
Delphi-Quellcode:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FMiddle := Point(X, Y);
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  Angle, Length: Single;
  dX, dY: Integer;
begin
  if ssLeft in Shift then
  begin
    Image1.Canvas.FillRect(Rect(0, 0, Image1.Width, Image1.Height));
    Image1.Canvas.MoveTo(FMiddle.X, FMiddle.Y);

    if ssShift in Shift then
    begin
      dX := X - FMiddle.X;
      dY := Y - FMiddle.Y;
      Length := Sqrt(Sqr(dX) + Sqr(dY));

      // Angle auf Vielfaches von 45° runden
      Angle := Round(ArcTan2(dY, dX) / (Pi / 4)) * (Pi / 4);
      Image1.Canvas.LineTo(FMiddle.X + Round(Cos(Angle) * Length), FMiddle.Y + Round(Sin(Angle) * Length));
    end
    else
      Image1.Canvas.LineTo(X, Y);
  end;
end;


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