Programme ne s'arretant jamais (Fractales)

Programme ne s'arretant jamais (Fractales) - Java - Programmation

Marsh Posté le 28-04-2011 à 21:15:17    

Bonjour à tous,
 
Je suis en train de coder un programme qui permet de tracer une fractale de Julia dans un fichier BitMap.
Le processus est le suivant : à chaque itération d'une boucle while, la couleur du pixel qu'on traite augmente de 1 (et s'éclairci donc à chaque fois). On sort de cette boucle quand le pixel ne diverge plus... Enfin, tout ça est bien compliqué, j'essaye d'expliquer facilement pour que tout le monde comprenne, mais sans qu'on explique vraiment ce qu'est une fractale, et le plan complexe, ça ne sert pas à grand chose.
 
De toute façon, ce n'est pas cette partie de mon programme qui bug. Je vous ai surtout dit tout ça pour un peu expliquer le contexte.
C'est la partie où l'on rentre dans un fichier Bitmap (sachant que chaque pixel d'un fichier Bitmap a un codage indépendant des autres pixels : http://turrier.fr/tutoriels/form_0 [...] cimal.html ), les codes hexadécimaux des couleurs des pixels. Apparemment, la boucle ne s'arrete jamais.
Vous trouverez cela dans la classe BitMap : la méthode getPixels() (je crois que c'est elle qui bug, mais je peux me tromper).
 
Je ne comprends pas pourquoi elle ne s'arrete jamais. Je vous envoie mes codes sources : http://www.esiee.fr/~decaudam/Fractales.zip
 
Et voici la méthode qui bug (elle ne suffira peut etre pas à comprendre le problème si on n'a qu'elle, mais bon) :

Code :
  1. public String[][] getPixels()
  2.     {
  3.         aPixels = new String[aWidth][aHeight];
  4.        
  5.         for (int i = 0 ; i < aWidth ; i++)
  6.         {
  7.             for (int j = 0 ; j < aHeight ; j++)
  8.             {
  9.                 Pixel vPixel = new Pixel(i, j);
  10.                 int vColor = vPixel.showColor();
  11.                 if(vColor > 255)
  12.                     aPixels[i][j] = "0000FF";
  13.                 else
  14.                     aPixels[i][j] = "0000" + Integer.toHexString(vColor); //IL faut vérifier le format de cette sortie : doit etre de la forme String 0000XX. Attention : avec cette méthode, la valeur ne peut pas dépasser 0xFF = 255
  15.             }
  16.         }
  17.         return aPixels;
  18.     }


 
Merci d'avance pour votre aide


Message édité par Marin2 le 28-04-2011 à 21:23:36
Reply

Marsh Posté le 28-04-2011 à 21:15:17   

Reply

Marsh Posté le 28-04-2011 à 21:28:11    

Quand tu dis qui bug, tu veux dire qu'il ne s'arrete jamais ?
 
je n'ai pas regarde ton code dans le zip, mais je ne vois pas de boucle infini dans cette methode.
 
Le plus simple, c'est de mettre des prints pour voir ce qu'il fait en temps reel ou d'utiliser un debugger dans cette fameuse boucle while pour voir ce que ton programme fait ...
 
Quand je lie "n sort de cette boucle quand le pixel ne diverge plus", ca me fait penser a un pb de convergence ...

Reply

Marsh Posté le 29-04-2011 à 16:36:27    

mr simon a écrit :

Quand tu dis qui bug, tu veux dire qu'il ne s'arrete jamais ?
 
je n'ai pas regarde ton code dans le zip, mais je ne vois pas de boucle infini dans cette methode.
 
Le plus simple, c'est de mettre des prints pour voir ce qu'il fait en temps reel ou d'utiliser un debugger dans cette fameuse boucle while pour voir ce que ton programme fait ...
 
Quand je lie "n sort de cette boucle quand le pixel ne diverge plus", ca me fait penser a un pb de convergence ...


 
Je suis assez d'accord avec ça... Quand on regarde ce qui se passe dans la méthode "calcColor()" de la classe Pixel, on voit un boucle "while (aZ.mod() < 2)"... Es-tu sur que ton module sera un jour plus grand que 2 ?  

Reply

Marsh Posté le 29-04-2011 à 16:48:50    

Ben je pense que oui, puisque aZ ne peut qu'augmenter, au fil des itérations (il me semble) : aZn+1 = aZn ² + C.
aZn² est toujours plus grand que aZn, et C finit forcément par etre dépassé par aZn, puisque c'est une constante.
 
Donc, si aZ peut monter autant qu'on veut, le module doit finir par dépasser 2. Non ?

Reply

Marsh Posté le 29-04-2011 à 18:07:54    

aZn2 > aZn ssi aZn > 1 il faut aussi C > 0
 
le plus simple dans tout cas, c de priner aZn a chaque iteration, tu verras bien ce qu'il se passe !

Reply

Marsh Posté le 30-04-2011 à 00:30:30    

Marin2 a écrit :

Ben je pense que oui, puisque aZ ne peut qu'augmenter, au fil des itérations (il me semble) : aZn+1 = aZn ² + C.
aZn² est toujours plus grand que aZn, et C finit forcément par etre dépassé par aZn, puisque c'est une constante.
 
Donc, si aZ peut monter autant qu'on veut, le module doit finir par dépasser 2. Non ?


 
Tu manipules des nombres complexes, on ne peut donc pas parler de "plus grand que". D'autre part il y a clairement des contre-exemples avec par exemple C = 0 et mod(Z0) <1. On a alors Zn = Z0 ^2N qui tend vers 0. Je crois que pour ce type de problème il vaut mieux utiliser un nombre d'itérations paramétrable. Plus tu itères, plus tu tu gagnes en précision.

Reply

Marsh Posté le 01-05-2011 à 11:36:45    

Ok, donc finalement c'était un simple problème mathématique, pas de programmation. Merci de votre aide, cette partie est maintenant réglée.
 
Maintenant, j'ai un deuxième problème. J'envoie les codes hexa des couleurs vers un fichier, pour créer une image bitmap.
Voici comment marche une image bitmap :
http://turrier.fr/tutoriels/form_0 [...] cimal.html
 
Pour résumer, chaque pixel est codé séparément des autres : le fichier est donc une suite de codes en hexa, pour définir la couleur de chaque pixel (BleuBleu VertVert RougeRouge), après quelques lignes de "header", ou on définit des trucs comme le type de fichier (.bmp), la taille en octet, la taille en pixel (hauteur, largeur), etc.
 
Donc j'envoie le contenu de mes tableaux vers un fichier. Cependant, mes tableaux sont des tableaux de String. Car il me les faut en hexa, et je ne sais pas comment faire pour écrire de l'hexa sous forme d'int en java (les chiffres de A à F ne rentrent pas). Donc le fichier me les convertit automatiquement en leur code ASCII correspondant. Par exemple, j'envoie 00 00 5A avec mon programme, et j'obtient 3030 3030 3541. Je voudrais éviter cette conversion.
 
J'ai pensé à une solution (si vous en avez une meilleure, je suis preneur !) : je transforme les codes contenues dans mes chaines de caractères en caractères correspondant au code ASCII.
Exemple : si j'ai 00 00 5A à envoyer, je le convertit d'abord en [nul][nul]Z. Je fais cela par le programme, bien sûr, avec des cast :  
byte codeAEnvoyer = 5A;
codeConvertiAEnvoyer = (char)codeAEnvoyer;
 
Cette méthode à un gros problème. C'est que j'ai des String au départ, et pas des byte comme dans mon exemple. Le cast ne marche donc pas. Et comme je fais pas mal d'opérations sur mes String (comme ne prendre que 2 caractères par case de tableaux, etc.), je ne peux pas vraiment facilement m'en débarrasser.
 
Donc si vous avez des idées, je vous écoute :)


Message édité par Marin2 le 01-05-2011 à 11:46:14
Reply

Marsh Posté le 02-05-2011 à 18:28:32    

Question: Pourquoi diable tes tableaux sont des Strings?
Un hexa, c'est juste un int codé en base 16 hein Oo?
 
Fait des tableaux d'int, entre tes données en integer dedans, et tu verras que ça marche tout seul :o


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 03-05-2011 à 21:45:24    

Je ne peux pas, car il me faut que deux "chiffres" par case de tableau. Je divise mes String en plusieurs parties de 2 chiffres chacunes.
Je n'ai trouvé aucun moyen de faire ça avec des int (surtout que leur nombre de chiffre varie selon la base utilisée : décimal ou hexa).
 
Je pensais avoir trouvé une solution, mais elle ne marche pas. J'utilise ceci :
int i = Integer.valueOf(s, 16).intValue();
où s est ma String.
J'écris ensuite le résultat dans mon fichier.
 
Mais ça ne renvoie pas le résultat attendu. Je ne sais pas pourquoi
 
Voilà le programme modifié : www.esiee.fr/~decaudam/Fractales.zip

Reply

Marsh Posté le 04-05-2011 à 11:18:34    

Marin2 a écrit :

Mais ça ne renvoie pas le résultat attendu. Je ne sais pas pourquoi

 

Tu lui donne quoi à manger, tu obtiens quoi et tu attend quoi ?

 

Sinon, on en a vaguement "parlé" ici :D

 

La méthode getArrayFromStringRepresentation() fera peut-être ce que tu cherches.

 


Message édité par LeRiton le 04-05-2011 à 11:18:44
Reply

Marsh Posté le 04-05-2011 à 11:18:34   

Reply

Marsh Posté le 08-05-2011 à 10:59:39    

Voilà, j'ai réussi à faire marcher mon programme. Merci à tous pour votre aide.
 
J'ai juste une dernière petite question : quand je lance mon programme, pour dessiner une fractale, il met très longtemps à la dessiner (environ 20 minutes pour une image de taille 80x40).
Je comprends que l'ordinateur doit faire énormément de calculs (d'après quelques calculs vite fait, il doit faire environ 1,7 millions d'opérations).
Est-ce que c'est normal qu'il soit si lent ? Dans ce cas, comment font les générateurs de fractales (programmes téléchargeables sur internet qui dessinent les fractales) ?
Comment pourrais-je augmenter sa vitesse sans avoir à restructurer tout mon programme (et encore, je ne vois même pas comment je pourrais faire marcher ce programme d'une façon différente) ?
 
Enfin, comment puis-je connaitre la fréquence de la JVM ?

Reply

Marsh Posté le 08-05-2011 à 14:57:02    

Marin2 a écrit :

Voilà, j'ai réussi à faire marcher mon programme. Merci à tous pour votre aide.
 
J'ai juste une dernière petite question : quand je lance mon programme, pour dessiner une fractale, il met très longtemps à la dessiner (environ 20 minutes pour une image de taille 80x40).
Je comprends que l'ordinateur doit faire énormément de calculs (d'après quelques calculs vite fait, il doit faire environ 1,7 millions d'opérations).
Est-ce que c'est normal qu'il soit si lent ? Dans ce cas, comment font les générateurs de fractales (programmes téléchargeables sur internet qui dessinent les fractales) ?
Comment pourrais-je augmenter sa vitesse sans avoir à restructurer tout mon programme (et encore, je ne vois même pas comment je pourrais faire marcher ce programme d'une façon différente) ?
 
Enfin, comment puis-je connaitre la fréquence de la JVM ?


C'est parce que tu manipules des chaines de caractères plutot que directement des nombres

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed