Seite 1 von 2

Mathematisches problem

Verfasst: 16.10.2009 13:26
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

Re: Mathematisches problem

Verfasst: 16.10.2009 15:20
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.

Re: Mathematisches problem

Verfasst: 16.10.2009 15:44
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

Re: Mathematisches problem

Verfasst: 16.10.2009 16:31
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!

Re: Mathematisches problem

Verfasst: 16.10.2009 16:59
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:

Re: Mathematisches problem

Verfasst: 16.10.2009 17:02
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.

Re: Mathematisches problem

Verfasst: 16.10.2009 17:11
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.

Re: Mathematisches problem

Verfasst: 16.10.2009 17:55
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

Verfasst: 16.10.2009 18:46
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.

Re: Mathematisches problem

Verfasst: 16.10.2009 19:45
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.