Fractales en python avec tkinter
Répondre à la discussion
Affichage des résultats 1 à 8 sur 8

Fractales en python avec tkinter



  1. #1
    henryallen

    Fractales en python avec tkinter


    ------

    Bonjour

    J'ai récemment décidé d'essayer de dessiner des fractales à l'aide de tkinter. Donc pour ceux qui ne le sauraient pas, voici (en gros) comment on fait (d'un point de vue mathématique):
    On a une application f qui, à tout nombre complexe (représenté par un point sur le plan), associe un autre nombre complexe. Prenons f(z)=z²-0.75. Si on prend z=1+i, on a f(z)=2i-0.75. On continue ensuite en calculant f(2i-0.75), etc. Si les points d'affixe ces nombres complexes s'éloignent de l'origine, on colorie le premier point (d'affixe 1+i) en bleu. Sinon, on le colorie en noir. On obtient donc finalement une fractale qui est une figure géométrique qui est auto-similaire: une même image se retrouve à toutes les échelles.

    J'ai donc fait ce code:

    Code:
    #*-coding:Latin-1-*
    
    from tkinter import *
    
    def suite(a, b):
        """Fonction prenant en arguments a et b (a+ib) et déterminant s'ils appartiennent à la fractale."""
        i=0
        re=a
        im=b
        while i<40 and re*re+im*im<4: #On calcule les 40 premiers termes, et on vérifie que leur distance à l'origine ne dépasse pas 2.
            tamp=re
            re=re*re-im*im-3/4
            im=2*tamp*im #On calcule le terme suivant.
            i+=1        
        if i==40:
            return (0) #Si la boucle s'est interrompue car i=40, le point sera noir.
        else:
            return(1) #Sinon il sera bleu.
    
    couleurs={}
    zoom=100 #Sert à déterminer la taille.
    for al_re in range(int(-1.5*zoom), int(1.5*zoom)):
        for al_im in range(int(-1.2*zoom), int(1.2*zoom)): #Pour tous les points dans une portion du plan:
            borne=suite(al_re/zoom, al_im/zoom)
            if borne==0:
                couleurs[al_re, al_im]="noir"
            else:
                couleurs[al_re, al_im]="bleu" #On regarde, grâce à la fonction suite, si le point est noir ou bleu, et on l'indique dans le dictionnaire couleurs.
    fenetre=Tk()
    canvas=Canvas(fenetre, height=int(2.4*zoom), width=int(3*zoom))
    canvas.pack() #On crée notre fenêtre et notre Canevas.
    for key, couleur in couleurs.items():
        if couleur=="noir":
            canvas.create_oval(int(1.5*zoom)+key[0], int(1.2*zoom)-key[1], int(1.5*zoom)+key[0], int(1.2*zoom)-key[1], fill="black")
        else:
            canvas.create_oval(int(1.5*zoom)+key[0], int(1.2*zoom)-key[1], int(1.5*zoom)+key[0], int(1.2*zoom)-key[1], fill="blue") #On colorie les points.
    fenetre.mainloop()
    Bon, il est assez moche, sachant que la portion du plan que j'affiche doit être déterminée avant, mais peu importe. Mon souci est que certains points sont noirs alors qu'ils devraient être bleus. Comment pourrais-je régler ça sans trop augmenter la durée pendant laquelle le programme tourne ? (Sachant qu'elle est déjà un peu élevée ...).

    Merci d'avance
    Bonne journée

    -----

  2. #2
    Chanur

    Re : Fractales en python avec tkinter

    Bonjour,

    Pour savoir si un point bleu fini par être noir, il n'y a pas d'autre moyen que d'augmenter le nombre d'itérations

    Clairement, dans ton code, ce qui prend du temps c'est la boucle :
    Code:
        while i<40 and re*re+im*im<4: #On calcule les 40 premiers termes, et on vérifie que leur distance à l'origine ne dépasse pas 2.
            tamp=re
            re=re*re-im*im-3/4
            im=2*tamp*im #On calcule le terme suivant.
            i+=1
    tu peux l'accélérer un peu en ne calculant pas deux fois re*re et im*im (et peut-être en écrivant 0.75 au lieu de 3/4 : il est possible que python fasse la division à chaque fois)
    Code:
        re2 = 0
        im2 = 0
        while i<40 and re2+im2<4: #On calcule les 40 premiers termes, et on vérifie que leur distance à l'origine ne dépasse pas 2.
            tamp=re
            re2=re*re
            im2=im*im
            re=re2-im2-0.75
            im=2*tamp*im #On calcule le terme suivant.
            i+=1
    Il n'y a plus que 4 multiplications au lieu de 6

    Si tu veux tu peux aussi choisir un autre ensemble de Julia, par exemple en ajoutant une partie imaginaire à la constante :
    Tu calcules z(n+1) = z(n)² + c avec, dans ton cas, c = -0.75, ce qui donne une assez grande zone noire (longue à calculer).
    En prenant, par exemple, c = -0.75 + 0.2i tu auras une fractale plus rapide. (voir ici)

    Sinon, c'est nettement plus compliqué, mais tu peux écrire un algorithme qui pousse le calcul plus loin pour les points proches de la frontière noir/bleu que pour les points éloignés.
    Dernière modification par Chanur ; 27/01/2018 à 17h58.
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  3. #3
    henryallen

    Re : Fractales en python avec tkinter

    Bonsoir

    Merci pour votre réponse Je n'avais en effet pas pensé à réduire le nombre de calculs à cet endroit. Oui, j'avais également essayé avec d'autres ensembles de Julia, mais ça restait relativement lent. J'ai essayé d'accélérer le programme autrement, mais ça n'a pas bien fonctionné:

    Code:
    #*-coding:Latin-1-*
    
    from tkinter import *
    
    def suite(a, b):
        """Fonction prenant en arguments a et b (a+ib) et déterminant s'ils appartiennent à la fractale."""
        i=0
        re=a
        im=b
        re2=im2=0
        while i<40 and re2+im2<4: #On calcule les 40 premiers termes, et on vérifie que leur distance à l'origine ne dépasse pas 2.
            tamp=re
            re2=re*re
            im2=im*im
            re=re2-im2-0.75
            im=2*tamp*im
            i+=1        
        if i==40:
            return (0) #Si la boucle s'est interrompue car i=40, le point sera noir.
        else:
            return(1) #Sinon il sera bleu.
    
    zoom=100 #Sert à déterminer la taille.
    fenetre=Tk()
    canvas=Canvas(fenetre, height=int(2.4*zoom), width=int(3*zoom))
    canvas.pack() #On crée notre fenêtre et notre Canevas.
    for al_re in range(int(-1.5*zoom), int(1.5*zoom)):
        for al_im in range(int(-1.2*zoom), int(1.2*zoom)): #Pour tous les points dans une portion du plan:
            borne=suite(al_re/zoom, al_im/zoom)
            if borne==0:
                canvas.create_oval(int(1.5*zoom)+al_re, int(1.2*zoom)-al_im, int(1.5*zoom)+al_re, int(1.2*zoom)-al_im, fill="black")
            else:
                canvas.create_oval(int(1.5*zoom)+al_re, int(1.2*zoom)-al_im, int(1.5*zoom)+al_re, int(1.2*zoom)-al_im, fill="blue") #On regarde, grâce à la fonction suite, si le point est noir ou bleu, et on l'indique dans le dictionnaire couleurs.
    fenetre.mainloop()
    Plutôt que de stocker les couleurs dans un dictionnaire puis de les re-regarder à l'aide d'une boucle, ici je crée directement les points. Cependant ça ne fonctionne pas, le résultat étant totalement noir ... Où est le problème ?

    Merci d'avance et bonne soirée

  4. #4
    Chanur

    Re : Fractales en python avec tkinter

    Citation Envoyé par henryallen Voir le message
    Où est le problème ?
    Je ne sais pas.
    Je ne connais pas python et quand j'essaie d'exécuter ton code, il me répond "No module named tkinter" ce qui fait que je ne peux pas l'exécuter.
    Espérons que quelqu'un de plus compétent que moi pourra te répondre ...
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  5. A voir en vidéo sur Futura
  6. #5
    pm42

    Re : Fractales en python avec tkinter

    Il faut installer le module avec pip install tkinter par exemple. Ensuite, tout dépend de ce qu'il utilise comme IDE et comme environnement genre virtualenv, anaconda...

    A part ça tes remarques étaient les bonnes mais j'avais fait tourné le code original qui n'affichait que du noir et j'ai eu la flemme de débugger.
    Sinon, python a peu de chance d'être très rapide par défaut et il serait intéressant de voir si on peut faire tourner le code de jython ou cython.

    Un petit exemple ici : https://www.ibm.com/developerworks/c...Python?lang=en

  7. #6
    Chanur

    Re : Fractales en python avec tkinter

    Citation Envoyé par pm42 Voir le message
    Il faut installer le module avec pip install tkinter par exemple. Ensuite, tout dépend de ce qu'il utilise comme IDE et comme environnement genre virtualenv, anaconda...
    Oui, mais mon système n'est pas du tout à jour et j'ai la flemme.

    Citation Envoyé par pm42 Voir le message
    A part ça tes remarques étaient les bonnes mais j'avais fait tourné le code original qui n'affichait que du noir et j'ai eu la flemme de débugger.
    Sinon, python a peu de chance d'être très rapide par défaut et il serait intéressant de voir si on peut faire tourner le code de jython ou cython.

    Un petit exemple ici : https://www.ibm.com/developerworks/c...Python?lang=en
    J'ai hésité à suggérer C++, mais je me suis dis que c'était hors sujet ...
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  8. #7
    jacknicklaus

    Re : Fractales en python avec tkinter

    visiblement tu t'intéresses aux ensembles de Mandelbrot.

    Une méthode d'optimisation est d'utiliser l’algorithme de Mariani. En gros, cet algorithme provient d'une preuve mathématique sur l'ensemble de Mandelbrot qui assure que si on peut tracer les 4 côtés d'un rectangle avec la même couleur, alors tout l'intérieur du rectangle sera aussi de cette couleur.
    There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy.

  9. #8
    henryallen

    Re : Fractales en python avec tkinter

    Bonjour

    Merci pour toutes vos réponses ! Pour information, sur certaines versions de python ce n'est pas tkinter mais Tkinter je crois, et j'utilise IDLE.
    J'essayerai de me pencher sur cet algorithme de Mariani, merci !

    Bonne journée et à bientôt

Discussions similaires

  1. [Python] Interface TKinter et Boucle infinie
    Par Loupsio dans le forum Programmation et langages, Algorithmique
    Réponses: 8
    Dernier message: 21/11/2017, 19h50
  2. Problème - Fenêtre Tkinter python
    Par Eroos dans le forum Programmation et langages, Algorithmique
    Réponses: 3
    Dernier message: 03/05/2017, 10h15
  3. Aide TKINTER Python
    Par raroum dans le forum Programmation et langages, Algorithmique
    Réponses: 0
    Dernier message: 22/04/2016, 20h42
  4. python, tkinter, gestion d'événements
    Par Jack dans le forum Programmation et langages, Algorithmique
    Réponses: 11
    Dernier message: 29/10/2013, 11h34
  5. Python : pas moyen d'importer tkinter
    Par helium0xFF dans le forum Programmation et langages, Algorithmique
    Réponses: 1
    Dernier message: 10/09/2012, 13h26