2 Prozeduren für 2D-Spiele - Winkel

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
MLK
Beiträge: 267
Registriert: 01.11.2004 13:17
Wohnort: Hamburg

Beitrag von MLK »

stimmt. und wenn, wie ich schrieb, der code an sich fehlerhaft ist, dann war er es schon vorher. da gibts auch nix zu testen.
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

so, ihr matheasss :

Naturlich kann man eine sehr hohe genauigkeit nehmen, aber:
-Float zahlen sind begrentzt
-bei einer hohen genauigkeit daert das berechnen der werte länger !
:wink:
Wie kann man den Atan in asm schreiben ?
Danke !
Zuletzt geändert von Robert Wünsche am 12.11.2004 16:31, insgesamt 1-mal geändert.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ich meinte auch nicht, DoubleFloat zu benutzen, nur die genauigkeit der Float ausnutzen....

in dem ich schreibe:

Code: Alles auswählen

pi.f    =  3.141592654
pi180.f = 57.29577951
ich definier diese gern als globals vor, um sie dann in allen procs, wo ich sie brauche zu benutzen... spricht da performance-mässig was gegen ?
Zuletzt geändert von Kaeru Gaman am 12.11.2004 23:36, insgesamt 2-mal geändert.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

hach ja, diese fehler !
:roll: :wink: !
Danke !
Natürlich nehms ich locker :) .
Ich hab das hier gelernt :wink:.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Was ich mal sagen wollte:
Meine Procedure liefert die genaueren Werte zurück. Teste doch mal dies hier:

Code: Alles auswählen

;und weils so schön ist noch nics 
; Ermittelt den Winkel zwischen zwei Punkten 
Procedure.f Object_GetAngle_Points(x1.f, y1.f, x2.f, y2.f) 
  Protected w.f 
  w = ATan((y2 - y1) / (x2 - x1)) * 57.295776 
  If x2 < x1 
    w = 180 + w 
  EndIf 
  If w < 0 : w + 360 : EndIf 
  If w > 360 : w - 360 : EndIf 
  
  ProcedureReturn w 
EndProcedure 

;und meiner ! 
;Routine zum bestimmen des Winkels 
;x2 ist der punkt, der die mitte ist und von diesem die gradzahl bestimmt wird! 
;y2 
Procedure.f G_2d_Winkel (p_x1.f,p_y1.f,p_x2.f,p_y2.f) 
  grad.f =(1/((p_y1-p_y2)/(p_x1-p_x2))) 
  grad.f = ATan(grad.f)*57.29 
  ProcedureReturn grad.f 
EndProcedure 

x = 1
y = 1

Debug Object_GetAngle_Points(0, 0, x, y)
Debug G_2d_Winkel(x, y, 0, 0)
Bei mir kommt korrekt 45° heraus, bei dir 44.995464°. Komische Zahl. Außerdem beginnt bei mir der Winkel mathematisch korrekt wie im Einheitskreis. Das heißt der Winkel von P(0|0) nach Q(1|0) beträgt genau 0° und es geht gegen den Uhrzeigersinn weiter, während das bei dir 89.990929° sind und die Winkel im Uhrzeigersinn gehen. Also auch wieder ungenau und mathematisch unkorrekt, aber das ist ja wiederum definitionssache und deswegen eigentlich nicht erwähnenswert. Weiterhin kommen bei dir auch negative Winkel heraus, was natürlich nicht weiter schlimm wäre, wenn es nicht passieren könnte, dass der Programmierer und Anwender dieser Procedure sein restliches Programm nur auf Winkel >= 0° und < 360° ausgelegt hat oder ähnliches.

Nochwas, was ich nicht von dir erwartet hätte: Wenn man von einem Bruch den Kehrwert nimmt, braucht man einfach nur Zähler und Nenner zu vertauschen, was bedeutet, dass du aus der Formel '[c](1 / ((p_y1 - p_y2) / (p_x1 - p_x2)))[/c] auch einfach '[c](p_x1 - p_x2) / (p_y1 - p_y2)[/c]' machen kannst, wodurch deine Procedure wieder schneller werden würde.

Ich habe gerade noch einen Fehler entdeckt, den ich bei mir ja auch beheben musste, nämlich wenn die x-Koordinaten zueinander verschiedene Größen habe, also mal x1 > x2 oder x1 < x2 ist. So ist nämlich [c]Debug G_2d_Winkel(1, 1, 0, 0)[/c] und [c]Debug G_2d_Winkel(-1, -1, 0, 0)[/c] bei dir das gleiche.

Aber genug dazu. Glaub mir einfach oder seh es ein, dass meine Procedure die bessere ist.
Kristel
Beiträge: 72
Registriert: 30.08.2004 00:17

Beitrag von Kristel »

*sichauchmaleinmisch*
NicTheQuick hat geschrieben:Nochwas, was ich nicht von dir erwartet hätte: Wenn man von einem Bruch den Kehrwert nimmt, braucht man einfach nur Zähler und Nenner zu vertauschen, was bedeutet, dass du aus der Formel '[c](1 / ((p_y1 - p_y2) / (p_x1 - p_x2)))[/c] auch einfach '[c](p_x1 - p_x2) / (p_y1 - p_y2)[/c]' machen kannst, wodurch deine Procedure wieder schneller werden würde.
NicTheQuick hat geschrieben:

Code: Alles auswählen

grad.f =(1/((p_y1-p_y2)/(p_x1-p_x2)))
*hüstel* /:->
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

danke fürs bugfixing !
Find ich nett !

IQ frage:
Warum hab ich p_?? genommen ?
hääää ?

gut jetzt !
Das mit 44, blaaaaaaaaa ist nur ne geringe abweichung aufgrund meines ungenauen zahlenwertes (57.??).
Was zu beachten ist:
Ich hab mir die procedure duch überlegung ausgeknobelt und du ?
Das ist schon absicht, dass sie mal -179 ... +179 liefert, wenn ich es umstellen würde() dann würde() meine engine nicht mehr richtig funktionieren !
Das mit dem speed, ich glaub, ich schulde dir was !
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@Robert Wünsche: Du schuldest mir was? Wie soll ich das verstehen? :? Naja...
Natürlich, negative Winkel gibt es schon, sorgen bei mir aber meistens für Verwirrung, wenn ich mir davon die Kurve vorstellen will. :wink: Also ist es Definitionssache.
Ich habe mir die Procedure auch selbst hergeleitet. Danach googeln braucht man da nun wirklich nicht. Man muss nur wissen, wie man von einer Steigung auf einen Winkel kommt und welche Besonderheiten das ganze hat, z.B. dass [c]tan(alpha) = tan(alpha + Pi)[/c] ist.
Kristel hat geschrieben:
NicTheQuick hat geschrieben:

Code: Alles auswählen

grad.f =(1/((p_y1-p_y2)/(p_x1-p_x2)))
*hüstel* /:->
Dieser Ausschnitt ist nicht aus meiner Procedure, sondern von Roberts Version der Procedure, auch wenn darüber steht '[c];und meiner ![/c]'. Ich habe den Code auf der vorherigen Seite von Robert kopiert. Dieses '[c]meiner[/c]' bezieht sich also auf Robert und nicht auf mich.
Oder habe ich jetzt überhaupt nicht verstanden, was du gemeint hast? :?
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

achso :| ja na klar.
Die klammer !
ist schon behoben !
Das sind doch nur par nanosekunden !
:)
Noch was ?

@nic:
"ich schulde dir noch was" -->
danke für die verbesserungsvorschläge in meiner protzedur !
--> hoffentlich kann ich mich revonggiren (oder so).

OK ?
Robert Wünsche
Beiträge: 243
Registriert: 29.08.2004 12:46
Wohnort: Irgendwo im nirgendwo
Kontaktdaten:

Beitrag von Robert Wünsche »

so :mrgreen:
Das no plus ultra (das orginal ist nur in meiner engine enthalten :mrgreen: :
trotzdem zeigs ich mal:

Code: Alles auswählen

Procedure.f G_2d_Winkel (p_x1.f,p_y1.f,p_x2.f,p_y2.f) 
  ProcedureReturn ATan(p_x1 - p_x2 / (p_y1 - p_y2))*57.295776
EndProcedure 
danke nic :wink: , erhältst später von mir vielleicht noch einen kleinen bonus.
Antworten