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