Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 22/04/2014, à 17:35

GeRoHi

Enregistrement et accès a un tableau à deux dimensions - Java.

Hello tout le monde,

Pour la fac je dois coder une simulation d'explosion, ça fonctionne mais à un moment, j'essaie d'enregistrer les positions de chaque particule au cours du temps dans une matrice, puis d'afficher la matrice en question.
Pour une raison inconnue, lors de l'affichage, ça renvoie systématiquement le dernier enregistrement, la dernière position atteinte par la particule. Il semblerait que à chaque enregistrement d'une position, la nouvelle valeur ecrase toutes les précédentes dans la matrice.

Ca sera peut être plus clair avec le code sous les yeux :

//Calcul des positions de chaque point au cours du temps, enregistrement dans une matrice.
  position2D[][] Positions = new position2D [nbmesures][Particules.length];
  double te=0;
  for (int i=0;i<Particules.length;i++) {
    te=0.0;
    for (int j=0;j<nbmesures;j++) {
      Positions[j][i]=position(Particules[i].pos, Particules[i].equa, te);
      Ecran.afficherln("t= ",te," : ( ",Positions[j][i].x," ; ",Positions[j][i].y," )", "PREMIERE VALEUR : ( ",Positions[0][0].x," ; ",Positions[0][0].y," )");
      te=te+deltaT;
    }
    Ecran.afficherln("VALEUR TEST"," : ( ",Positions[5][0].x," ; ",Positions[5][0].y," )");
  }
  //



//Affichage de la matrice des positions.
Ecran.afficherln("MATRICE DES POSITIONS \n--------------");
for (int i=0;i<nbparticules;i++){
  Ecran.afficherln("Particule ",i,"\n-----------------");
    for (int k=0;k<nbmesures;k++) {
      Ecran.afficherln("t",k," : ( ",Positions[k][i].x," ; ",Positions[k][i].y," )", "k",k,"i",i);
    }
  }
  //
  

Voici un exemple d'éxécution pour vous rendre compte de où ça pars en live :

>javac expl000sion.java
>Exit code: 0
>javac expl000sion.java
>Exit code: 0
>java expl000sion
vitesse min ?
50
vitesse max ?
60
Combien de particules ?
1
Delta t?
0.5
Durée?
10
nbmesures =20
Conditions initiales : 
 Angle : 3.5359308289492795
 Vitesse : 57.42092383784119 m.s-1
 particule.length = 1

t= 0.0 : ( 0 ; 0 )PREMIERE VALEUR : ( 0 ; 0 )
t= 0.5 : ( -26 ; -12 )PREMIERE VALEUR : ( -26 ; -12 )
t= 1.0 : ( -53 ; -26 )PREMIERE VALEUR : ( -53 ; -26 )
t= 1.5 : ( -79 ; -44 )PREMIERE VALEUR : ( -79 ; -44 )
t= 2.0 : ( -106 ; -63 )PREMIERE VALEUR : ( -106 ; -63 )
t= 2.5 : ( -132 ; -85 )PREMIERE VALEUR : ( -132 ; -85 )
t= 3.0 : ( -159 ; -110 )PREMIERE VALEUR : ( -159 ; -110 )
t= 3.5 : ( -185 ; -137 )PREMIERE VALEUR : ( -185 ; -137 )
t= 4.0 : ( -212 ; -166 )PREMIERE VALEUR : ( -212 ; -166 )
t= 4.5 : ( -238 ; -198 )PREMIERE VALEUR : ( -238 ; -198 )
t= 5.0 : ( -265 ; -232 )PREMIERE VALEUR : ( -265 ; -232 )
t= 5.5 : ( -291 ; -269 )PREMIERE VALEUR : ( -291 ; -269 )
t= 6.0 : ( -318 ; -308 )PREMIERE VALEUR : ( -318 ; -308 )
t= 6.5 : ( -344 ; -350 )PREMIERE VALEUR : ( -344 ; -350 )
t= 7.0 : ( -371 ; -394 )PREMIERE VALEUR : ( -371 ; -394 )
t= 7.5 : ( -397 ; -441 )PREMIERE VALEUR : ( -397 ; -441 )
t= 8.0 : ( -424 ; -490 )PREMIERE VALEUR : ( -424 ; -490 )
t= 8.5 : ( -450 ; -541 )PREMIERE VALEUR : ( -450 ; -541 )
t= 9.0 : ( -477 ; -595 )PREMIERE VALEUR : ( -477 ; -595 )
t= 9.5 : ( -503 ; -652 )PREMIERE VALEUR : ( -503 ; -652 )
VALEUR TEST : ( -503 ; -652 )


MATRICE DES POSITIONS 
--------------
Particule 0
-----------------
t0 : ( -503 ; -652 )k0i0
t1 : ( -503 ; -652 )k1i0
t2 : ( -503 ; -652 )k2i0
t3 : ( -503 ; -652 )k3i0
t4 : ( -503 ; -652 )k4i0
t5 : ( -503 ; -652 )k5i0
t6 : ( -503 ; -652 )k6i0
t7 : ( -503 ; -652 )k7i0
t8 : ( -503 ; -652 )k8i0
t9 : ( -503 ; -652 )k9i0
t10 : ( -503 ; -652 )k10i0
t11 : ( -503 ; -652 )k11i0
t12 : ( -503 ; -652 )k12i0
t13 : ( -503 ; -652 )k13i0
t14 : ( -503 ; -652 )k14i0
t15 : ( -503 ; -652 )k15i0
t16 : ( -503 ; -652 )k16i0
t17 : ( -503 ; -652 )k17i0
t18 : ( -503 ; -652 )k18i0
t19 : ( -503 ; -652 )k19i0

>Exit code: 0

P.S : Faites pas gaffe aux "Ecran.afficher" c'est une petite classe développée par notre prof pour nous simplifier les choses ^^

Hors ligne

#2 Le 22/04/2014, à 17:51

claudius01

Re : Enregistrement et accès a un tableau à deux dimensions - Java.

Bonsoir,

Peut-on avoir le code de la méthode position() utilisée dans Positions[jj][ii]=position(Particules[ii].pos, Particules[ii].equa, te);
Cela ressemble à un problème d'allocation qui ne serait pas faite d'où l'utilisation de la dernière accédée (à confirmer/ infirmer)

NB: J'ai changé les indices i en ii et j en jj pour des raisons éditoriales ;-)


Cordialement, A+
--
Claudius

Dernière modification par claudius01 (Le 22/04/2014, à 18:05)

Hors ligne

#3 Le 22/04/2014, à 18:01

GeRoHi

Re : Enregistrement et accès a un tableau à deux dimensions - Java.

Voici tous mes types agrégés et méthodes wink :

   //Type agrégé des coordonnées d'un point dans le plan.
  static class position2D {
    int x=0;
    int y=0;
  }
  //
  
  
  
  //Type agrégé des paramètres d'une equation de trajectoire. 
  static class eqTrajectoire {
    double angle=0.0;
    double vitesse=0.0;
    position2D posI = new position2D();
  }
  

  
  //
  
  
  
  //Type agrégé de la position d'un point et de ses conditions de vitesse et d'angle initiales.  
  static class Point {
    position2D pos = new position2D();
    eqTrajectoire equa = new eqTrajectoire();
  }
  
 
 
  //
  
  
  
  //Génération d'un réel tiré aléatoirement entre a et b. (Vitesse)  
  public static double genVitesseAlea (double a,double b) {
    return Math.random()*(b-a)+a;
  }
  

 
  //
  
  
  
  //Génération angle aléatoire.
  public static double genAngleAlea () {
    return (Math.random()*((2*(Math.PI))));
  }
  
 
  
  //
  
  
  
  //Fonction renvoyant la position d'un point en utilisant les paramètres d'une equation horaire pré-établie.
  public static position2D position(position2D p, eqTrajectoire equa, double t) {
      p.x=equa.posI.x+(int)(equa.vitesse*Math.cos(equa.angle)*t);
      p.y=equa.posI.y+(int)(((-9.81*t*t)/2)+equa.vitesse*Math.sin(equa.angle)*t);    
    //Ecran.afficherln("angle : ",equa.angle,"\n sinus angle :",Math.sin(equa.angle),"\n vitesse : ",equa.vitesse,"\n temps :",t);
    return p;
  }

  
  //

Si tu veux mais du coup j'ai peur qu'on se mélange entre les indices et les coordonnées des points ^^ m'enfin tongue

Hors ligne

#4 Le 23/04/2014, à 10:23

claudius01

Re : Enregistrement et accès a un tableau à deux dimensions - Java.

Bonjour,

Ok merci pour le complément d'infos. De plus, j'ai changé les i en ii et j en jj ;-).
Tout d'abord, le code présenté n'est pas à vrai dire du Java mais plutôt une transcription d'un code C aux new et class près ... soit ...
Je pense que le problème vient des définitions static des classes Point et position2D (en autres) qui conduisent aux new d'allouer une et une seule référence pour chacune de ces classes.
Je t'invite à supprimer ces static et à jeter un coup d’œil au doc Tableau d'objets...


Cordialement, A+
--
Claudius

Dernière modification par claudius01 (Le 23/04/2014, à 11:11)

Hors ligne

#5 Le 24/04/2014, à 04:03

GeRoHi

Re : Enregistrement et accès a un tableau à deux dimensions - Java.

Beh, si c'est pas du java j'en reste coi ^^
On nous dis depuis le début de l'année que c'est du java, j'ai installer l'environnement java que j'ai chopé sur le site d'oracle, etc.. Qu'est ce qui te fait dire que c'est une transcription de C ?

Les classes en question je les ai pas mal utilisées elles semblent fonctionner, et pareil pour les matrices j'ai fais des tests avec des matrices simples contenant des entiers, aucun problème pour enregistrer dedans et pour l'afficher après coup.. J'ai même exécuté le code en mode pas à pas dans ma tête et toujours pas moyen de comprendre d'où ça vient.. je crois que je vais envoyer un mail au prof ^^

Hors ligne

#6 Le 24/04/2014, à 12:05

claudius01

Re : Enregistrement et accès a un tableau à deux dimensions - Java.

Bonjour,

GeRoHi a écrit :

On nous dis depuis le début de l'année que c'est du java, j'ai installer l'environnement java que j'ai chopé sur le site d'oracle, etc.. Qu'est ce qui te fait dire que c'est une transcription de C ?

Je développerai plut tard si tu le veux, mais en attendant j'ai reproduis et donc à priori trouvé l'origine du problème.

La ligne en faute est:

Positions[j][i]=position(Particules[i].pos, Particules[i].equa, te);

qui fait que la référence de 'Positions[j][ii]' (ii = i) pour des raisons éditoriales ;-) retournée par la méthode 'position()' est toujours la même ;-(

Je propose de la corriger avec:

Positions[j][i]=position(new position2D(), new eqTrajectoire(), te);

Le programme revisité à partir du tiens et qui m'a permis cette identification est:

public class TestExplosion {

	final static int nbmesures = 6;
	final static int length = 1;

	static class position2D {
		int x = 0;
		int y = 0;
	}

	static class Point {
	        position2D pos = new position2D();
	        eqTrajectoire equa = new eqTrajectoire();
	}

	static class eqTrajectoire  {
  		double angle = 30.0;
		double vitesse = 60.0;
		position2D posI = new position2D();
 	}

	public static position2D position(position2D p, eqTrajectoire equa, double t) {
		
		p.x = equa.posI.x + (int)(equa.vitesse * Math.cos(equa.angle) * t);
	        p.y = equa.posI.y + (int)(((-9.81*t*t)/2) + equa.vitesse * Math.sin(equa.angle)*t);    
		return p;
   	}

	public static void main(String[] args) {

		position2D[][] Positions = new position2D[nbmesures][length];

		double deltaT = 0.5;
		double te = 0.0;
                /* Inutile après correction bug
		Point Particules[] = new Point[length];
		for (int i = 0; i < length; i++) {
			Particules[i] = new Point();
		}
                */
		for (int i = 0; i < length; i++) {
	            te = 0.0;
		    for (int j = 0; j < nbmesures; j++) {
		      // Bug: Positions[j][i] aura toujours la même référence que 'Particules[i].pos'
		      //Positions[j][i] = position(Particules[i].pos, Particules[i].equa, te);

		      /* Fix bug: Passage d'une nouvelle référence ;-) */
		      Positions[j][i] = position(new position2D(), new eqTrajectoire(), te);

		      System.out.println("t= " + te + " : ( " + Positions[j][i].x + " ; " + Positions[j][i].y + " )" + " PREMIERE VALEUR : ( " +
		    		  Positions[0][0].x + " ; " + Positions[0][0].y + " )");
		      te = te + deltaT;
		      //System.out.println("#" + j + " [" + Positions[j][i].toString() + "]\n");
		    }
		    System.out.println("VALEUR TEST" + " : ( " + Positions[5][0].x + " ; " + Positions[5][0].y +  " )");
		}

		System.out.println("\nMATRICE DES POSITIONS \n--------------");
		for (int i = 0; i < length; i++) {
			System.out.println("Particule " + i + "\n-----------------");
			for (int k = 0; k < nbmesures; k++)  {
				System.out.println("t" + k + " : ( " + Positions[k][i].x + " ; " + Positions[k][i].y + " ) " +  "k " + k + " i " + i);
				//System.out.println("#" + k + " [" + Positions[k][i].toString() + "]\n");
			}
		   }
		}
}

qui fournit bien en sortie (avec mes valeurs à moi ;-):

t= 0.0 : ( 0 ; 0 ) PREMIERE VALEUR : ( 0 ; 0 )
t= 0.5 : ( 4 ; -30 ) PREMIERE VALEUR : ( 0 ; 0 )
t= 1.0 : ( 9 ; -64 ) PREMIERE VALEUR : ( 0 ; 0 )
t= 1.5 : ( 13 ; -99 ) PREMIERE VALEUR : ( 0 ; 0 )
t= 2.0 : ( 18 ; -138 ) PREMIERE VALEUR : ( 0 ; 0 )
t= 2.5 : ( 23 ; -178 ) PREMIERE VALEUR : ( 0 ; 0 )
VALEUR TEST : ( 23 ; -178 )

MATRICE DES POSITIONS 
--------------
Particule 0
-----------------
t0 : ( 0 ; 0 ) k 0 i 0
t1 : ( 4 ; -30 ) k 1 i 0
t2 : ( 9 ; -64 ) k 2 i 0
t3 : ( 13 ; -99 ) k 3 i 0
t4 : ( 18 ; -138 ) k 4 i 0
t5 : ( 23 ; -178 ) k 5 i 0

Cordialement, A+
--
Claudius

Dernière modification par claudius01 (Le 24/04/2014, à 13:22)

Hors ligne

#7 Le 24/04/2014, à 14:21

GeRoHi

Re : Enregistrement et accès a un tableau à deux dimensions - Java.

Béni sois-tu ! smile

J'ai juste changé le "particule[ii].pos" en un "new position2D()" dans les paramètres de la méthode position et ça fonctionne, pas eu besoin de toucher aux paramètres de l'équation ce qui m'arrange plutôt.

Par contre je suis pas certain d'avoir compris pourquoi ça marche ? Oo

Tu dis que

la référence de 'Positions[j][ii]' (ii = i retournée par la méthode 'position()' est toujours la même ;-(

mais pourtant dans mon premier exemple d’exécution on voit que les valeurs sont dans un premier temps correctes et évoluent puis sont ensuite écrasées par les suivantes.. ?

En tous cas je te remercie beaucoup pour ton aide smile, je suis enfin débloqué là dessus, si tu veux bien en plus essayer de me faire comprendre pourquoi ça marchait je t'avoue que ça m'intéresse tongue

Et, si tu peux développer rapidement sur la question java/C je suis preneur aussi ^^

Hors ligne

#8 Le 24/04/2014, à 17:24

claudius01

Re : Enregistrement et accès a un tableau à deux dimensions - Java.

Re GeRoHi, content pour toi et merci également (non, il n'a rien de divin dans tout cela - sinon, j'aurai changé de métier depuis des lustres ;-)

1) Explication

Tu as a écrit :

mais pourtant dans mon premier exemple d’exécution on voit que les valeurs sont dans un premier temps correctes et évoluent puis sont ensuite écrasées par les suivantes.. ?

Tout simplement parce que la trace dans la boucle affiche le résultat du calcul et de l'affectation dans 'Positions[j][ii]', calcul qui évolue comme prévu :-).
Mais cette trace n'indique en rien que le bon objet 'position2D' du tableau est affecté d'une manière durable  :-(.
C'est pour cela que la 1ère chose que j'ai ajoutée est la ligne

System.out.println("#" + j + " [" + Positions[j][i].toString() + "]\n");

qui sort un truc comme

#2 [TestExplosion$position2D@3125ee71]

et qui m'a montré que les références des 'Positions[j][ii]' quels que soient ii et j étaient toujours les mêmes et égales à celle de 'Particules[ii].pos'. Normal après relecture du code...

2) Maintenant, s'agissant de la question java/C .

La 1ère chose qui m'a "chagriné" à la lecture est l'utilisation du mot class pour en fait définir des structures à la mode C alors que je m'attendais à au moins une classe Particule() contenant une jolie classe Point() avec leur constructeur ad hoc (cad non par défaut) car

Tu as a écrit :

Pour la fac je dois coder une simulation d'explosion, ça fonctionne mais à un moment, j'essaie d'enregistrer les positions de chaque particule au cours du temps dans une matrice, puis d'afficher la matrice en question.

La 2ème chose a été les 2 boucles for encastrées déroulant la matrice à 2 dimensions. Normal car le programme ne manipule pas des objets (sur lesquels on peut utiliser des listes avec des itérateurs, encapsuler leurs propriétés, les mettre dans des matrices, etc.) mais l'information on ne peut plus précise:
La position à un instant donné des particules dans un plan (x, y) exprimées en entier (int)

D'où ma réponse à laquelle j'ajouterais maintenant: Mais pourquoi avoir écrit en Java alors qu'il n'y pas l'ombre d'une programmation orientée objet.

Pour identifier le problème, j'ai donc revisité ton programme et là surprise:
Pas besoin d'import de packages hormis le 'java.lang.Math'. Le programme est auto suffisant !

Je ne vais pas me lancer à montrer l’intérêt de cette POO mais plutôt à 2 remarques:

a) L'utilisation d'un langage ne se limite pas et ne doit pas se limiter à sa syntaxe même si c'est le passage obligé mais surtout aux concepts sous-jacents et notamment leur paradigme. C'est comme une langue; après le vocabulaire, la grammaire, la conjugaison, les faux amis, etc. il y a la culture du pays parlant cette langue

b) Si j'étais votre professeur (loin de moi cette idée et surtout de mon métier), je m'amuserais à proposer une suite à ce problème de simulation d'explosion ;-)
Maintenant que votre programme de simulation est codé et correct, je vous propose de faire le même programme avec des particules dans un espace à 3 dimensions dont les positions sont exprimées en coordonnées polaires avec (r, @ et phi) codés sur des "Double" pour avoir une meilleure précision. Pour ceux qui auront finis dans moins d'une 1/2 heure, vous rajouterez en plus du nombre de mesures et du temps, une dimension indiquant le type de particule.

Dans ta version actuelle, je pense qu'il faut tout réécrire et surtout ... tout retester :-(((

NB1: Pense à passer en [Résolu] (si tu en convient) en rééditant le sujet du 1er post.
NB2: Ne pas hésiter à me corriger si grosses bêtises.


Cordialement, A+
--
Claudius

Hors ligne