Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 11, 2025 02:51

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Berechnung ergibt manchmal -NAN
BeitragVerfasst: Sa Jul 18, 2009 14:15 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Okt 27, 2003 17:46
Beiträge: 788
Hallo...

Wie und aus welchem Grunde kann diese Berechnung manchmal NAN ergeben?

Rotate ist immer zwischen 0 und 360 daran liegt es auch nicht... und speed ist auch begrenzt...
manchmal kommt bei PlayerInfo.x und .z NAN raus...

Code:
  1.  
  2.       PlayerInfo.x := PlayerInfo.x + sin(PlayerInfo.ROTATE*pi/180) * PlayerInfo.Speed;
  3.       PlayerInfo.z := PlayerInfo.z - cos(PlayerInfo.ROTATE*pi/180) * PlayerInfo.Speed;
  4.  



Hier noch ein Teil Code:

Code:
  1.   procedure TPlayer.Aktualisieren();
  2.    var
  3.     av,ah,avh,wv,wh,wvh,cv,ch,cvh,var_1,var_2,var_3,var_4, var_nan: extended;
  4.    begin
  5.      // ### ### ### Lenkeinschlag berechnen ### ### ###
  6.  
  7.      if engine.taste.Links then
  8.      begin
  9.         PlayerInfo.TURN := PlayerInfo.TURN - 0.1*realperc;
  10.         if PlayerInfo.TURN < -1 then PlayerInfo.TURN := -1;
  11.      end else begin
  12.         if PlayerInfo.TURN < 0 then PlayerInfo.TURN := 0;
  13.      end;
  14.      if engine.taste.rechts then
  15.      begin
  16.         PlayerInfo.TURN := PlayerInfo.TURN + 0.1*realperc;
  17.         if PlayerInfo.TURN > 1 then PlayerInfo.TURN := 1;
  18.      end else begin
  19.         if PlayerInfo.TURN > 0 then PlayerInfo.TURN := 0;
  20.      end;
  21.      PlayerInfo.ROTATE := PlayerInfo.ROTATE + PlayerInfo.TURN;
  22.      if PlayerInfo.ROTATE > 360 then PlayerInfo.ROTATE := PlayerInfo.ROTATE - 360;
  23.      if PlayerInfo.ROTATE < 0 then PlayerInfo.ROTATE := PlayerInfo.ROTATE + 360;
  24.  
  25.      // ### ### ### Geschwindigkeit berechnen ### ### ###
  26.  
  27.      if engine.taste.vor then
  28.      begin
  29.       PlayerInfo.Speed := PlayerInfo.Speed + 0.01 * RealPerc;
  30.       if PlayerInfo.Speed > 0.2 then PlayerInfo.Speed := 0.2;
  31.      end else if engine.taste.zurueck then
  32.      begin
  33.       PlayerInfo.Speed := PlayerInfo.Speed - 0.01 * RealPerc;
  34.       if PlayerInfo.Speed < -0.1 then PlayerInfo.Speed := -0.1;
  35.      end else if PlayerInfo.Speed > 0 then
  36.      begin
  37.       PlayerInfo.Speed := PlayerInfo.Speed - 0.002 * RealPerc;
  38.      end else if PlayerInfo.Speed < 0 then
  39.      begin
  40.       PlayerInfo.Speed := PlayerInfo.Speed + 0.002 * RealPerc;
  41.      end;
  42.  
  43.  
  44.       PlayerInfo.x := PlayerInfo.x + sin(PlayerInfo.ROTATE*pi/180) * PlayerInfo.Speed;
  45.       PlayerInfo.z := PlayerInfo.z - cos(PlayerInfo.ROTATE*pi/180) * PlayerInfo.Speed;
  46.  
  47.       PlayerInfo.Speed := PlayerInfo.Speed - ((PlayerInfo.avh_rotate/90) * 9.81 * Realperc * 0.002);
  48.      // ### ### ### RadStellung berechnen ### ### ###
  49.  
  50.       PlayerInfo.radwinkel := PlayerInfo.radwinkel - PlayerInfo.Speed*10;
  51.  
  52.      // ### ### ### Wenn das Auto an schrägen steht, müssen die Räder enger zusammen sein... ### ### ###
  53.  
  54.        avh := cos(DEGTORAD(PlayerInfo.avh_rotate))*3.5;     //Neue "halbe Autolänge" an schrägen
  55.        //wvh := 90-RadToDeg(arctan(2 / avh));
  56.        //cvh := -3.5 / sin(DEGTORAD(wvh));
  57.  
  58.        av := cos(DEGTORAD(PlayerInfo.av_rotate))*2;     //Neue "halbe Autobreite" an schrägen
  59.        ah := cos(DEGTORAD(PlayerInfo.ah_rotate))*2;
  60.  
  61.        wv := 90-RadToDeg(arctan(avh / av));       //Dadurch den winkel und...
  62.        wh := 180-(90-RadToDeg(arctan(avh / ah)));
  63.  
  64.        cv := -avh{-3.5} / sin(DEGTORAD(90-wv));             //...die Länge für die räderpositionbrechnung berechnen
  65.        ch := -avh{-3.5} / sin(DEGTORAD(90-(180-wh)));
  66.  
  67.  
  68.      // ### ### ### Räderpositionen berechnen ### ### ###
  69.  
  70.        //rv Rechts-Vorne berechnen
  71.        PlayerInfo.rv_x := PlayerInfo.x + sin((PlayerInfo.ROTATE + wv)*pi/180) * -cv;
  72.        PlayerInfo.rv_z := PlayerInfo.z - cos((PlayerInfo.ROTATE + wv)*pi/180) * -cv;
  73.        PlayerInfo.rv_Y := engine.Landschaft.GetInterpolatedHeight(PlayerInfo.rv_X,PlayerInfo.rv_Z);
  74.        //lv Links-Vorne berechnen
  75.        PlayerInfo.lv_x := PlayerInfo.x + sin((PlayerInfo.ROTATE - wv)*pi/180) * -cv;
  76.        PlayerInfo.lv_z := PlayerInfo.z - cos((PlayerInfo.ROTATE - wv)*pi/180) * -cv;
  77.        PlayerInfo.lv_Y := engine.Landschaft.GetInterpolatedHeight(PlayerInfo.lv_X,PlayerInfo.lv_Z);
  78.        //rh Rechts-Hinten berechnen
  79.        PlayerInfo.rh_x := PlayerInfo.x + sin((PlayerInfo.ROTATE + wh)*pi/180) * -ch;
  80.        PlayerInfo.rh_z := PlayerInfo.z - cos((PlayerInfo.ROTATE + wh)*pi/180) * -ch;
  81.        PlayerInfo.rh_Y := engine.Landschaft.GetInterpolatedHeight(PlayerInfo.rh_X,PlayerInfo.rh_Z);
  82.        //lh Links-Hinten berechnen
  83.        PlayerInfo.lh_x := PlayerInfo.x + sin((PlayerInfo.ROTATE - wh)*pi/180) * -ch;
  84.        PlayerInfo.lh_z := PlayerInfo.z - cos((PlayerInfo.ROTATE - wh)*pi/180) * -ch;
  85.        PlayerInfo.lh_Y := engine.Landschaft.GetInterpolatedHeight(PlayerInfo.lh_X,PlayerInfo.lh_Z);
  86.  
  87.        PlayerInfo.Y := (PlayerInfo.rv_y + PlayerInfo.lv_y + PlayerInfo.rh_y + PlayerInfo.lh_y) / 4;
  88.  
  89.      // ### ### ### Achsen-Winkel berechnen ### ### ###
  90.        var_1 := PlayerInfo.rv_Y;
  91.        var_2 := PlayerInfo.lv_Y;
  92.        var_3 := PlayerInfo.rh_Y;
  93.        var_4 := PlayerInfo.lh_Y;
  94.        if var_1 < 0 then var_1 := -var_1;
  95.        if var_2 < 0 then var_2 := -var_2;
  96.        if var_3 < 0 then var_3 := -var_3;
  97.        if var_4 < 0 then var_4 := -var_4;
  98.  
  99.        var_1 := (var_1 + var_2)/2;
  100.        var_2 := (var_3 + var_4)/2;
  101.        if var_1 < 0 then var_1 := -var_1;
  102.        if var_2 < 0 then var_2 := -var_2;
  103.  
  104.        PlayerInfo.avh_rotate := RadToDeg(arcsin( (var_1-var_2)/7 ));
  105.        PlayerInfo.av_rotate := RadToDeg(arcsin((PlayerInfo.rv_Y - PlayerInfo.lv_Y)/4));
  106.        PlayerInfo.ah_rotate := RadToDeg(arcsin((PlayerInfo.rh_Y - PlayerInfo.lh_Y)/4));
  107.    end;

_________________
www.audi32.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 18, 2009 14:31 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
NaN kann rauskommen bei diversen ungültigen operationen (auch eine Rechnung mit NaN) und wenn ein Float nicht initialisiert wurde. Ansonsten könntest du mal versuchen, mit dem Debugger schritt für Schritt durchzugehen, wo das auftaucht - wobei vielleicht nen haufen WriteLns und ein Halt, wenn NaN auftaucht hilfreicher ist.

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 18, 2009 15:01 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Jede Operation mit NaN gibt wieder NaN. Also ich empfehle hier wie Lord Horazont die "Ausgabemethode".

Ich sehe du hast da unten arcsin verwendet. Der arcsin ist nur zwischen -1.0 und 1.0 definiert. Da du aber nur mit endlicher Genauigkeit arbeitest, kann es sein das Berechnungen dir z.B. ein ergebnis wie "1.00001" liefern. Da kommt dann natürlich NaN raus.

Eine weitere Fehlerquelle ist natürlich eine mögliche Division durch Null.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 18, 2009 16:48 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Okt 27, 2003 17:46
Beiträge: 788
ja nur wie kann ich das machen... weil ein:

if variable = NAN then

funktioniert nicht... :-/
Und das tritt immer auf wenn mein "auto" an bestimmten stellen auf der Heightmap rumfährt.
Immer wenn es zu steil am Hang steht...

Ich werde nachher mal den Source hochladen, ist noch nicht wirklich viel... aber ich finds nicht, evtl. will sich es jemand angucken...

_________________
www.audi32.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 18, 2009 16:52 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Die Funktion heißt "IsNAN". Erwartet einen Float-Wert und gibt einen Boolean zurück.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 19, 2009 09:59 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
Code:
  1.        av := cos(DEGTORAD(PlayerInfo.av_rotate))*2;     //Neue "halbe Autobreite" an schrägen
  2.        ah := cos(DEGTORAD(PlayerInfo.ah_rotate))*2;
  3.  
  4.        wv := 90-RadToDeg(arctan(avh / av));       //Dadurch den winkel und...
  5.        wh := 180-(90-RadToDeg(arctan(avh / ah)));

av und ah können je nach rotation null werden...
Einfach den Grenzwert pi/2 für av=ah=0 per hand rein programmieren.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 19, 2009 10:32 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Okt 27, 2003 17:46
Beiträge: 788
Ja durch die Funktion isNAN kam ich jetzt auch bis dahin und sah dass da was im argen ist...
Allerdings muss ich erst noch gucken was :-/ werde mich dann wieder melden.
isNAN hat auf jeden fall schon sehr geholfen :-)

_________________
www.audi32.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 19, 2009 12:39 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Okt 27, 2003 17:46
Beiträge: 788
Also ich habe hier jetzt mal den Source angehängt.
Irgendwie habe ich das problem, dass
Code:
  1. arcsin(4.1/4)

und zwar dadurch, dass er die "Breite" des autos falsch berechnet. Diese wird immer neu berechnet, dass es wenn er am Berg steht nicht doppelt so breit aussieht zB.
Aber ihr könnt euch ja das mal angucken damit ihr wisst von was ich rede.
Stellt euch einfach mal am Berg schräg hin (Linke Seite - Rechts Seite) muss mehr als 45° sein...
Diese gepostete berechnung ist in 'un_player'

Ich könnte zwar auch newton nehmen, aber ich wollte es halt mal selbst probieren und machen.

http://www.audi32.de/projekte/fehler.rar

_________________
www.audi32.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 19, 2009 13:44 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
Das Argument vom arcsin muß kleiner gleich 1 sein


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 19, 2009 13:50 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
genauer:
Coolcat hat geschrieben:
Der arcsin ist nur zwischen -1.0 und 1.0 definiert.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 19, 2009 13:57 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Okt 27, 2003 17:46
Beiträge: 788
ja nur ich weiß nicht warum es überhaupt dazu kommen kann das es auf 4,1 / 4 kommt.
Naja ich glaub ich muss halt noch bisschen suchen.

_________________
www.audi32.de


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 14 Queries | GZIP : On ]