Mathematisches problem

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
kob
Beiträge: 116
Registriert: 01.01.2008 02:02
Computerausstattung: 2x 2.4 GHz Amd Cpu | Geforce N9600GT OC |2.5GB Ram |Windows 7 Ultimate
Wohnort: Fulda

Mathematisches problem

Beitrag von kob »

Hallo ich habe mal wieder ein problem mit der mathemathik in einem programm.
Ich habe zwei punkte , nun möchte ich den winkel zwischen den 2 punkten herausbekommen.
an punkt a befundet sich ein 3d sprite , das dan in richtung des punktes b kucken soll.
ich habe schon bei google gekukt , auch formeln gefunden , doch die funktionieren nicht richtig ,
immer wen ich einmal herumgehe , drehr er sich nur um 180 grad und nicht um 360 grad , so wie er es tun sollte.
besagte formel lautet : w=atan( (y2-y1) / (x2-x2) )

es währe net , wen mir jemand helfen könnte , habe langsam keine lust mehr auf trigonometrie
Wenn sie weich werden bringt Pandora sie um und scheisst sie aus bevor sie irgend etwas merken.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Mathematisches problem

Beitrag von STARGÅTE »

vorab, es gibt keinen Winkel zwischen zwei Punkten ^^

Du meinst wo die Gerade duch die beiden Punkte und die Horizontgerade dazwischen der winkel:

das Problem ist, das ATan ekin Vollkreis zurück geben kann, sonden nur n Halbkreis, also:

Code: Alles auswählen

 ; Berechnet den Winkel
 Procedure.f Angle(x.f,y.f)
  Protected Angle.f
  Angle = ATan(y/x)
  If x < 0 : Angle + #PI : EndIf 
  ProcedureReturn Angle
 EndProcedure
Das Input wäre dann:

Code: Alles auswählen

w.f = Angle(x2-x2,y2-y1)
Dabei ist w im Intervall [-#PI/2,3*#PI/2]
wenn du das in Grad haben willst:

Code: Alles auswählen

w.f = Angle(x2-x2,y2-y1)*180/#PI
Bei Sprite 3D ist es zum glück egal ob du dann als Winkel -45° hast oder 315°, es ist die selbe drehung.
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
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: Mathematisches problem

Beitrag von TomS »

STARGÅTE hat geschrieben:w.f = Angle(x2-x2,y2-y1)
Meinst du nicht x2-x1?

Ich check das was nicht:
Wenn die X-Koordinate beider Punkte gleich ist, dann ist der Winkel ja +-90°

Aber X2-X1 ist doch dann 0. Wie kann denn Atan(y/0) ein brauchbares Ergebnis liefern?
Und vor allem, warum stürzt das Programm nicht ab und gibt 'nen Fehler aus?

Code: Alles auswählen

Debug 1/0
-> Fehler in Form von Infobox

Code: Alles auswählen

a=0
Debug 1/a
-> Fehler in Form von Compiler-Nachricht am unteren Rand der IDE
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Mathematisches problem

Beitrag von STARGÅTE »

Ja

Code: Alles auswählen

w.f = Angle(x2-x1,y2-y1)
hab das alsche von oben kopiert ^^

debug 1/0 ist verboten, aber 1/0.0 geht:

Code: Alles auswählen

x.f =0.0
Debug 1/x
Debug Tan(1/x)*180/#PI
und da der ATan für +Unendlich bzw -Unendlich wohl definiert ist, nämlich +PI/2 oder -PI/2 kommt auch das richtige ergebnis raus.

Eine kontrolle auf x=0 ist also unnötig!
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
kob
Beiträge: 116
Registriert: 01.01.2008 02:02
Computerausstattung: 2x 2.4 GHz Amd Cpu | Geforce N9600GT OC |2.5GB Ram |Windows 7 Ultimate
Wohnort: Fulda

Re: Mathematisches problem

Beitrag von kob »

:allright: THX :allright:

Leuft alles.
Hatte glat vergessen , das die steigung ja die tangente ist.
hatte unser mathelehrer mal in seiner matheextase erwähnt [ca12 Tafeln
pro stunde und ca 99.8% Fehlerquote]
jedenfals danke hast mein kleinen shooter gerettet :praise:
Wenn sie weich werden bringt Pandora sie um und scheisst sie aus bevor sie irgend etwas merken.
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: Mathematisches problem

Beitrag von TomS »

Aha.
Ist das dann eine Art Sicherheitsmechanismus von PB. Dass 0.0 quasi als Lim(x->0) angesehen wird?
Dann ist das Ergebnis natürlich logisch.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Mathematisches problem

Beitrag von STARGÅTE »

Jo.

Der Ausdruck 0/0 ist auch in PB nicht definiert: -1.#IND

Code: Alles auswählen

b.f = 0.0
b / 0.0
Debug b
Aber Unendlich ist sehr wohl ein Wert den PB benutzen kann, wobei die Operatioen eingeschrängt sind.

Code: Alles auswählen

a.f = -1
a / 0.0
Debug a
Debug 1/a
Debug Pow(2,a)
Man kommt die richtigen ergebnisse.
Aber auch Infinity/Infinity ist in PB nicht definiert.
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
Little John

Re: Mathematisches problem

Beitrag von Little John »

STARGÅTE hat geschrieben:da der ATan für +Unendlich bzw -Unendlich wohl definiert ist, nämlich +PI/2 oder -PI/2
Sorry, das stimmt nicht.

Code: Alles auswählen

arctan(x) ist definiert für -unendlich < x < +unendlich
Man beachte, dass da beide Male < steht, und nicht <=.

Das liegt daran, dass die Tangensfunktion wegen

Code: Alles auswählen

tan(x) = sin(x)/cos(x)
nur dort definiert ist, wo die Kosinusfunktion keine Nullstelle hat, also nur für

Code: Alles auswählen

x <> (2*z + 1) * Pi/2  [wobei z eine beliebige ganze Zahl ist]
Anders ausgedrückt: Diejenigen x-Werte, die ein ungerades Vielfaches von Pi/2 sind, gehören nicht zur Definitionsmenge von tan(x) -- damit gehören sie auch nicht zur Wertemenge von arctan(x). Das sind z.B.

Code: Alles auswählen

..., -5*Pi/2, -3*Pi/2, -Pi/2, +Pi/2, 3*Pi/2, 5*Pi/2, ...
Gruß, Little John
Benutzeravatar
kob
Beiträge: 116
Registriert: 01.01.2008 02:02
Computerausstattung: 2x 2.4 GHz Amd Cpu | Geforce N9600GT OC |2.5GB Ram |Windows 7 Ultimate
Wohnort: Fulda

Beitrag von kob »

Das mit dem unentlichen funktioniert nicht.
man kan zwar bestimt programmes schreiben , die
näherungsweise mit unändlich rechnen können ,
doch nie mit unentlich direkt :
X = #UNENTLICH

Das geht nicht , da ein computer nur entliche zahlen berechnen kan , da
er nur ein entlichen speicher hat. das ist aber ein interessantes gebiet , dazu
gibt es ja sogar beispiele . die dinger heißen fraktale und sind im prinzip Math
formeln grafisch argestellt. Weil man in formeln belibige werte einsätzen kann
müssen diese aber begräntszt werden. [Höre mich jetzt an wie bein DV Lehrer >_< ]

will jetzt kein sermon halten , aber ist euch schonmal aufgefallen , das Unentlich und null
vielg gemeinsam haben ?

wichtig ist hat bei komplexen rechnungen , das man den zahlenbereich im entliche bereich hält.
Wenn sie weich werden bringt Pandora sie um und scheisst sie aus bevor sie irgend etwas merken.
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: Mathematisches problem

Beitrag von DarkDragon »

TomS hat geschrieben:Aha.
Ist das dann eine Art Sicherheitsmechanismus von PB. Dass 0.0 quasi als Lim(x->0) angesehen wird?
Dann ist das Ergebnis natürlich logisch.
Das ist nicht unbedingt von PB so gemacht. Das Programm kann der FPU sagen ob es diese speziellen Fließkommazahlwerte annehmen kann oder ob es einen Interrupt auslösen soll soweit ich weiß. Und ich bin der Meinung, dass das so wie es jetzt ist am idealsten ist. Immerhin gibt es Probleme wie diese:

Code: Alles auswählen

; ...

maximum = -infinity ; Müsste man in PB vielleicht anders machen, in Java kenn ich das so
ForEach value()
  If value() > maximum ; das geht tatsächlich und ist offiziell so!
    maximum = value()
  EndIf
Next
die ohne das Feature so aussehen würden:

Code: Alles auswählen

; ...

FirstElement(value())
maximum = value()

ForEach value()
  If value() > maximum
    maximum = value()
  EndIf
Next
@kob: Es "endet" und es "entet" nicht.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Antworten