Winkel zu einem Punkt bekommen

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Winkel zu einem Punkt bekommen

Beitrag von Josef Sniatecki »

Hier ist eine Funktion von mir, die einen Winkel von einem Punkt zu einem
anderen Punkt zurückgibt. Dadurch kann man z.B. erkennen, im welchen
Winkel die Maus von einem bestimmten Punkt (z.B. der Spieler oder eine
Waffe) zeigt.

Hier ist die Prozedur:

Code: Alles auswählen

Procedure.f WinkelZu(StartX.f,StartY.f,EndX.f,EndY.f)
  ;EndX Und EndY ist der Vektor zu den der Winkel von
  ;StartX und StartY zeigen soll.
 
  Protected Angle.f ;Der gesuchte Winkel.
  Protected XDistance.f ;Der Abstand zwischen StartX und EndX.
  Protected YDistance.f ;Das Gleicher für StartY und EndY.
  Protected Distance.f ;Hypotenuse von X- und YDistance.
 
  XDistance=EndX-StartX
  YDistance=EndY-StartY
  Distance=Sqr(XDistance*XDistance+YDistance*YDistance)
 
  ;Nun kommt das wichtigste:
  Angle=ACos(XDistance/Distance)*57.295776
 
  If StartY<EndY : Angle=360-Angle : EndIf
  ProcedureReturn Angle
EndProcedure
Der Rückgabewert passt sich dem Koordinatensystem des
Bildschirmes an.

Hier ist ein Beispiel code:

Code: Alles auswählen

Debug WinkelZu(0,0,100,100)
Nun wird der Winkel vom Ursprung des Koordinatensystem zum
Punkt (100|100) angezeigt. Die Ausgabe wird 45° und nicht 315° sein;
denn das Koordinatensystem des Bildschirmes verläuft nach unten rechts
und nicht nach oben rechts.
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

Nun wird der Winkel vom Ursprung des Koordinatensystem zum
Punkt (100|100) angezeigt. Die Ausgabe wird 45° und nicht 315° sein;
denn das Koordinatensystem des Bildschirmes verläuft nach unten rechts
und nicht nach oben rechts.
die Ausgabe des Winkels sollte analog zum Drehwinkel der Befehle wie RotateSprite3D sein,
das macht das Ergebnis besser verarbeitbar... ;)
wenn ich mich recht entsinne, bedeutet das, dass die drehrichtung im Uhrzeigersinn (rechtshändig, mathematisch negativ) ist,
und die Null-Grad-Richtung "oben" ist, also in negativer y-Richtung verläuft.
die ausgabe sollte also 135° sein!

sorry, es geht nicht darum, mathematisch korrekt zu sein, sondern programmtechnisch kompatibel.
mathematisch wäre die Nullrichtung wohl rechts, und die drehrichtung gegen den uhrzeigersinn,
dann müßte das ergebnis -45°, bzw. 315° lauten....
aber wie gesagt, darum gehts nicht.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

@Kaeru Gaman

die 0° muss nach Rechts zeigen, das geht schon aus den Trigonometrischen Funktionen hervor, und 90° nach unten:

x = Cos(Winkel)
y = Sin(Winkel)

Das heißt
Winkel = 0 --> x=1;y=0 also nach rechts
Winkel = 90 --> x=0;y=1 also nach unten
Winkel = 180 --> x=-1;y=0 also nach links
Winkel = 270 --> x=0;y=-1 also nach oben

Die Procedure ist also ok

Desweiteren möchte ich anmerken das es immer etwas zeitsparender ist wenn man mit dem Tangens Arbeitet:

Code: Alles auswählen

; Berechnet den Winkel im Bogenmaß
Procedure.d Angle(x.d,y.d)
 Protected Angle.d
 Angle = ATan(y/x)
 If x < 0 : Angle + #PI : EndIf 
 ProcedureReturn Angle
EndProcedure
Das erspart das zeitintensive Wurzelziehen der Hypotenuse
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

aber es geht um programmtechnische Kompatibilität!

bis zur 3.94 oder so war der Drehwinkel für RotateSprite3D auch - mathematisch korrekter - Rechts die Nullrichtung.
das hat dazu geführt, dass man nach einem Rotate-0°-Befehl das Sprite um 90° gedreht bekam.
das wurde also geändert, damit die 0°-Drehung einen unveränderten Winkel bedeutet - die Hauptrichtung aufwärts, wie die Ursprungsmatrix es vorgibt.

das war und ist ganz einfach programmtechnisch sinnvoll, auch wenn es mathematisch mangelhaft scheint.

genauso sollte sich die Drehrichtung an den vorhandenen Befehlen ausrichten,
in diesem falle im Uhrzeigersinn also mathematisch negativ.

das ist alles eine Frage der Interpretation.
Rechtshändige Koordinatensysteme haben die selbe Daseinsberechtigung, wie Linkshändige,
und welche Richtung die Priorität erhält, also x-positiv, wie karthesisch richtig,
oder y-negativ, wie matrixbedingt logisch und richtig, ist wieder Geschmackssache.

letztendlich zählt für die Anwendbarkeit einer Routine eher,
ob sie kompatibel zu allen anderen Befehlen ist,
oder ob man aufwendig umrechnen muss.

eine mathematisch korrekte routine ist ja nicht "falsch", sie ist nur umständlich,
weil ich erst -90° und dann *-1 rechnen muss, damit ich ihr Ergebnis verwenden kann,
um es in RotateSprite3D einsetzen zu können.

PS:
ich weiß nicht, wie das für Routinen für 3D aussieht....
ich kenn OGRE nicht so gut, aber in POV ist das Koordinatensystem linkshändig und z-folgend,
d.h. x ist von links nach rechts,
y ist von unten nach oben (gegensätzlich zu standard-2D),
und z ist vom Betrachter weg!
ich meine mich zu erinnern, dass in OGRE das y waagerecht ist, und z nach oben...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

JO aber genau diese Änderung an RotateSprite ärgert mich bis heute!

Es ist wohl benutzer abhängig welches System man nutz, und welchen Befehl man dann anpasst.

Ich habe zB lieber meine Bilder angepasst und an das Rotate angepasst.
Das liegt aber daran das ich sehr viel cos und sin arbeite, und ich es einfach nicht haben kann wenn der sin für x "missbraucht wird"

das mit den 3D-Koordinaten verwirrt mich bis heute, da in der Mathematik ja x nach rechts, y zu mir und z nach oben zeigt.

Mal sehn was Josef Sniatecki macht ...

PS: Im Prinzip kann man ja auch einfach die Bilder anders rum zeichnen :wink:
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

STARGÅTE hat geschrieben::wink: nenhciez mur sredna redliB eid hcafnie hcua aj nam nnak piznirP mI :SP
:mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> JO aber genau diese Änderung an RotateSprite ärgert mich bis heute!
die hat mir eher gut gefallen, weil eine 0-Drehung das Ursprungsbild abbildet,
anders als vorher ein bereits um 90° gedrehtes Derivat.

> das mit den 3D-Koordinaten verwirrt mich bis heute, da in der Mathematik ja x nach rechts, y zu mir und z nach oben zeigt.
lies dir mal in der POV-Dokumentation die Erklärungen (mit Bildern) zum linkshändigen Koordinatensystem durch,
danach bleiben keine Fragen mehr offen, danach kannst du jedes individuelle
Koordinatensystem richtig anwenden, wenn du seine Klassifizierung kennst.

[offtopic]
das erinnert mich an Orson Scott Cards Erzählungen zur Orientierung im freien Raum....
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Falscher Winkel

Beitrag von Josef Sniatecki »

Ich habe auch oft gemerkt, dass bei der Anwendung von "RotateSprite3D"
immer der Winkel für das Koordinatensystem "nach oben rechts"
genutzt wird.
Selber nutze ich jedoch diesen Befehl kaum. Ich mache einfach den Winkel
minus 90° und schon passt der Parameter für "RotateSprite3D".

Tortzdem sollte man den Befehl "RotateSprite3D" an dem Koordinatensystem
des Bildschirmes anpassen.
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

Kaeru Gaman hat geschrieben:> JO aber genau diese Änderung an RotateSprite ärgert mich bis heute!
die hat mir eher gut gefallen, weil eine 0-Drehung das Ursprungsbild abbildet,
anders als vorher ein bereits um 90° gedrehtes Derivat.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Beitrag von Josef Sniatecki »

Dieser Code ist auch noch möglich:

Code: Alles auswählen

Procedure.f WinkelZu(StartX.f,StartY.f,EndX.f,EndY.f)
  ;EndX Und EndY ist der Vektor zu den der Winkel von
  ;StartX und StartY zeigen soll.
 
  Protected Angle.f ;Der gesuchte Winkel.
  Protected XDistance.f ;Der Abstand zwischen StartX und EndX.
  Protected YDistance.f ;Das Gleicher für StartY und EndY.
 
  XDistance=EndX-StartX
  YDistance=EndY-StartY
 
  ;Nun kommt das wichtigste:
  Angle=ATan(XDistance/YDistance)*57.295776+270
 
  If StartY<EndY : Angle=Angle-180 : EndIf
  ProcedureReturn Angle
EndProcedure
Hier wird genauso ein angepasster Winkel zum Bildschirmkoordinatensystem
zurückgegeben. Die Schnelligkeit von diesem Befehl unterscheidet
sich kaum von ersten aus diesem Thema.
Zuletzt geändert von Josef Sniatecki am 08.06.2008 17:18, insgesamt 1-mal geändert.
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Antworten