bon, le code est 'bon', j'ai plus qu'à l'épurer et à mettre un peu d'aide au début, là les flèches ne dépasseront jamais un certain seuil, d'ailleurs c'est plus des flèches
This commit is contained in:
parent
7c3a300947
commit
2e3a2f89ad
108
3/TP3_voisin.py
108
3/TP3_voisin.py
@ -5,6 +5,7 @@ from random import random, choice
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import argparse
|
import argparse
|
||||||
|
from math import * # pour utliser les fonctions mathématiques dans l'option -f
|
||||||
|
|
||||||
"""
|
"""
|
||||||
MNI TP3 - 27 janvier 2020
|
MNI TP3 - 27 janvier 2020
|
||||||
@ -68,31 +69,85 @@ def diagonaliser_matrice22(m):
|
|||||||
u1 = np.array([u2[1], -u2[0]])
|
u1 = np.array([u2[1], -u2[0]])
|
||||||
return u1, u2, lambda1, lambda2
|
return u1, u2, lambda1, lambda2
|
||||||
|
|
||||||
|
def get_u1_u2_affichage(u1, u2, bary, dist_x, dist_y, pb, pg):
|
||||||
|
"""renvoie u1 et u2 prêt pour l'affichage en fonction du barycentre,
|
||||||
|
de la distance x et y sur l'ensemble des points, le point le plus bas et
|
||||||
|
le point le plus à gauche"""
|
||||||
|
if np.linalg.norm(u1) == np.linalg.norm(u2) == 0:
|
||||||
|
# un seul point
|
||||||
|
u1 = np.array([1, 0]) / 500
|
||||||
|
u2 = np.array([0, 1]) / 500
|
||||||
|
return u1, u2
|
||||||
|
bary = np.array((bary[0] - pg[0], bary[1] - pb[1]))
|
||||||
|
if u1[0] != 0 and u1[1] != 0:
|
||||||
|
if u1[0] > 0: # vers la droite
|
||||||
|
t1x = (dist_x - bary[0]) / u1[0]
|
||||||
|
else:
|
||||||
|
t1x = -bary[0] / u1[0]
|
||||||
|
if u1[1] > 0: # vers le haut
|
||||||
|
t1y = (dist_y - bary[1]) / u1[1]
|
||||||
|
else:
|
||||||
|
t1y = -bary[1] / u1[1]
|
||||||
|
t1 = min(t1x, t1y)
|
||||||
|
elif u1[0] != 0:
|
||||||
|
if u1[0] > 0: # vers la droite
|
||||||
|
t1 = (dist_x - bary[0]) / u1[0]
|
||||||
|
else:
|
||||||
|
t1 = -bary[0] / u1[0]
|
||||||
|
else:
|
||||||
|
if u1[1] > 0: # vers le haut
|
||||||
|
t1 = (dist_y - bary[1]) / u1[1]
|
||||||
|
else:
|
||||||
|
t1 = -bary[1] / u1[1]
|
||||||
|
if u2[0] != 0 and u2[1] != 0:
|
||||||
|
if u2[0] > 0: # vers la droite
|
||||||
|
t2x = (dist_x - bary[0]) / u2[0]
|
||||||
|
else:
|
||||||
|
t2x = -bary[0] / u2[0]
|
||||||
|
if u2[1] > 0: # vers le haut
|
||||||
|
t2y = (dist_y - bary[1]) / u2[1]
|
||||||
|
else:
|
||||||
|
t2y = -bary[1] / u2[1]
|
||||||
|
t2 = min(t2x, t2y)
|
||||||
|
elif u2[0] != 0:
|
||||||
|
if u2[0] > 0: # vers la droite
|
||||||
|
t2 = (dist_x - bary[0]) / u2[0]
|
||||||
|
else:
|
||||||
|
t2 = -bary[0] / u2[0]
|
||||||
|
else:
|
||||||
|
if u2[1] > 0: # vers le haut
|
||||||
|
t2 = (dist_y - bary[1]) / u2[1]
|
||||||
|
else:
|
||||||
|
t2 = -bary[1] / u2[1]
|
||||||
|
u1 = u1 * t1 * 2/3
|
||||||
|
u2 = u2 * t2 * 1/3
|
||||||
|
return u1, u2
|
||||||
|
|
||||||
def get_info_affichage(l_pts):
|
def get_info_affichage(l_pts):
|
||||||
"""renvoie les vecteurs u1 et u2 pour l'affichage ainsi que xmin, xmax, ymin, ymax"""
|
"""renvoie les vecteurs u1 et u2 pour l'affichage ainsi que xmin, xmax, ymin, ymax"""
|
||||||
bary = calc_barycentre(l_pts)
|
bary = calc_barycentre(l_pts)
|
||||||
u1, u2 = diagonaliser_matrice22(calc_matrice_corrélation(l_pts))[:2]
|
u1, u2 = diagonaliser_matrice22(calc_matrice_corrélation(l_pts))[:2]
|
||||||
|
pb = min(l_pts, key = lambda x: x[1])
|
||||||
|
pg = min(l_pts, key = lambda x: x[0])
|
||||||
dist = min(max(l_pts[:,0]) - bary[0], max(l_pts[:,1]) - bary[1])
|
dist = min(max(l_pts[:,0]) - bary[0], max(l_pts[:,1]) - bary[1])
|
||||||
|
# dist = max(map(lambda x: np.linalg.norm(x-bary), l_pts))
|
||||||
dist_x = max(l_pts[:,0]) - min(l_pts[:,0])
|
dist_x = max(l_pts[:,0]) - min(l_pts[:,0])
|
||||||
dist_y = max(l_pts[:,1]) - min(l_pts[:,1])
|
dist_y = max(l_pts[:,1]) - min(l_pts[:,1])
|
||||||
x_range = min(l_pts[:,0]) - 0.1 * dist_x, max(l_pts[:,0]) + 0.1 * dist_x
|
x_range = min(l_pts[:,0]) - 0.1 * dist_x, max(l_pts[:,0]) + 0.1 * dist_x
|
||||||
y_range = min(l_pts[:,1]) - 0.1 * dist_y, max(l_pts[:,1]) + 0.1 * dist_y
|
y_range = min(l_pts[:,1]) - 0.1 * dist_y, max(l_pts[:,1]) + 0.1 * dist_y
|
||||||
u1 = u1 / np.linalg.norm(u1) * dist
|
u1, u2 = get_u1_u2_affichage(u1, u2, bary, dist_x, dist_y, pb, pg)
|
||||||
u2 = u2 / np.linalg.norm(u2) * 1/2 * dist
|
# print(u1, u2)
|
||||||
return u1, u2, x_range, y_range, dist
|
return u1, u2, x_range, y_range
|
||||||
|
|
||||||
|
|
||||||
def visualiser_nuage(l_pts):
|
def visualiser_nuage(l_pts):
|
||||||
bary = calc_barycentre(l_pts)
|
bary = calc_barycentre(l_pts)
|
||||||
u1, u2 = diagonaliser_matrice22(calc_matrice_corrélation(l_pts))[:2]
|
u1, u2 = get_info_affichage(l_pts)[:2]
|
||||||
dist = min(max(l_pts[:,0]) - bary[0], max(l_pts[:,1]) - bary[1])
|
|
||||||
u1 = u1 / np.linalg.norm(u1) * dist
|
|
||||||
u2 = u2 / np.linalg.norm(u2) * 1/2 * dist
|
|
||||||
ax = plt.axes()
|
ax = plt.axes()
|
||||||
# plot du nuage
|
# plot du nuage
|
||||||
plt.scatter(l_pts[:,0], l_pts[:,1])
|
plt.scatter(l_pts[:,0], l_pts[:,1])
|
||||||
ax.arrow(*bary, *u1, head_length=0.1*dist, head_width=0.1*dist, ec="black", fc="white")
|
ax.arrow(*bary, *u1, ec="red", fc="white")
|
||||||
ax.arrow(*bary, *u2, head_length=0.1*dist, head_width=0.1*dist, ec="black", fc="white")
|
ax.arrow(*bary, *u2, ec="orange", fc="white")
|
||||||
# ax.set_aspect('equal')
|
# ax.set_aspect('equal')
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
@ -103,10 +158,11 @@ def animation_nuage(l_pts, loops=10, time_sleep=2, delta_bruit=3):
|
|||||||
fig.canvas.draw()
|
fig.canvas.draw()
|
||||||
# nuage courant (pas de do while en Python)
|
# nuage courant (pas de do while en Python)
|
||||||
bary = calc_barycentre(l_pts)
|
bary = calc_barycentre(l_pts)
|
||||||
u1, u2, x_range, y_range, dist = get_info_affichage(l_pts)
|
u1, u2 = get_info_affichage(l_pts)[:2]
|
||||||
|
u1l = np.linalg.norm(u1)
|
||||||
sc = ax.scatter(l_pts[:,0], l_pts[:,1])
|
sc = ax.scatter(l_pts[:,0], l_pts[:,1])
|
||||||
arr1 = ax.arrow(*bary, *u1, head_length=0.1*dist, head_width=0.1*dist, ec="black", fc="white")
|
arr1 = ax.arrow(*bary, *u1, ec="red", fc="white")
|
||||||
arr2 = ax.arrow(*bary, *u2, head_length=0.1*dist, head_width=0.1*dist, ec="black", fc="white")
|
arr2 = ax.arrow(*bary, *u2, ec="orange", fc="white")
|
||||||
plt.title("itération 0")
|
plt.title("itération 0")
|
||||||
fig.canvas.flush_events()
|
fig.canvas.flush_events()
|
||||||
fig.canvas.draw()
|
fig.canvas.draw()
|
||||||
@ -119,15 +175,16 @@ def animation_nuage(l_pts, loops=10, time_sleep=2, delta_bruit=3):
|
|||||||
l_pts += ran
|
l_pts += ran
|
||||||
# recalcul des données
|
# recalcul des données
|
||||||
bary = calc_barycentre(l_pts)
|
bary = calc_barycentre(l_pts)
|
||||||
u1, u2, x_range, y_range, dist = get_info_affichage(l_pts)
|
u1, u2, x_range, y_range = get_info_affichage(l_pts)
|
||||||
|
u1l = np.linalg.norm(u1)
|
||||||
ax.set_xlim(*x_range)
|
ax.set_xlim(*x_range)
|
||||||
ax.set_ylim(*y_range)
|
ax.set_ylim(*y_range)
|
||||||
# plot
|
# plot
|
||||||
sc.set_offsets(l_pts) # repositionnement des points
|
sc.set_offsets(l_pts) # repositionnement des points
|
||||||
arr1.remove() # on enlève les vecteurs
|
arr1.remove() # on enlève les vecteurs
|
||||||
arr2.remove()
|
arr2.remove()
|
||||||
arr1 = ax.arrow(*bary, *u1, head_length=0.1*dist, head_width=0.1*dist, ec="black", fc="white")
|
arr1 = ax.arrow(*bary, *u1, ec="red", fc="white")
|
||||||
arr2 = ax.arrow(*bary, *u2, head_length=0.1*dist, head_width=0.1*dist, ec="black", fc="white")
|
arr2 = ax.arrow(*bary, *u2, ec="orange", fc="white")
|
||||||
fig.canvas.flush_events()
|
fig.canvas.flush_events()
|
||||||
fig.canvas.draw() # on redessine
|
fig.canvas.draw() # on redessine
|
||||||
fig.canvas.flush_events()
|
fig.canvas.flush_events()
|
||||||
@ -141,17 +198,19 @@ def main(argv):
|
|||||||
gpi.add_argument("-i", "--input",
|
gpi.add_argument("-i", "--input",
|
||||||
help="input file for dots - if none, generate dots")
|
help="input file for dots - if none, generate dots")
|
||||||
gpi.add_argument("-f", "--function",
|
gpi.add_argument("-f", "--function",
|
||||||
help="function to use to generate dots, ex -f 3*x+4")
|
help="function to use to generate dots, ex -f \"3*x**2+cos(x)\"")
|
||||||
parser.add_argument("-N", "--nb-dots", type=int, default=500,
|
parser.add_argument("-m", "--max-dot-xval", type=float, default=10,
|
||||||
help="number of dots to generate (from 0 to NB_DOTS) from function")
|
help="x range of generated dots (from 0 to MAX_DOT_VAL, step=0.1) from function")
|
||||||
gps.add_argument("-s", "--show", action="store_true",
|
gps.add_argument("-s", "--show", action="store_true",
|
||||||
help="show cloud of dots with u1 and u2")
|
help="show cloud of dots with u1 and u2")
|
||||||
gps.add_argument("-l", "--loop", type=int, default=10,
|
gps.add_argument("-l", "--loop", type=int,
|
||||||
help="number of loop to show/perform on randomized dots from originals ones")
|
help="number of loop to show/perform on randomized dots from originals ones")
|
||||||
|
parser.add_argument("-g", "--generate-with-noise", action="store_true",
|
||||||
|
help="apply noise on dots generation")
|
||||||
parser.add_argument("-d", "--delay", type=float, default=2,
|
parser.add_argument("-d", "--delay", type=float, default=2,
|
||||||
help="amount of time between each loop")
|
help="amount of time between each loop")
|
||||||
parser.add_argument("-n", "--noise", type = float, default=10,
|
parser.add_argument("-n", "--noise", type = float, default=10,
|
||||||
help="maximum value of the noise applied between each step")
|
help="maximum value of the noise applied between each step and on generation if option -g and -f called")
|
||||||
if not argv:
|
if not argv:
|
||||||
parser.print_usage()
|
parser.print_usage()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@ -164,10 +223,13 @@ def main(argv):
|
|||||||
l_pts = acquérir_depuis_fichier(args.input)
|
l_pts = acquérir_depuis_fichier(args.input)
|
||||||
else:
|
else:
|
||||||
l_pts = []
|
l_pts = []
|
||||||
n = args.nb_dots # nombre de points
|
n = args.max_dot_xval
|
||||||
f = lambda x: eval(args.function) # fonction génératrice de la ditribution
|
f = lambda x: eval(args.function) # fonction génératrice de la ditribution
|
||||||
delta_bruit = 0 # bruit généré, 0 si on en veut aucun
|
if args.generate_with_noise:
|
||||||
for i in range(n):
|
delta_bruit = args.noise # bruit généré, 0 si on en veut aucun
|
||||||
|
else:
|
||||||
|
delta_bruit = 0
|
||||||
|
for i in np.arange(0, n, 0.1):
|
||||||
y = f(i) + choice((-1, 1)) * random() * delta_bruit/2
|
y = f(i) + choice((-1, 1)) * random() * delta_bruit/2
|
||||||
l_pts.append([i, y])
|
l_pts.append([i, y])
|
||||||
l_pts = np.array(l_pts)
|
l_pts = np.array(l_pts)
|
||||||
|
Reference in New Issue
Block a user