Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from tkinter import *
- import time
- import math
- #constant
- window_width=300
- window_height=300
- ball_size=20
- ball_distance = ball_size/2
- ball_offset_line = ball_size/2 + ball_distance/2
- nb_balls= 1
- pixel_step=1
- ball_weight=20
- time_refresh=0.005
- time_simulation=2
- window_offsetx = window_width/2 - 2.5*ball_size - 2*ball_distance
- window_offsety = window_height/3
- selected_ball = -1
- canvas= -1
- white_ball=-1
- balls=-1
- xp=0
- xm=0
- delta=0
- pente=0
- coeff_directeur=0
- ord_origin=0
- ord2_origin=0
- coeff2_directeur = 0
- phi=0
- m1=0.450
- m2=0.450
- def angle_apres_choc(v1,v2,theta1,theta2):
- if v2==0:
- theta11=math.atan(((m1-m2)/(m1+m2))*math.tan(theta1))
- theta21=(math.pi)/2
- v11=math.sqrt(pow(v1*math.cos(theta1),2)+pow(((2*m2)/(m1+m2))*(math.sin(theta2)*v2)+((m1-m2)/(m1+m2))*v1*math.sin(theta1),2))
- v21=math.sqrt(pow(v2*math.cos(theta2),2)+pow(((2*m1)/(m1+m2))*(math.sin(theta1)*v1)+((m2-m1)/(m1+m2))*v2*math.sin(theta2),2))
- else:
- theta11=math.atan(((2*m2)/(m1+m2)*v2*math.sin(theta2))/(v1*math.cos(theta1))+(m1-m2)/(m1+m2)*math.tan(theta1))
- theta21=math.atan(((2*m1)/(m1+m2)*v1*math.sin(theta1))/(v2*math.cos(theta2))+(m2-m1)/(m1+m2)*math.tan(theta2))
- v11=math.sqrt(pow(v1*math.cos(theta1),2)+pow(((2*m2)/(m1+m2))*(math.sin(theta2)*v2)+((m1-m2)/(m1+m2))*v1*math.sin(theta1),2))
- v21=math.sqrt(pow(v2*math.cos(theta2),2)+pow(((2*m1)/(m1+m2))*(math.sin(theta1)*v1)+((m2-m1)/(m1+m2))*v2*math.sin(theta2),2))
- return(v11,v21,theta11,theta21)
- def intersect(x0,x1,y0,y1):
- if y0==y1:
- x=(pow(x0,2)-pow(x1,2))/(2*(x0-x1))
- A = 1
- B = -2*y1
- C = pow(x1,2)+pow(x,2) - 2*x1*x + pow(y1,2) - pow(ball_size/2,2)
- delta = pow(B,2)-4*(A)*C
- ym = ((-B)-math.sqrt(delta))/(2*A)
- yp = ((-B)+math.sqrt(delta))/(2*A)
- y=(yp+ym)/2
- return(x,y)
- else:
- N=(-pow(x1,2)+pow(x0,2)-pow(y1,2)+pow(y0,2))/(2*(y0-y1))
- B=2*(y0*((x0-x1)/(y0-y1)))-2*N*((x0-x1)/(y0-y1))-2*x0
- A=pow((x0-x1)/(y0-y1),2)+1
- C=(pow(x0,2)+pow(y0,2)+pow(N,2)-pow(ball_size/2,2)-2*y0*N)
- delta = pow(B,2)-4*(A)*C
- xm=((-B)-math.sqrt(delta))/(2*A)
- xp=((-B)+math.sqrt(delta))/(2*A)
- x=(xm+xp)/2
- ym=N-xm*((x0-x1)/(y0-y1))
- yp=N-xp*((x0-x1)/(y0-y1))
- y=(ym+yp)/2
- return(x,y)
- def tangente(x0,y0,x1,y1):
- if (x1-x0)==0:
- pente=0
- coeff_directeur=0
- ord_origin=y1
- else:
- pente=(y1-y0)/(x1-x0)
- if pente:
- coeff_directeur=-1/(pente)
- else:
- coeff_directeur=0
- ord_origin=y1-coeff_directeur*x1
- return(coeff_directeur,ord_origin)
- def coeffdirecteur(x0,y0,x1,y1):
- if x1-x0==0:
- coeff2_directeur=1000000000
- ord2_origin=0
- else:
- coeff2_directeur=(y1-y0)/(x1-x0)
- ord2_origin=y0-coeff2_directeur*x0
- return(coeff2_directeur,ord2_origin)
- def angle(c0,c1):
- phi=math.atan((c1-c0)/(1+c1*c0))
- return(phi)
- def mouse_clicked(event):
- global selected_ball
- for i in range(1,nb_balls+1):
- event.widget.itemconfig(i, fill="black")
- event.widget.itemconfig(nb_balls+1, fill='white')
- selected_ball = event.widget.find_overlapping(event.x, event.y,event.x,event.y)
- event.widget.itemconfig(selected_ball, fill="red")
- if not len(selected_ball): return
- def left_move(event):
- if selected_ball != -1:
- canvas.move(selected_ball, -pixel_step, 0)
- def right_move(event):
- if selected_ball != -1:
- canvas.move(selected_ball, pixel_step, 0)
- def up_move(event):
- if selected_ball != -1:
- canvas.move(selected_ball, 0, -pixel_step)
- def down_move(event):
- if selected_ball != -1:
- canvas.move(selected_ball, 0, pixel_step)
- def simulation_launched():
- depls = []
- # Init speeds
- for ball in balls:
- depls.append([0,0])
- depls[-1] = [0, - pixel_step]
- white_coords = canvas.coords(white_ball)
- center_white_x0= white_coords[0]+ ball_size/2
- center_white_y0= white_coords[1] + ball_size/2
- for i in range(1,int(time_simulation/time_refresh)):
- white_coords = canvas.coords(white_ball)
- center_white_x=white_coords[0]+ ball_size/2
- center_white_y= white_coords[1] + ball_size/2
- for ball in balls:
- for ball2 in balls:
- if balls.index(ball2) > balls.index(ball):
- black_coords_1 = canvas.coords(ball)
- black_coords_2 = canvas.coords(ball2)
- center_black_x1 = black_coords_1[0]+ ball_size/2
- center_black_y1 = black_coords_1[1] + ball_size/2
- center_black_x2 = black_coords_2[0]+ ball_size/2
- center_black_y2 = black_coords_2[1] + ball_size/2
- radius = ball_size/2
- if math.sqrt(pow(center_black_x1 - center_black_x2,2)+pow(center_black_y1 - center_black_y2,2))<=2*radius:
- (contact_x, contact_y) = intersect(center_black_x1, center_black_x2, center_black_y1, center_black_y2)
- (coef_tang, ord_orig_tang) = tangente(center_black_x2, center_black_y2, contact_x, contact_y)
- #canvas.create_line(0,ord_orig_tang,window_width,ord_orig_tang+window_width*coef_tang,fill='red')
- (coef_droite, ord_orig_droite)=coeffdirecteur(center_white_x0,center_white_y0,contact_x,contact_y)
- #canvas.create_line(center_white_x0,center_white_y0,contact_x,contact_y,fill='blue')
- phi=angle(coef_droite,coef_tang)
- (v1_choc,v2_choc,theta1_choc,theta2_choc)=angle_apres_choc(66,0,phi,0)
- if coef_tang <0 :
- depls[balls.index(ball2)][0]=v1_choc*time_refresh*3*math.cos(theta1_choc+angle(coef_tang,0))
- depls[balls.index(ball2)][1]=v1_choc*time_refresh*3*math.sin(theta1_choc-angle(coef_tang,0))
- depls[balls.index(ball)][0]=v2_choc*time_refresh*3*math.cos(theta2_choc+angle(coef_tang,0))
- depls[balls.index(ball)][1]=-v2_choc*time_refresh*3*math.sin(theta2_choc+angle(coef_tang,0))
- else:
- depls[balls.index(ball2)][0]=v1_choc*time_refresh*3*math.cos(math.pi-theta1_choc-angle(coef_tang,0))
- depls[balls.index(ball2)][1]=v1_choc*time_refresh*3*math.sin(theta1_choc+angle(coef_tang,0))
- depls[balls.index(ball)][0]=v2_choc*time_refresh*3*math.cos(theta2_choc+angle(coef_tang,0))
- depls[balls.index(ball)][1]=-v2_choc*time_refresh*3*math.sin(theta2_choc+angle(coef_tang,0))
- canvas.move(ball,depls[balls.index(ball)][0],depls[balls.index(ball)][1])
- time.sleep(time_refresh)
- canvas.update()
- #Ecran de simulation
- #Initialisation
- def main():
- global balls, white_ball
- fenetre= Tk()
- fenetre.title("Simulateur de billard")
- Button(fenetre,text='Quit', command=fenetre.destroy).pack(side=BOTTOM)
- Button(fenetre,text="launch",command=simulation_launched).pack(side=BOTTOM)
- global canvas
- canvas=Canvas(fenetre,width=window_width,height=window_height, background='green')
- balls=[]
- for j in range(0,5):
- for i in range(0,5-j):
- initx= window_offsetx + (ball_size+ ball_distance)*i + (ball_offset_line)*j
- inity= window_offsety +(ball_size + ball_distance)*j
- ball=canvas.create_oval(initx,inity, initx+ ball_size,inity + ball_size,fill='black')
- balls.append(ball)
- white_ball = canvas.create_oval(window_width/2 - ball_size/2, window_height- ball_size,window_width/2+ball_size/2, window_height,fill='white')
- balls.append(white_ball)
- canvas.bind('<Button-1>', mouse_clicked)
- fenetre.bind('<Left>', left_move)
- fenetre.bind('<Right>', right_move)
- fenetre.bind('<Up>',up_move)
- fenetre.bind('<Down>', down_move)
- canvas.pack()
- fenetre.mainloop()
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement