Back to Top

DETECTEUR DE PARTICULES AVEC PYTHON (Tkinter, maths et random)

 

Bonsoir les genies.... j'espère que vous vous portez bien. Notre dernier exercice portant sur l'équation paramétrique du mouvement avait pour but de vous montrer l'exécution d'un programme concret en python. 

Le developpement logiciel est une activité fastidieuse qui demande beaucoup d'ingeniosité. Savoir coder ou connaitre un langage n'est pas suffisant. Il faut aussi savoir imaginer des solutions pour etre efficace. 

Description du projet : 

Il s'agissait d'ecriture une application qui permet de detecter le nombre de particules qui atteingnent l'ecran de lecture apres leur emissions et avant leurs disparutions. Le bouton start lance les particule tandis que le bouton stop arretes l'emissions des particules. Les 3 curseurs ( scale) reglent respectivement la vitesse, l'angle et la gravité.

L'utilisation du module random permet de donner aux particules une valeur aleatoire de l'angle fourni par le curseur ( angle). Cette valeur est plus ou moins 5 la valeur de l'angle.

La class particule ici s'occupe juste d'attribué à chaque particule le mouvement parabolique aucours du temps et verifie si la particules a atteint le fond de l'ecran pour l'ajouter sur la courbe de densitè ou si elle est simplement atteint son temps d'existence.

Voici le code : n'exité pas un laisser vos commentaire et question s'il y'a des choses que vous n'avez pas comprises : 


from tkinter import *

from tkinter.messagebox import *

import math, os

from random import randrange


class particule():

    #on cree la class Particule qui va controler les mouvements des particules suivant

    # l'equation parametrique et egalement controlé si la particule oui ou non à atteint l'ecran

    def __init__(self, v, g, r, crds, end, obj, can, sVar, colorTable):

        self.v, self.g ,self.r, self.crds , self.end , self.obj = v, g, r, crds, end, obj

        self.time , self.c , self.canvas , self.sVar, self.colorTable= 0, 0, can, sVar, colorTable

        self.cur = self.crds.copy()

        self.start()

        

    def start(self):

        #on modifie les coordonnés de la particule suivant l'equation parametrique du mouvement

        for i in range(0,len(self.crds),2):

            # x = v*cos(alpha)*t+x0

            self.cur[i]=self.v*math.cos((self.r*math.pi)/180)*self.time+self.crds[i]

        for i in range(1,len(self.crds)+1,2):

            # y = 1/2*g*t**2+v*sin(alpha)*t+y0

            self.cur[i]=(0.5*self.g*(self.time**2))+self.v*math.sin((self.r*math.pi)/180)*self.time+self.crds[i]


        #on associe à la particule ses nouvelles coordonnées

        self.canvas.coords(self.obj,self.cur)

        #on obtiens la position actuel de la particule

        self.pose = self.canvas.bbox(self.obj)

        

        if self.c>self.end:

            # si le temps de vie de la particule est expiré

            self.canvas.delete(self.obj)

        elif self.pose[0]>w and self.pose[3]>0 and self.pose[3]<h*0.45 and self.pose[3]>0:

            #si la particule à atteint la fin de l'ecran

            self.sVar.set(self.sVar.get()+1)

            title.config(text = ' particules détectées : '+str(self.sVar.get()))

            self.colorTable.append(self.canvas.itemcget(self.obj, 'fill'))

            if len(self.colorTable)>100:

                del self.colorTable[0]

            self.canvas.delete(self.obj)

        else:

            self.c +=5

            self.time+=0.1

            self.canvas.after(42,self.start)


#l'on dessine le repere

def repere(cible, size = 2):

    x , y = 0, 0

    for i in range(500):

        if x%50==0:

            cible.create_line(x, -20, x, h+20, width = size)

        else:

            cible.create_line(x, -20, x, h+20, width = 1)

        x+=20

    for i in range(500):

        if y%50==0:

            cible.create_line(-20, y, w+20, y, width = size)

        else:

            cible.create_line(-20, y, w+20, y, width = 1)

        y+=20

        

def stop():

    global flag

    flag = False


#la fonction qui lance les particule

def throwing():

    global flag

    flag = True

    throw()

    screenVar.set(0)

    emitButton.config(command = lambda : None)

    if len(tableLines)==0:

        createLine()


#la fonction qui cree les ccourbes d'occurences des particules détectées

def createLine():

    for e in colorDict:

        tableLines.append(curves.create_line(colorDict[e], fill = e, width = 2, smooth = 1))

    lineDraw()


#la fonction qui actualise les coordonnées des courbes de particules

def lineDraw():

    global colorTable, colorDict

    counts = [0,0,0,0,0,0]

    for i in range(len(colorTable)):

        for e in colorDict:

            if e ==colorTable[i]:

                elt = color.index(colorTable[i])

                counts[elt]+=1

    v = 0

    for e in colorDict:

        colorDict[e].append(int(w*0.33))

        colorDict[e].append(int(h*0.25)-counts[v]*5)

        for i in range(0, len(colorDict[e]), 2):

            colorDict[e][i]-=10

        curves.coords(tableLines[v], colorDict[e])

        v+=1

    elts = canvas.find_withtag('particle')

    if flag == False and len(elts)==0:

        colorTable = []

    curves.after(1000, lineDraw)


#la fonction qui cree les particules    

def throw():

    global colorTable

    if flag == True:

        c = canvas.create_polygon([15,h*0.5-10,25,h*0.5,5,h*0.5], fill = color[randrange(len(color))], outline ='', tag ='particle')

        particle =  particule(vitesse.get(),gravity.get(),-1*randrange(angle.get()-5, angle.get()+5),

              [15,h*0.45-10,25,h*0.45,5,h*0.45], 750, c, canvas, screenVar, colorTable)

        canvas.after(100,throw)

    else:

        emitButton.config(command =throwing)

        

def info():

    showinfo('info', "cette application compte \n le nombre de particules\n qui arrivent au fond de l'ecran\n \n auteur : python Lite fr 2024(c)")


fenetre = Tk()

fenetre['bg'] = 'purple'


screenVar ,  flag = IntVar(), True

w, h = fenetre.winfo_screenwidth(), fenetre.winfo_screenheight()

color = ['yellow', 'blue', 'red','purple','orange','green']

colorTable, tableLines = [], []

colorDict = {'yellow' : [int(w*0.33),int(h*0.25),int(w*0.33),int(h*0.25)], 'blue' : [int(w*0.33),int(h*0.25),int(w*0.33),int(h*0.25)],

             'red' : [int(w*0.33),int(h*0.25),int(w*0.33),int(h*0.25)],'purple' : [int(w*0.33),int(h*0.25),int(w*0.33),int(h*0.25)],

             'orange' : [int(w*0.33),int(h*0.25),int(w*0.33),int(h*0.25)],'green' : [int(w*0.33),int(h*0.25),int(w*0.33),int(h*0.25)]}


fenetre.title('flux de particules')

canvas = Canvas(fenetre, width = int(w*0.99), height = int(h*0.45), relief = RIDGE , bd = 5)

curves = Canvas(fenetre, width = int(w*0.1), height = int(h*0.25), relief = RIDGE , bd = 5, bg = '#dd99ff')

angle = Scale(fenetre, label = 'angle : ', from_ = 0, to = 360, tickinterval = 60, resolution = 1, orient= 'horizontal', bg = '#aa22ff'

              ,font = ('arial', 5,'bold'), fg = 'white')

vitesse = Scale(fenetre, label = 'vitesse : ', from_ = 0, to = 200, tickinterval = 50, resolution = 1, orient = 'horizontal', bg = '#aa22ff'

                ,font = ('arial', 5,'bold'), fg = 'white')

gravity = Scale(fenetre, label = 'gravity : ', from_ = 0, to = 20, tickinterval = 5, resolution = 0.2, orient = 'horizontal', bg = '#aa22ff'

                ,font = ('arial', 5,'bold'), fg = 'white')

title = Label( fenetre, text = ' compte le nombre de particules ', font = ('arial', 9, 'bold'), relief = RIDGE, bg = '#ffff99', fg= 'purple')

angle.set(35)

vitesse.set(125)

gravity.set(9.8)

emitButton = Button(fenetre, text = 'start ', command = throwing, relief = FLAT, bg = '#ffff99',font = ('arial', 10,'bold'))

endButton = Button(fenetre, text = 'stop ', command = stop, relief = FLAT, bg = '#ffff99', font = ('arial', 10,'bold'))

infoButton = Button(fenetre, text = 'aide ', command = info, relief = FLAT, bg = '#ffff99', font = ('arial', 10,'bold'))

title.grid(column =0 , row = 0, sticky ='nswe', padx = 2, pady = 2, columnspan =3 )

canvas.grid(column =0 , row =1 , sticky ='nswe', padx = 2, pady = 2, columnspan =3 )

angle.grid(column =0 , row = 2, sticky ='nswe', padx = 2, pady = 2, columnspan = 2)

vitesse.grid(column =0 , row =3 , sticky ='nswe', padx = 2, pady = 2, columnspan =2 )

gravity.grid(column =0 , row = 4, sticky ='nswe', padx = 2, pady = 2, columnspan =2 )

curves.grid(column =2 , row =2 , sticky ='nswe', padx = 2, pady = 2 , rowspan = 3)

emitButton.grid(column =0 , row =5 , sticky ='nswe', padx = 2, pady = 2)

endButton.grid(column =1 , row =5 , sticky ='nswe', padx = 2, pady = 2)

infoButton.grid(column =2 , row =5 , sticky ='nswe', padx = 2, pady = 2)

repere(canvas, size = 2)

repere(curves, size = 1)

fenetre.mainloop()




0Comments

Enregistrer un commentaire