IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Resultat inatendu: "NaN"


Sujet :

avec Java

  1. #1
    Membre du Club
    Homme Profil pro
    Chercheur d'Emploi
    Inscrit en
    Février 2017
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'Emploi

    Informations forums :
    Inscription : Février 2017
    Messages : 86
    Points : 65
    Points
    65
    Par défaut Resultat inatendu: "NaN"
    Bonjour a tous.

    Toujours entrain d'essayer de retranscrire la methode DoMath() de ce github en c#: https://github.com/Whiplash141/Whips...or/MainForm.cs en Java.

    Je pensais être arriver au bout sauf que le resultat est "NaN".. j'ai beau chercher dans tous les sens je ne comprends vraiment pas pourquoi:

    MainActivity:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    import java.lang.Math; 
    import java.util.List;
    import java.util.LinkedList;
     
    public class MainActivity {
     
     
      public static void main(String[] args) {
     
     
        double timeToSimulate = 8;
        double timeStep = 0.0001; // seconds
        double gravity = 9.81; // m/s/s
        double muzzleVelocity = 950; // m/s
        double zeroingRange = 254;// m
        double targetRange = 500; // m
        double dragForce = 0.00095;
        double mildots;
     
        List<Vecteur2> positionList = new LinkedList<Vecteur2>();
        List<Vecteur2> rotatedPositionList = new LinkedList<Vecteur2>();
     
     
            Vecteur2 velocityVector = new Vecteur2(muzzleVelocity, 0);
            Vecteur2 positionVector = new Vecteur2(0, 0);
            positionList.add(positionVector);
     
     
            for (double t = 0; t <= timeToSimulate; t += timeStep) {
                double frictionAcceleration = dragForce * velocityVector.LengthSquared();
     
                //compute total acceleration on the bullet
                Vecteur2 accelerationVector = Vecteur2.Normalize(velocityVector).negatif().multiplie(frictionAcceleration).plus(new Vecteur2(0, -gravity));
     
                //d = 1/2*a*t^2 + vi*t + d0;
                positionVector = positionVector.plus(velocityVector.multiplie(timeStep).plus(accelerationVector.multiplie(1/2).multiplie(timeStep).multiplie(timeStep)));
                positionList.add(positionVector);
     
                //vf = vi + at
                velocityVector = velocityVector.plus(accelerationVector.multiplie(timeStep));
            }
     
            //Solve for zeroing position
            Vecteur2 zeroingPosition = new Vecteur2(0, 0);
            double smallestDistance = 100000;
            for (int i = 0; i < positionList.size(); i++) { //Erreure possible: size() ici remplace Count en c#
                Vecteur2 thisPos = positionList.get(i);
     
                double distanceFromOrigin = thisPos != Vecteur2.Zero() ? thisPos.Length() : 0f;
     
                double thisDistance = Math.abs(distanceFromOrigin - zeroingRange);
     
                if (thisDistance < smallestDistance) {
                    zeroingPosition = thisPos;
                    smallestDistance = thisDistance;
                }
            }
     
            //Get elevation angle for zeroing
            double zeroingElevationAngle = zeroingPosition != Vecteur2.Zero() ? Math.atan(zeroingPosition.y / -zeroingPosition.x) : 0.0;
            double cos = (double) Math.cos(zeroingElevationAngle);
            double sin = (double) Math.sin(zeroingElevationAngle);
     
            //Create rotation matrix (matricies are transposed from math conventions)
            Matrix3x2Perso rotationMatrix = new Matrix3x2Perso();
            rotationMatrix.m11 = cos;
            rotationMatrix.m12 = sin;
            rotationMatrix.m21 = -sin;
            rotationMatrix.m22 = cos;
     
            //Rotate all of our values
            for (int i = 0; i < positionList.size(); i++) { // 3ème erreur possible avec size() qui remplace Count
                rotatedPositionList.add(Vecteur2.TransformNormal(positionList.get(i), rotationMatrix));
            }
     
            //Solve for desired range
            Vecteur2 targetPos = new Vecteur2(0, 0);
            smallestDistance = 100000;
            for (int i = 0; i < rotatedPositionList.size(); i++) { ///2eme erreur possible avec size() qui remplace Count
                Vecteur2 thisPos = rotatedPositionList.get(i);
     
                double thisDistance = Math.abs(thisPos.x - targetRange);
     
                if (thisDistance < smallestDistance) {
                    targetPos = thisPos;
                    smallestDistance = thisDistance;
                }
            }
     
            mildots = (double) Math.atan(-targetPos.y / targetPos.x) * 1000f;
            String direction = mildots > 0 ? "above" : "below";
     
            System.out.println(direction+" "+mildots);
     
        }
    }
    Vecteur2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    import java.lang.Math;
     
    public class Vecteur2 {
     
        double x;
        double y;
     
        private static Vecteur2 zeroVector = new Vecteur2(0f, 0f);
     
        public Vecteur2(double dX, double dY) {
            x = dX;
            y = dY;
        }
     
        public double LengthSquared() {
            return Math.pow(x, 2) + Math.pow(y, 2);
        }
     
        public static Vecteur2 TransformNormal(Vecteur2 normal, Matrix3x2Perso matrix) {
            normal.x = (normal.x * matrix.m11) + (normal.y * matrix.m21);
            normal.y = (normal.x * matrix.m12) + (normal.y * matrix.m22);
            return normal;
        }
     
        public static Vecteur2 Normalize(Vecteur2 value) {
            double val = 1.0f / (double) Math.sqrt((value.x * value.x) + (value.y * value.y));
            value.x *= val;
            value.y *= val;
            return value;
        }
     
        public static Vecteur2 Zero()
        {
            return zeroVector;
        }
     
        public double Length()
        {
            return (double)Math.sqrt((x * x) + (y * y));
        }
        public Vecteur2 negatif()
        {
            this.x = -this.x;
            this.y = -this.y;
            return this;
        }
     
        public Vecteur2 multiplie(Vecteur2 scaleFactor)
        {
            this.x *= scaleFactor.x;
            this.y *= scaleFactor.y;
            return this;
        }
     
        public Vecteur2 multiplie(double scaleFactor)
        {
            this.x *= scaleFactor;
            this.y *= scaleFactor;
            return this;
        }
        public Vecteur2 plus(Vecteur2 value2)
        {
            this.x += value2.x;
            this.y += value2.y;
            return this;
        }
        public Vecteur2 plus(double value2)
        {
            this.x += value2;
            this.y += value2;
            return this;
        }
     
     
    }
    Matrix3x2Perso
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Matrix3x2Perso {
        double m11 = 0;
        double m12 = 0;
        double m21 = 0;
        double m22 = 0;
        double m31 = 0;
        double m32 = 0;
     
        public Matrix3x2Perso(){
        }
    }

  2. #2
    Membre confirmé
    Avatar de provirus
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2009
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2009
    Messages : 248
    Points : 580
    Points
    580
    Par défaut
    Bonjour,

    C'est un gros code, alors ça aiderait de savoir qu'elle ligne cause le NaN.

    Merci

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    +1 Affiche tes résultats intermédiaires au fur et à mesure pour voir quand tu obtiens NaN. Typiquement, tu récupèrera un NaN sur une division par zéro ou en appelant Math.Sqrt sur une valeur négative.

    edit: vu que tes méthodes multiplie, negatif etc modifient systématiquement le vecteur de départ plutot que d'en créer un nouveau, vu que tu bourrine bien la gueule à ton velocityVector dans la boucle, il me semble qu'il tends rapidement vers 0. Vu que t'as 80.000 tours de boucles, tu va vite arriver à un vecteur nul, que tu va essayer de normalizer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
                //velocityVector = 950;0
                double frictionAcceleration = dragForce * velocityVector.LengthSquared(); //857.350
     
     
                //compute total acceleration on the bullet
                Vecteur2 accelerationVector = Vecteur2.Normalize(velocityVector) // 1;0
                            .negatif()  // -1;0
                            .multiplie(frictionAcceleration)  //857.350;0
                            .plus(new Vecteur2(0, -gravity));   //857.350;-9.81
     
                //d = 1/2*a*t^2 + vi*t + d0;
                positionVector = positionVector.plus(
                             velocityVector.multiplie(timeStep)  //0.085735;-0.000981
                             .plus(
                                  accelerationVector.multiplie(1/2)  //0.0428675;-0.0004905
                                  .multiplie(timeStep) //0.00000428675;-0.00000004905
                                  .multiplie(timeStep)//0.00000000428675;-0.00000000004905
                             ));
     
    // j'arrête là, tu vois déjà la valeur ridiculement petite que commence à prendre ton vecteur veolcity (qui est le même que acceleration au passage, c'est la même instance que tu te trimbale).

  4. #4
    Membre du Club
    Homme Profil pro
    Chercheur d'Emploi
    Inscrit en
    Février 2017
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'Emploi

    Informations forums :
    Inscription : Février 2017
    Messages : 86
    Points : 65
    Points
    65
    Par défaut
    J'ai enfin reussi !

    le problème venait des methodes d'operation dans la classe Vecteur2. Elles changeaient les variables utilisées pour les operations au lieu de juste s'en servir pour le resultat.

    Un exemple avec la methode negatif(), là c'est correct:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        public Vecteur2 negatif()
        {
        	Vecteur2 temp = new Vecteur2();
            temp.x = -this.x;
            temp.y = -this.y;
            return temp;
        }

    Désolé pour le long code. En effet j'aurait du tester les operations une par une.



    Par contre maintenant j'ai encore un soucis: le calcul se fait tres lentement (quasiment une dizaine de secondes sur mon ordi portable et plusieurs minutes sur une tablette un peu vieille (via une appli android que j'ai crée et qui ne contient que ce calcul pour le moment) tres problematique sachant que j'aimerais un resultat en moins d'une seconde sur la vieille tablette.

    Pourtant sur mon ordi le resultat est quasi instantané via le programme d'origine codé en c#.

    Le seul moyen que j'ai trouvé pour que le programme ne soit pas trop lent c'est d'enlever deux 0 au timestep (soit timeStep = 0.01f au lieu de 0.0001f) ce qui fait rend le resultat vraiment pas assez precis. si j'enleve un seul 0 (ce qui donne 0.001) ça ne fausse pas le resultat mais c'est encore trop lent sur tablette.

    Comment regler ce probleme d'extreme lenteur ?

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Le problème c'est que la création d'objets et la gestion du GC, ça consomme pas mal de ressources. De plus, dur de comparer ce qui se passe sur ton PC et une tablette. Les processeurs n'ont pas du tout les même performances. Vu le calcul que tu dois faire j'éviterais de le faire comme tu le fais avec de multiples objets et appels de méthodes. Les linkedList ne sont pas non plus l'objet le plus performant pour stocker un nombre connu d'entrée. Utilise plutôt un tableau.

    Il faudrait déjà comparer le code c# et le code java sur une architecture identique pour se faire une idée. Aussi le code référencé utilise des floats, tu utilise des doubles. Coté android, certaines versions ont des architectures optimisées pour des doubles, d'autres pour des floats :/ A voir en fonction de la tablette https://stackoverflow.com/questions/...loat-or-double

    Enfin, en c# les vector2 sont des Struct, pas des objets. Ca veut dire pas de dé référencement, pas d'allocation, pas d'héritage et des performances bien meilleurs. Le plus proche en java serait de garder deux variable x et y plutot que des Vecteur dans ton code.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo