Initial commit
This commit is contained in:
+954
@@ -0,0 +1,954 @@
|
||||
import tkinter
|
||||
from math import *
|
||||
from functools import partial
|
||||
|
||||
ver="1.1.0"
|
||||
|
||||
#Déclaration des variables
|
||||
#Tailles du menu (minimal pour la hauteur)
|
||||
WMENU = 200
|
||||
HMENU = 450
|
||||
|
||||
#Couleur des champs de saisie en erreur
|
||||
WRONG="tomato"
|
||||
|
||||
#Les différentes polices d'écritures utilisées dans le programme
|
||||
t3font = ('Times Roman', 18,'bold')
|
||||
t2font = ('Times Roman', 14,'bold')
|
||||
t1font = ('Times Roman', 12,'underline')
|
||||
pbfont = ('Times Roman',11,'bold')
|
||||
pfont = ('Times Roman',10)
|
||||
bfont = ('Times Roman',10)
|
||||
mfont = ('Times Roman',10,'bold')
|
||||
b2font = ('Times Roman',12,'bold')
|
||||
|
||||
curves=[] #Liste de stockage des courbes
|
||||
LENCURVES=10 #Nombre de variables d'une courbe
|
||||
ACTIVE=0 #Clé d'accès à une variable
|
||||
TYPE=1
|
||||
EQ=2
|
||||
XEQ=3
|
||||
YEQ=4
|
||||
PARMIN=5
|
||||
PARMAX=6
|
||||
PARSTEP=7
|
||||
CCOLOR=8
|
||||
SIZE=9
|
||||
|
||||
#TYPES
|
||||
PARAM=0
|
||||
POLAR=1
|
||||
YFX=2
|
||||
XFY=3
|
||||
|
||||
ntypes=["Arc parametré","Courbe polaire","y=f(x)","x=f(y)"]
|
||||
types={ntypes[PARAM]:PARAM,ntypes[POLAR]:POLAR,ntypes[YFX]:YFX,ntypes[XFY]:XFY}
|
||||
|
||||
#Idem pour le stockage des variables pour le graphique
|
||||
graph=[]
|
||||
LENGRAPH=14
|
||||
XMIN=0
|
||||
XMAX=1
|
||||
YMIN=2
|
||||
YMAX=3
|
||||
AXIS1=4
|
||||
AXIS2=5
|
||||
AXIS3=6
|
||||
AXIST1=7
|
||||
AXIST2=8
|
||||
AXISA=9
|
||||
GRID1=10
|
||||
GRID2=11
|
||||
GRID3=12
|
||||
GCOLOR=13
|
||||
|
||||
#Idem pour le stockage des variables des options
|
||||
opts=[]
|
||||
LENOPTS=4
|
||||
TX=0
|
||||
TY=1
|
||||
ZOOM=2
|
||||
RND=3
|
||||
|
||||
scr=0 #Courbe sélectionnée dans le menu
|
||||
page=1 #Page du menu
|
||||
|
||||
zoombe=False
|
||||
|
||||
def start():
|
||||
'''Lancement du programme'''
|
||||
global win #Définition de la fenetre en variable globale
|
||||
win=tkinter.Tk() #Création de la fenetre / démarrage de tkinter
|
||||
|
||||
#Création des variables tkinter (courbes, graph, options)
|
||||
tkvars([],[-5,5,-5,5,1,1,0,1,1,1,1,1,1,"white"],[500,500,0,3])
|
||||
#tkvars([],[-4.5,4.5,-6,3,0,0,0,0,0,0,0,0,0,"white"],[500,500,0,3])
|
||||
|
||||
#Ajout d'une nouvelle courbe suivant certains paramètres
|
||||
#newCurve(1,ntypes[POLAR],"cos(t)/(1-sin(t))","","",0,2*pi,0.1,"red",1)
|
||||
#newCurve(1,ntypes[PARAM],"","t**5-(10/3)*t**3","(-t**4+(11/5)*t**2)*3/2",-1.825,1.825,0.01,"red",2)
|
||||
#newCurve(1,ntypes[POLAR],"sin(2*t)","","",0,"2*pi",0.1,"red",1)
|
||||
|
||||
#Création des éléments de la fenetre
|
||||
paintwin()
|
||||
|
||||
|
||||
def paintwin():
|
||||
global win,cv #le canvas doit être global pour l'accès d'autres fonctions
|
||||
|
||||
#Création de la fenetre
|
||||
width=opts[TX].get()+WMENU #Largeur en fonction du canvas + menu
|
||||
#Hauteur en fonction du canvas mais minimum du menu
|
||||
if(opts[TY].get()<HMENU):
|
||||
height=HMENU
|
||||
else:
|
||||
height=opts[TY].get()
|
||||
|
||||
win.title("Graph (version "+ver+")") #Titre de la fenetre
|
||||
win.resizable(width=False,height=False) #Fenetre non redimensionnable
|
||||
#Application des tailles de la fenetre
|
||||
win.geometry(""+str(width)+"x"+str(height))
|
||||
|
||||
#Création du canvas
|
||||
|
||||
|
||||
#Création des evenements
|
||||
win.bind("<Return>",enter) #La touche entrée appelle la fonction enter
|
||||
win.bind("<MouseWheel>",zoom)
|
||||
|
||||
#Cration du menu avec rafraichissement du canvas
|
||||
menu(1,True,False)
|
||||
|
||||
#Fin de la création de la fenetre
|
||||
win.mainloop()
|
||||
|
||||
|
||||
def menu(pagea,repaint,same,*args):
|
||||
global menuf
|
||||
|
||||
#Si on demande de rafraichir le canvas, on appelle paint
|
||||
if(repaint):
|
||||
paint()
|
||||
|
||||
#On essaye de détruire l'ancien menu, menuf
|
||||
try:
|
||||
menuf.destroy()
|
||||
except NameError: #Si menuf n'existe pas, on ne fais rien
|
||||
pass
|
||||
except tkinter.TclError:
|
||||
pass
|
||||
|
||||
#On crée un nouveau conteneur d'élements, menuf
|
||||
menuf=tkinter.Frame(win)
|
||||
|
||||
#Si on demande juste de rafraichir le menu, on prend page comme réference
|
||||
if(same):
|
||||
if(page==1):
|
||||
page1(menuf) #Ajouts des élements de la page 1 sur menuf
|
||||
if(page==2):
|
||||
page2(menuf)
|
||||
if(page==3):
|
||||
page3(menuf)
|
||||
else: #Sinon on prend le paramètre pagea pour changer de page
|
||||
if(pagea==1):
|
||||
page1(menuf)
|
||||
if(pagea==2):
|
||||
page2(menuf)
|
||||
if(pagea==3):
|
||||
page3(menuf)
|
||||
|
||||
#On positionne le menu à droite du canvas
|
||||
#side LEFT signifie le sens d'ajout des élements
|
||||
#fill Y signifie que l'élement doit remplir toute la hauteur disponible
|
||||
menuf.grid(column=1,row=0,sticky=tkinter.N)
|
||||
|
||||
def menuBar(frame,n):
|
||||
#Barre de navigation du menu
|
||||
|
||||
men=tkinter.Frame(frame) #Nouveau conteneur ajouté à celui en paramètre
|
||||
#Les différents boutons
|
||||
#partial permet de rajouter des paramètres à une fonction de commande
|
||||
b1=tkinter.Button(men,text="Courbes",font=mfont,command=partial(menu,1,False,False),width=7)
|
||||
b2=tkinter.Button(men,text="Graph",font=mfont,command=partial(menu,2,False,False),width=7)
|
||||
b3=tkinter.Button(men,text="Options",font=mfont,command=partial(menu,3,False,False),width=7)
|
||||
#Modification du bouton de la page actuelle
|
||||
if(n==1):
|
||||
b1.config(state=tkinter.DISABLED,bg="yellow")
|
||||
if(n==2):
|
||||
b2.config(state=tkinter.DISABLED,bg="yellow")
|
||||
if(n==3):
|
||||
b3.config(state=tkinter.DISABLED,bg="yellow")
|
||||
#Position des boutons sur une grille
|
||||
b1.grid(column=0,row=0)
|
||||
b2.grid(column=1,row=0)
|
||||
b3.grid(column=2,row=0)
|
||||
men.pack(fill=tkinter.X)
|
||||
|
||||
def page1(frame):
|
||||
global page
|
||||
page=1
|
||||
|
||||
f=tkinter.Frame(frame) #Nouveau conteneur ajouté à celui en paramètre
|
||||
|
||||
menuBar(f,1) #On ajoute les boutons sur f
|
||||
|
||||
f1=tkinter.Frame(f) #Conteneur des boutons de navigation des ourbes
|
||||
#celui de droite appelle la fonction move(-1)
|
||||
#et affiche le nombre de courbes avant
|
||||
b1=tkinter.Button(f1,text=("<= ("+str(scr)+")"),font=bfont,command=partial(move,-1),width=11)
|
||||
if(scr==0): #Si il n'y as pas de courbes avant, il est désctivé
|
||||
b1.config(state=tkinter.DISABLED)
|
||||
b1.grid(column=0,row=0) #on l'ajoute sur une grille
|
||||
del b1 #On libère la mémoire
|
||||
#le bouton de gauche affiche le nombre de courbes apres
|
||||
b2=tkinter.Button(f1,text=("("+str(len(curves)-scr-1)+") =>"),font=bfont,command=partial(move,1),width=11)
|
||||
#S'il ni y en a pas, on change son nom et sa commande
|
||||
if(scr==len(curves)-1 or len(curves)==0):
|
||||
b2.config(text="Nouvelle courbe",command=badd)
|
||||
b2.grid(column=1,row=0)
|
||||
del b2
|
||||
f1.pack(fill=tkinter.X) #on pack l'ensemble des boutons
|
||||
|
||||
#Si scr se trouve dans la liste des courbes
|
||||
#Il se peut que non si il n'y a pas de courbes
|
||||
if(len(curves)>scr):
|
||||
#A chaque element de saisie se trouve une variable de la liste du début
|
||||
#la modification s'effectue en instantanée mais pas le rafraichissement
|
||||
#du graph ici géré par entrée
|
||||
#Cela permet aussi de choisir quand on a finis l'edition
|
||||
#pour eviter les erreurs constamment
|
||||
f1=tkinter.LabelFrame(f,text=("Courbe "+str(scr+1)),padx=5,pady=5)
|
||||
|
||||
f2=tkinter.Frame(f1)
|
||||
|
||||
tkinter.Label(f2,text="Type :",font=pfont).grid(column=0,row=0)
|
||||
tkinter.OptionMenu(f2,curves[scr][TYPE],*ntypes,command=ctype).grid(column=1,row=0)
|
||||
|
||||
f2.pack(fill=tkinter.X)
|
||||
|
||||
if(types[curves[scr][TYPE].get()]==PARAM):
|
||||
f2=tkinter.LabelFrame(f1,text="Equations paramétriques",padx=5,pady=5)
|
||||
tkinter.Label(f2,text="x(t)=",font=pfont).grid(column=0,row=0)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][XEQ],width=19)
|
||||
try:
|
||||
ft(curves[scr][XEQ].get(),0.01)
|
||||
except(ZeroDivisionError):
|
||||
pass
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=0)
|
||||
|
||||
tkinter.Label(f2,text="y(t)=",font=pfont).grid(column=0,row=1)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][YEQ],width=19)
|
||||
try:
|
||||
ft(curves[scr][YEQ].get(),0.01)
|
||||
except(ZeroDivisionError):
|
||||
pass
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=1)
|
||||
|
||||
f2.pack(fill=tkinter.X)
|
||||
else:
|
||||
f2=tkinter.LabelFrame(f1,text="Equation",padx=5,pady=5)
|
||||
if(types[curves[scr][TYPE].get()]==POLAR):
|
||||
tkinter.Label(f2,text="ρ(t)=",font=pfont).grid(column=0,row=0)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][EQ],width=19)
|
||||
try:
|
||||
ft(curves[scr][EQ].get(),0.01)
|
||||
except(ZeroDivisionError):
|
||||
pass
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=0)
|
||||
|
||||
if(types[curves[scr][TYPE].get()]==YFX):
|
||||
tkinter.Label(f2,text="y=f(x)=",font=pfont).grid(column=0,row=0)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][EQ],width=19)
|
||||
try:
|
||||
x=0.01
|
||||
eval(curves[scr][EQ].get())
|
||||
except(ZeroDivisionError):
|
||||
pass
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=0)
|
||||
|
||||
if(types[curves[scr][TYPE].get()]==XFY):
|
||||
tkinter.Label(f2,text="x=f(y)=",font=pfont).grid(column=0,row=0)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][EQ],width=19)
|
||||
try:
|
||||
y=0.01
|
||||
eval(curves[scr][EQ].get())
|
||||
except(ZeroDivisionError):
|
||||
pass
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=0)
|
||||
|
||||
f2.pack(fill=tkinter.X)
|
||||
if(types[curves[scr][TYPE].get()]==PARAM or types[curves[scr][TYPE].get()]==POLAR):
|
||||
f2=tkinter.LabelFrame(f1,text="Paramètre t",padx=5,pady=5)
|
||||
if(types[curves[scr][TYPE].get()]==POLAR):
|
||||
f2.config(text="Paramètre t (θ)")
|
||||
tkinter.Label(f2,text="Min:",font=pfont).grid(column=0,row=0)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][PARMIN],width=6)
|
||||
try:
|
||||
int(eval(curves[scr][PARMIN].get()))
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=0)
|
||||
|
||||
tkinter.Label(f2,text="Max:",font=pfont).grid(column=2,row=0)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][PARMAX],width=6)
|
||||
try:
|
||||
int(eval(curves[scr][PARMAX].get()))
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=3,row=0)
|
||||
|
||||
tkinter.Label(f2,text="Pas:",font=pfont).grid(column=0,row=1)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][PARSTEP],width=6)
|
||||
try:
|
||||
int(1/eval(curves[scr][PARSTEP].get()))
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=1)
|
||||
|
||||
f2.pack(fill=tkinter.X)
|
||||
|
||||
f2=tkinter.LabelFrame(f1,text="Autre",padx=5,pady=5)
|
||||
tkinter.Label(f2,text="Couleur: ",font=pfont).grid(column=0,row=0)
|
||||
tkinter.Entry(f2,textvariable=curves[scr][CCOLOR],width=10).grid(column=1,row=0)
|
||||
tkinter.Label(f2,text="Epaisseur:",font=pfont).grid(column=0,row=1)
|
||||
|
||||
e=tkinter.Entry(f2,textvariable=curves[scr][SIZE],width=10)
|
||||
try:
|
||||
int(curves[scr][SIZE].get())
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=1)
|
||||
|
||||
f2.pack(fill=tkinter.X)
|
||||
|
||||
f2=tkinter.Frame(f1,padx=5,pady=5)
|
||||
tkinter.Button(f2,text="Supprimer",width=12,command=partial(delCurve,scr),font=bfont).grid(column=0,row=0)
|
||||
tkinter.Checkbutton(f2,text="Visible",variable=curves[scr][ACTIVE],command=paint).grid(column=1,row=0)
|
||||
f2.pack(fill=tkinter.X)
|
||||
|
||||
f2.pack()
|
||||
|
||||
f1.pack(fill=tkinter.Y)
|
||||
f.pack(fill=tkinter.BOTH,anchor=tkinter.N)
|
||||
|
||||
def page2(frame):
|
||||
global page
|
||||
page=2
|
||||
#mêmes principes que précedemment
|
||||
f=tkinter.Frame(frame)
|
||||
|
||||
menuBar(f,2)
|
||||
|
||||
f1=tkinter.LabelFrame(f,text="Fenêtre",padx=5,pady=5)
|
||||
|
||||
f2=tkinter.Frame(f1)
|
||||
|
||||
f3=tkinter.LabelFrame(f2,text="X",padx=5,pady=5)
|
||||
tkinter.Label(f3,text="min:",font=pfont).grid(column=0,row=0)
|
||||
|
||||
e=tkinter.Entry(f3,textvariable=graph[XMIN],width=7)
|
||||
try:
|
||||
int(eval(graph[XMIN].get()))
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=0)
|
||||
|
||||
tkinter.Label(f3,text="max:",font=pfont).grid(column=2,row=0)
|
||||
|
||||
e=tkinter.Entry(f3,textvariable=graph[XMAX],width=7)
|
||||
try:
|
||||
int(eval(graph[XMAX].get()))
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=3,row=0)
|
||||
|
||||
f3.grid(column=0,row=0)
|
||||
|
||||
f3=tkinter.LabelFrame(f2,text="Y",padx=5,pady=5)
|
||||
tkinter.Label(f3,text="min:",font=pfont).grid(column=0,row=0)
|
||||
|
||||
e=tkinter.Entry(f3,textvariable=graph[YMIN],width=7)
|
||||
try:
|
||||
int(eval(graph[YMIN].get()))
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=0)
|
||||
|
||||
tkinter.Label(f3,text="max:",font=pfont).grid(column=2,row=0)
|
||||
|
||||
e=tkinter.Entry(f3,textvariable=graph[YMAX],width=7)
|
||||
try:
|
||||
int(eval(graph[YMAX].get()))
|
||||
except(NameError):
|
||||
e.config(bg=WRONG)
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=3,row=0)
|
||||
|
||||
f3.grid(column=0,row=1)
|
||||
|
||||
f2.pack(fill=tkinter.X)
|
||||
|
||||
f2=tkinter.Frame(f1)
|
||||
tkinter.Button(f2,text="Orthonormer X",command=orthx).grid(column=0,row=0)
|
||||
tkinter.Button(f2,text="Orthonormer Y",command=orthy).grid(column=1,row=0)
|
||||
f2.pack(fill=tkinter.X)
|
||||
st=tkinter.NORMAL
|
||||
if(not(azoomenable)):
|
||||
st=tkinter.DISABLED
|
||||
tkinter.Button(f1,text="Zoom auto",command=azoom,state=st).pack(fill=tkinter.X)
|
||||
|
||||
f1.pack(fill=tkinter.BOTH)
|
||||
|
||||
f1=tkinter.LabelFrame(f,text="Graduation",padx=5,pady=5)
|
||||
|
||||
f2=tkinter.LabelFrame(f1,text="Axes",padx=5,pady=5)
|
||||
tkinter.Checkbutton(f2,text="1 ",variable=graph[AXIS1],command=paint,width=7).pack()
|
||||
tkinter.Checkbutton(f2,text="0.5",variable=graph[AXIS2],command=paint,width=7).pack()
|
||||
tkinter.Checkbutton(f2,text="0.1",variable=graph[AXIS3],command=paint,width=7).pack()
|
||||
f2.grid(column=0,row=0)
|
||||
|
||||
f2=tkinter.LabelFrame(f1,text="Grille",padx=5,pady=5)
|
||||
tkinter.Checkbutton(f2,text="1 ",variable=graph[GRID1],command=paint,width=7).pack()
|
||||
tkinter.Checkbutton(f2,text="0.5",variable=graph[GRID2],command=paint,width=7).pack()
|
||||
tkinter.Checkbutton(f2,text="0.1",variable=graph[GRID3],command=paint,width=7).pack()
|
||||
f2.grid(column=1,row=0)
|
||||
|
||||
f1.pack(fill=tkinter.BOTH)
|
||||
|
||||
f1=tkinter.LabelFrame(f,text="Autre",padx=5,pady=5)
|
||||
f2=tkinter.Frame(f1)
|
||||
tkinter.Label(f2,text="Fond:",font=pfont).grid(column=0,row=0)
|
||||
tkinter.Entry(f2,textvariable=graph[GCOLOR],width=18).grid(column=1,row=0)
|
||||
f2.pack()
|
||||
tkinter.Checkbutton(f1,text="Titre des axes",variable=graph[AXIST1],command=paint).pack(anchor=tkinter.NW)
|
||||
tkinter.Checkbutton(f1,text="Axes flechés",variable=graph[AXISA],command=paint).pack(anchor=tkinter.NW)
|
||||
tkinter.Checkbutton(f1,text="Unités",variable=graph[AXIST2],command=paint).pack(anchor=tkinter.NW)
|
||||
f1.pack(fill=tkinter.X)
|
||||
|
||||
f.pack(fill=tkinter.BOTH,anchor=tkinter.N)
|
||||
|
||||
|
||||
def page3(frame):
|
||||
global page
|
||||
page=3
|
||||
#idem
|
||||
f=tkinter.Frame(frame)
|
||||
|
||||
menuBar(f,3)
|
||||
|
||||
f1=tkinter.LabelFrame(f,text="Taille du graph",padx=5,pady=5)
|
||||
tkinter.Label(f1,text="X:",font=pfont).grid(column=0,row=0)
|
||||
|
||||
e=tkinter.Entry(f1,textvariable=opts[TX],width=6)
|
||||
try:
|
||||
int(opts[TX].get())
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=1,row=0)
|
||||
|
||||
tkinter.Label(f1,text="Y:",font=pfont).grid(column=2,row=0)
|
||||
|
||||
e=tkinter.Entry(f1,textvariable=opts[TY],width=6)
|
||||
try:
|
||||
int(opts[TX].get())
|
||||
except:
|
||||
e.config(bg=WRONG)
|
||||
e.grid(column=3,row=0)
|
||||
|
||||
tkinter.Button(f1,text="changer",font=bfont,command=restart).grid(column=4,row=0)
|
||||
f1.pack(fill=tkinter.X)
|
||||
|
||||
f1=tkinter.LabelFrame(f,text="Autre",padx=5,pady=5)
|
||||
tkinter.Checkbutton(f1,text="Zoomer localement",variable=opts[ZOOM]).pack(anchor=tkinter.NW)
|
||||
f2=tkinter.Frame(f1)
|
||||
tkinter.Label(f2,text="Précision déplacements:",font=pfont).grid(column=0,row=0)
|
||||
tkinter.Entry(f2,textvariable=opts[RND],width=5).grid(column=1,row=0)
|
||||
f2.pack()
|
||||
f1.pack(fill=tkinter.X)
|
||||
|
||||
f1=tkinter.LabelFrame(f,text="Informations",padx=5,pady=5)
|
||||
tkinter.Label(f1,text="Commandes",font=pbfont).pack()
|
||||
tkinter.Label(f1,text="Entrée - Valider les champs\nClic gauche - Déplacer l'origine\nClic droit - Dézoomer\nClic droit (glisser) - Zoomer\nMolette - Zoomer/Dézoomer",font=pfont).pack()
|
||||
tkinter.Label(f1,text="Divers",font=pbfont).pack()
|
||||
tkinter.Label(f1,text="\"pi\" est valide dans l'écriture\ndes fonctions et valeurs.",font=pfont).pack()
|
||||
tkinter.Label(f1,text="A propos",font=pbfont).pack()
|
||||
tkinter.Label(f1,text="Graph version "+ver+"\nDéveloppé par : Clément Gouin\nclement.gouin@reseau.eseo.fr",font=pfont).pack()
|
||||
f1.pack(fill=tkinter.X)
|
||||
|
||||
f.pack(fill=tkinter.BOTH,anchor=tkinter.N)
|
||||
|
||||
def paint():
|
||||
global cv,autozoom,azoomenable
|
||||
try:
|
||||
cv.destroy()
|
||||
except NameError:
|
||||
pass
|
||||
except tkinter.TclError:
|
||||
pass
|
||||
cv=tkinter.Canvas(win,width=opts[TX].get(),height=opts[TY].get())
|
||||
cv.grid(column=0,row=0,sticky=tkinter.N)
|
||||
cv.bind("<Button-1>",bu1)
|
||||
cv.bind("<Button-3>",bu3)
|
||||
cv.bind("<B3-Motion>",bu3m)
|
||||
cv.bind("<ButtonRelease-3>",bu3r)
|
||||
#Une des fonctions principales du programme
|
||||
#elle permet le rafraichissement du canvas
|
||||
|
||||
#on crée tout d'abord le fond par un rectangle,
|
||||
#on efface rien, on colle juste le fond par dessus le précédent
|
||||
cv.create_rectangle(2,2,opts[TX].get(),opts[TY].get()-3,fill=graph[GCOLOR].get())
|
||||
#suivant les paramètres, on affiche les grilles et axes ou non
|
||||
if(graph[GRID3].get()):
|
||||
gridf(0.1,"grey90")
|
||||
if(graph[GRID2].get()):
|
||||
gridf(0.5,"grey80")
|
||||
if(graph[GRID1].get()):
|
||||
gridf(1,"grey70")
|
||||
#Ici on met en paramètre qui est l'axe maitre,
|
||||
#car c'est lui qui affiche les noms des axes, les unités et les fleches
|
||||
if(graph[AXIS1].get()):
|
||||
axisf(1,"grey40",4,True) #L'axe 1 est toujours maitre s'il est actif
|
||||
if(graph[AXIS2].get()):
|
||||
axisf(0.5,"grey40",2,(not(graph[AXIS1].get()))) #Sinon c'est le 0.5 etc.
|
||||
if(graph[AXIS3].get()):
|
||||
axisf(0.1,"grey40",1,(not(graph[AXIS1].get()) and not(graph[AXIS2].get())))
|
||||
#enfin on affiche les courbes successivement et si elles sont affichées
|
||||
autozoom=[0,0,0,0]
|
||||
azoomenable=False
|
||||
if(len(curves)>0):
|
||||
for k in range(len(curves)):
|
||||
if(curves[k][ACTIVE].get()):
|
||||
curvef(k,curves[k][CCOLOR].get(),curves[k][SIZE].get())
|
||||
if(zoombe):
|
||||
cv.create_rectangle(zoomb[0][0],zoomb[0][1],zoomb[1][0],zoomb[1][1],outline="red")
|
||||
|
||||
|
||||
def gridf(pas,col):
|
||||
#On récupère les différentes variables
|
||||
try:
|
||||
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
factx=tx/(abs(xmax-xmin))
|
||||
facty=ty/(abs(ymax-ymin))
|
||||
n = int((2+abs(ymax-ymin))/pas)
|
||||
d=abs(ymin)-abs(int(ymin))
|
||||
for k in range(n+1):
|
||||
cv.create_line(0,ty-(k*pas+d-1)*facty,tx,ty-(k*pas+d-1)*facty,fill=col)
|
||||
n = int((2+abs(xmax-xmin))/pas)
|
||||
d=abs(xmin)-abs(int(xmin))
|
||||
for k in range(n+1):
|
||||
cv.create_line((k*pas+d-1)*factx,0,(k*pas+d-1)*factx,ty,fill=col)
|
||||
|
||||
def axisf(pas,col,t1,high):
|
||||
try:
|
||||
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
factx=tx/(abs(xmax-xmin))
|
||||
facty=ty/(abs(ymax-ymin))
|
||||
if(min(xmin,xmax)<0 and max(xmin,xmax)>0):
|
||||
n = int((2+abs(ymax-ymin))/pas)
|
||||
d=abs(min(ymin,ymax))-abs(int(min(ymin,ymax)))
|
||||
if(high and graph[AXISA].get()):
|
||||
if(ymax>ymin):
|
||||
cv.create_line(-sgn(xmin,xmax)*xmin*factx,0,-sgn(xmin,xmax)*xmin*factx,ty,fill=col,arrow=tkinter.FIRST)
|
||||
else:
|
||||
cv.create_line(-sgn(xmin,xmax)*xmin*factx,0,-sgn(xmin,xmax)*xmin*factx,ty,fill=col,arrow=tkinter.LAST)
|
||||
else:
|
||||
cv.create_line(-sgn(xmin,xmax)*xmin*factx,0,-sgn(xmin,xmax)*xmin*factx,tx,fill=col)
|
||||
|
||||
for k in range(n+1):
|
||||
cv.create_line(-sgn(xmin,xmax)*xmin*factx-t1,ty-(k*pas+d-1)*facty,-sgn(xmin,xmax)*xmin*factx+t1+1,ty-(k*pas+d-1)*facty,fill=col)
|
||||
if(high and graph[AXIST2].get() and min(ymin,ymax)<pas and max(ymin,ymax)>pas):
|
||||
cv.create_text(-10-sgn(xmin,xmax)*xmin*factx,ty-(pas-ymin)*facty,text=str(pas),font=pfont,fill=col)
|
||||
if(high and graph[AXIST1].get()):
|
||||
if(ymax>ymin):
|
||||
cv.create_text(-10-xmin*factx,15,text="y",font=pfont,fill=col)
|
||||
else:
|
||||
cv.create_text(-10-xmin*factx,ty-35,text="y",font=pfont,fill=col)
|
||||
|
||||
if(min(ymin,ymax)<0 and max(ymin,ymax)>0):
|
||||
n = int((2+abs(xmax-xmin))/pas)
|
||||
d=abs(min(xmin,xmax))-abs(int(min(xmin,xmax)))
|
||||
if(high and graph[AXISA].get()):
|
||||
if(xmax>xmin):
|
||||
cv.create_line(0,ty+sgn(ymin,ymax)*ymin*facty,tx,ty+sgn(ymin,ymax)*ymin*facty,fill=col,arrow=tkinter.LAST)
|
||||
else:
|
||||
cv.create_line(0,ty+sgn(ymin,ymax)*ymin*facty,tx,ty+sgn(ymin,ymax)*ymin*facty,fill=col,arrow=tkinter.FIRST)
|
||||
else:
|
||||
cv.create_line(0,ty+sgn(ymin,ymax)*ymin*facty,tx,ty+sgn(ymin,ymax)*ymin*facty,fill=col)
|
||||
for k in range(n+1):
|
||||
cv.create_line((k*pas+d-1)*factx,ty+sgn(ymin,ymax)*ymin*facty-t1,(k*pas+d-1)*factx,ty+sgn(ymin,ymax)*ymin*facty+t1+1,fill=col)
|
||||
if(high and graph[AXIST2].get() and min(xmin,xmax)<pas and max(xmin,xmax)>pas):
|
||||
cv.create_text((pas-xmin)*factx,ty+sgn(ymin,ymax)*ymin*facty+15,text=str(pas),font=pfont,fill=col)
|
||||
if(high and graph[AXIST1].get()):
|
||||
if(xmax>xmin):
|
||||
cv.create_text(tx-10,ty+ymin*facty+15,text="x",font=pfont,fill=col)
|
||||
else:
|
||||
cv.create_text(10,ty+ymin*facty+15,text="x",font=pfont,fill=col)
|
||||
|
||||
def curvef(k,col,ta):
|
||||
global curves,azoomenable,autozoom
|
||||
try:
|
||||
tx,ty,xmax,xmin,ymax,ymin,parmin,parmax,parstep=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get()),eval(curves[k][PARMIN].get()),eval(curves[k][PARMAX].get()),eval(curves[k][PARSTEP].get())
|
||||
1/parstep
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
factx=tx/(xmax-xmin)
|
||||
facty=ty/(ymax-ymin)
|
||||
if(types[curves[k][TYPE].get()]==PARAM):
|
||||
azoomenable=True
|
||||
if(types[curves[k][TYPE].get()]==POLAR):
|
||||
azoomenable=True
|
||||
curves[k][XEQ].set("("+curves[k][EQ].get()+")*cos(t)")
|
||||
curves[k][YEQ].set("("+curves[k][EQ].get()+")*sin(t)")
|
||||
if(types[curves[k][TYPE].get()]==YFX):
|
||||
curves[k][XEQ].set("t")
|
||||
curves[k][YEQ].set(curves[k][EQ].get().replace('x','t'))
|
||||
curves[k][PARMIN].set(xmin)
|
||||
curves[k][PARMAX].set(xmax)
|
||||
curves[k][PARSTEP].set(abs(xmax-xmin)/(tx))
|
||||
if(types[curves[k][TYPE].get()]==XFY):
|
||||
curves[k][YEQ].set("t")
|
||||
curves[k][XEQ].set(curves[k][EQ].get().replace("y","t"))
|
||||
curves[k][PARMIN].set(ymin)
|
||||
curves[k][PARMAX].set(ymax)
|
||||
curves[k][PARSTEP].set(abs(ymax-ymin)/(ty))
|
||||
|
||||
n = int((parmax-parmin)/parstep)+2
|
||||
li=[];
|
||||
for k1 in range(n):
|
||||
t=parmin+k1*parstep
|
||||
try:
|
||||
li+=[[ft(curves[k][XEQ].get(),t),ft(curves[k][YEQ].get(),t),True]]
|
||||
if(azoomenable):
|
||||
if(li[k1][0]>autozoom[XMAX]):
|
||||
autozoom[XMAX]=li[k1][0]
|
||||
if(li[k1][0]<autozoom[XMIN]):
|
||||
autozoom[XMIN]=li[k1][0]
|
||||
if(li[k1][1]>autozoom[YMAX]):
|
||||
autozoom[YMAX]=li[k1][1]
|
||||
if(li[k1][1]<autozoom[YMIN]):
|
||||
autozoom[YMIN]=li[k1][1]
|
||||
except(ZeroDivisionError):
|
||||
li+=[[0,0,False]]
|
||||
for k1 in range(n):
|
||||
li[k1][0]=int((li[k1][0]-xmin)*factx)
|
||||
li[k1][1]=ty-int((li[k1][1]-ymin)*facty)
|
||||
for k1 in range(n-1):
|
||||
if(li[k1][2] and li[k1+1][2] and
|
||||
((0<li[k1][0]<tx and 0<li[k1][1]<ty) or
|
||||
(0<li[k1+1][0]<tx and 0<li[k1+1][1]<ty))):
|
||||
cv.create_line(li[k1][0],li[k1][1],li[k1+1][0],li[k1+1][1],fill=col,width=ta)
|
||||
|
||||
def restart():
|
||||
global win,curves,graph,opts,scr
|
||||
#Lorsque l'on veut modifier la fenetre, on doit la détruire
|
||||
#et cela détruit toutes les variables tkinter, on les sauvegarde
|
||||
#donc dans des listes et on les recrée
|
||||
|
||||
if(len(curves)>0):
|
||||
savcurves = []
|
||||
for k in range(len(curves)):
|
||||
temp=[]
|
||||
for l in range(len(curves[k])):
|
||||
temp+=[curves[k][l].get()]
|
||||
savcurves+=[temp[:]]
|
||||
savgraph=[]
|
||||
for k in range(len(graph)):
|
||||
savgraph+=[graph[k].get()]
|
||||
savopts=[]
|
||||
for k in range(len(opts)):
|
||||
savopts+=[opts[k].get()]
|
||||
win.destroy()
|
||||
win=tkinter.Tk()
|
||||
tkvars(savcurves,savgraph,savopts)
|
||||
paintwin()
|
||||
|
||||
|
||||
|
||||
def tkvars(cu,ax,op):
|
||||
global curves,graph,opts
|
||||
#Définitions des variables et de leur type
|
||||
|
||||
curves=[]
|
||||
if(len(cu)>0):
|
||||
for k in range(len(cu)):
|
||||
newCurve(cu[k][ACTIVE],cu[k][TYPE],cu[k][EQ],cu[k][XEQ],cu[k][YEQ],cu[k][PARMIN],cu[k][PARMAX],cu[k][PARSTEP],cu[k][CCOLOR],cu[k][SIZE])
|
||||
|
||||
graph=LENGRAPH*[None]
|
||||
graph[XMAX]=tkinter.StringVar()
|
||||
graph[XMIN]=tkinter.StringVar()
|
||||
graph[YMIN]=tkinter.StringVar()
|
||||
graph[YMAX]=tkinter.StringVar()
|
||||
graph[AXIS1]=tkinter.IntVar()
|
||||
graph[AXIS2]=tkinter.IntVar()
|
||||
graph[AXIS3]=tkinter.IntVar()
|
||||
graph[AXIST1]=tkinter.IntVar()
|
||||
graph[AXIST2]=tkinter.IntVar()
|
||||
graph[AXISA]=tkinter.IntVar()
|
||||
graph[GRID1]=tkinter.IntVar()
|
||||
graph[GRID2]=tkinter.IntVar()
|
||||
graph[GRID3]=tkinter.IntVar()
|
||||
graph[GCOLOR]=tkinter.StringVar()
|
||||
for k in range(len(graph)):
|
||||
graph[k].set(ax[k])
|
||||
|
||||
opts=LENOPTS*[None]
|
||||
opts[TX]=tkinter.IntVar()
|
||||
opts[TY]=tkinter.IntVar()
|
||||
opts[ZOOM]=tkinter.IntVar()
|
||||
opts[RND]=tkinter.IntVar()
|
||||
for k in range(len(opts)):
|
||||
opts[k].set(op[k])
|
||||
|
||||
def newCurve(active,typef,eq,xeq,yeq,tmin,tmax,tstep,color,size):
|
||||
global curves,scr
|
||||
#Ajout d'une courbe
|
||||
|
||||
curves+=[LENCURVES*[None]]
|
||||
n=len(curves)-1
|
||||
curves[n][ACTIVE]=tkinter.IntVar()
|
||||
curves[n][TYPE]=tkinter.StringVar()
|
||||
curves[n][EQ]=tkinter.StringVar()
|
||||
curves[n][XEQ]=tkinter.StringVar()
|
||||
curves[n][YEQ]=tkinter.StringVar()
|
||||
curves[n][PARMIN]=tkinter.StringVar()
|
||||
curves[n][PARMAX]=tkinter.StringVar()
|
||||
curves[n][PARSTEP]=tkinter.StringVar()
|
||||
curves[n][CCOLOR]=tkinter.StringVar()
|
||||
curves[n][SIZE]=tkinter.IntVar()
|
||||
curves[n][ACTIVE].set(active)
|
||||
curves[n][TYPE].set(typef)
|
||||
curves[n][EQ].set(eq)
|
||||
curves[n][XEQ].set(xeq)
|
||||
curves[n][YEQ].set(yeq)
|
||||
curves[n][PARMIN].set(tmin)
|
||||
curves[n][PARMAX].set(tmax)
|
||||
curves[n][PARSTEP].set(tstep)
|
||||
curves[n][CCOLOR].set(color)
|
||||
curves[n][SIZE].set(size)
|
||||
|
||||
def delCurve(n):
|
||||
global curves,scr
|
||||
#Destruction d'une courbe
|
||||
|
||||
del curves[n]
|
||||
scr-=1
|
||||
menu(1,True,False)
|
||||
|
||||
|
||||
def enter(event):
|
||||
#Evenement correspondand à l'appui de la touche entrée
|
||||
menu(1,True,True)
|
||||
|
||||
def bu1(event):
|
||||
global graph
|
||||
#Evenement du clic de la souris
|
||||
#le graph ce centre sur ce clic
|
||||
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
|
||||
|
||||
factx=tx/(xmax-xmin)
|
||||
facty=ty/(ymax-ymin)
|
||||
dx=(event.x-tx/2)/factx
|
||||
dy=(event.y-ty/2)/facty
|
||||
graph[XMAX].set(rnd(xmax+dx,opts[RND].get()))
|
||||
graph[XMIN].set(rnd(xmin+dx,opts[RND].get()))
|
||||
graph[YMAX].set(rnd(ymax-dy,opts[RND].get()))
|
||||
graph[YMIN].set(rnd(ymin-dy,opts[RND].get()))
|
||||
menu(2,True,True)
|
||||
|
||||
def bu3(event):
|
||||
global zoomb,zoombe,win
|
||||
zoombe=True
|
||||
zoomb=[[event.x,event.y],[event.x,event.y]]
|
||||
win.after(20,paint)
|
||||
|
||||
def bu3m(event):
|
||||
global zoomb,win
|
||||
zoomb[1]=[event.x,event.y]
|
||||
win.after(20,paint)
|
||||
|
||||
|
||||
def bu3r(event):
|
||||
global zoomb,zoombe,graph
|
||||
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
|
||||
zoombe=False
|
||||
if(abs(zoomb[0][0]-zoomb[1][0])<5 and abs(zoomb[0][1]-zoomb[1][1])<5):
|
||||
factx=opts[TX].get()/(abs(xmax-xmin))
|
||||
facty=opts[TY].get()/(abs(ymax-ymin))
|
||||
factx/=2
|
||||
facty/=2
|
||||
dx=(opts[TX].get()-(xmax-xmin)*factx)/factx
|
||||
dy=(opts[TY].get()-(ymax-ymin)*factx)/factx
|
||||
graph[XMAX].set(rnd(xmax+dx/2,opts[RND].get()))
|
||||
graph[XMIN].set(rnd(xmin-dx/2,opts[RND].get()))
|
||||
graph[YMAX].set(rnd(ymax+dy/2,opts[RND].get()))
|
||||
graph[YMIN].set(rnd(ymin-dy/2,opts[RND].get()))
|
||||
else:
|
||||
factx=opts[TX].get()/(abs(xmax-xmin))
|
||||
facty=opts[TY].get()/(abs(ymax-ymin))
|
||||
graph[XMIN].set(rnd(xmin+zoomb[0][0]/factx,opts[RND].get()))
|
||||
graph[XMAX].set(rnd(xmin+zoomb[1][0]/factx,opts[RND].get()))
|
||||
graph[YMIN].set(rnd(ymax-zoomb[0][1]/facty,opts[RND].get()))
|
||||
graph[YMAX].set(rnd(ymax-zoomb[1][1]/facty,opts[RND].get()))
|
||||
menu(1,True,True)
|
||||
|
||||
|
||||
def zoom(event):
|
||||
global graph
|
||||
#Evenement de la molette de la souris
|
||||
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
|
||||
|
||||
zoom = event.delta/120
|
||||
factx=opts[TX].get()/(abs(xmax-xmin))
|
||||
facty=opts[TY].get()/(abs(ymax-ymin))
|
||||
factx+=zoom*2
|
||||
facty+=zoom*2
|
||||
dx=(opts[TX].get()-(xmax-xmin)*factx)/factx
|
||||
dy=(opts[TY].get()-(ymax-ymin)*factx)/factx
|
||||
graph[XMAX].set(rnd(xmax+dx/2,opts[RND].get()))
|
||||
graph[XMIN].set(rnd(xmin-dx/2,opts[RND].get()))
|
||||
graph[YMAX].set(rnd(ymax+dy/2,opts[RND].get()))
|
||||
graph[YMIN].set(rnd(ymin-dy/2,opts[RND].get()))
|
||||
if(zoom>0 and opts[ZOOM].get()):
|
||||
dx=(event.x-opts[TX].get()/2)/factx
|
||||
dy=(event.y-opts[TY].get()/2)/facty
|
||||
graph[XMAX].set(rnd(graph[XMAX]+dx,opts[RND].get()))
|
||||
graph[XMIN].set(rnd(graph[XMIN]+dx,opts[RND].get()))
|
||||
graph[YMAX].set(rnd(graph[YMAX]-dy,opts[RND].get()))
|
||||
graph[YMIN].set(rnd(graph[YMIN]-dy,opts[RND].get()))
|
||||
menu(2,True,True)
|
||||
|
||||
def azoom():
|
||||
global graph
|
||||
graph[XMAX].set(autozoom[XMAX]*1.1)
|
||||
graph[XMIN].set(autozoom[XMIN]*1.1)
|
||||
graph[YMAX].set(autozoom[YMAX]*1.1)
|
||||
graph[YMIN].set(autozoom[YMIN]*1.1)
|
||||
menu(2,True,True)
|
||||
|
||||
def badd():
|
||||
global scr
|
||||
#ajout d'une courbe vide avec le bouton "Nouvelle Courbe"
|
||||
newCurve(0,ntypes[PARAM],"","","",0,0,0.1,"black",1)
|
||||
if(len(curves)>1):
|
||||
scr+=1
|
||||
menu(1,True,False)
|
||||
|
||||
def ctype(*args):
|
||||
#TODO
|
||||
if(types[curves[scr][TYPE].get()]==POLAR and curves[scr][EQ].get()!=""):
|
||||
curves[scr][EQ].set(curves[scr][EQ].get().replace("y","t"))
|
||||
curves[scr][EQ].set(curves[scr][EQ].get().replace("x","t"))
|
||||
if(types[curves[scr][TYPE].get()]==XFY and curves[scr][EQ].get()!=""):
|
||||
curves[scr][EQ].set(curves[scr][EQ].get().replace("t","y"))
|
||||
curves[scr][EQ].set(curves[scr][EQ].get().replace("x","y"))
|
||||
if(types[curves[scr][TYPE].get()]==YFX and curves[scr][EQ].get()!=""):
|
||||
curves[scr][EQ].set(curves[scr][EQ].get().replace("t","x"))
|
||||
curves[scr][EQ].set(curves[scr][EQ].get().replace("y","x"))
|
||||
menu(1,False,False)
|
||||
|
||||
def move(n):
|
||||
global scr
|
||||
#Changement de courbe dans le menu
|
||||
if(n>0 and scr<len(curves)-1):
|
||||
scr+=1
|
||||
elif(n<0 and scr>0):
|
||||
scr-=1
|
||||
menu(1,False,False)
|
||||
|
||||
def orthx():
|
||||
global graph
|
||||
#Orthonormalisation de l'axe x en fonction de l'axe y
|
||||
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
|
||||
|
||||
if(xmax<xmin):
|
||||
i=xmin
|
||||
graph[XMIN].set(xmax)
|
||||
graph[YMAX].set(i)
|
||||
c=xmin+(abs(xmax-xmin))/2
|
||||
dx=(abs(ymax-ymin))*tx/ty
|
||||
graph[XMAX].set(c+dx/2)
|
||||
graph[XMIN].set(c-dx/2)
|
||||
menu(2,True,True)
|
||||
|
||||
def orthy():
|
||||
global graph
|
||||
#Idem en inversant
|
||||
tx,ty,xmax,xmin,ymax,ymin=opts[TX].get(),opts[TY].get(),eval(graph[XMAX].get()),eval(graph[XMIN].get()),eval(graph[YMAX].get()),eval(graph[YMIN].get())
|
||||
if(ymax<ymin):
|
||||
i=ymin
|
||||
graph[YMIN].set(ymax)
|
||||
graph[YMAX].set(i)
|
||||
c=ymin+(abs(ymax-ymin))/2
|
||||
dy=(abs(xmax-xmin))*ty/tx
|
||||
graph[YMAX].set(c+dy/2)
|
||||
graph[YMIN].set(c-dy/2)
|
||||
menu(2,True,True)
|
||||
|
||||
#fonctions utiles
|
||||
|
||||
def ft(text,t):
|
||||
#Transformation du texte de f(t) en vraie fonction
|
||||
return eval(text)
|
||||
|
||||
def rnd(n,p):
|
||||
#arrondi de n au p-ième chiffre
|
||||
return int(n*10**p+0.5)/(10**p)
|
||||
|
||||
def sgn(minv,maxv):
|
||||
#signe en fonction de l'inversion des axes
|
||||
if(maxv<minv):
|
||||
return -1
|
||||
return 1
|
||||
|
||||
#Démarrage du programme
|
||||
start()
|
||||
Reference in New Issue
Block a user