![]() |
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:
(SP=StartPunkt, der wird beim klick gesetzt(OnMouserDown))
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); 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) |
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
|
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. |
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); |
Re: Zeichnen einer Linie im 45° Winkel
Zitat:
Also erst mal schauen, in welchem Quadranten wir sind:
Delphi-Quellcode:
Dann anhand des Quadranten den Zielpunkt rechnen.
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; 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; |
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). |
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. |
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. |
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); |
Re: Zeichnen einer Linie im 45° Winkel
Mit
![]()
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 20:47 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