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
|
||||
from time import sleep
|
||||
import argparse
|
||||
from math import * # pour utliser les fonctions mathématiques dans l'option -f
|
||||
|
||||
"""
|
||||
MNI TP3 - 27 janvier 2020
|
||||
@ -68,31 +69,85 @@ def diagonaliser_matrice22(m):
|
||||
u1 = np.array([u2[1], -u2[0]])
|
||||
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):
|
||||
"""renvoie les vecteurs u1 et u2 pour l'affichage ainsi que xmin, xmax, ymin, ymax"""
|
||||
bary = calc_barycentre(l_pts)
|
||||
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 = max(map(lambda x: np.linalg.norm(x-bary), l_pts))
|
||||
dist_x = max(l_pts[:,0]) - min(l_pts[:,0])
|
||||
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
|
||||
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
|
||||
u2 = u2 / np.linalg.norm(u2) * 1/2 * dist
|
||||
return u1, u2, x_range, y_range, dist
|
||||
u1, u2 = get_u1_u2_affichage(u1, u2, bary, dist_x, dist_y, pb, pg)
|
||||
# print(u1, u2)
|
||||
return u1, u2, x_range, y_range
|
||||
|
||||
|
||||
def visualiser_nuage(l_pts):
|
||||
bary = calc_barycentre(l_pts)
|
||||
u1, u2 = diagonaliser_matrice22(calc_matrice_corrélation(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
|
||||
u1, u2 = get_info_affichage(l_pts)[:2]
|
||||
ax = plt.axes()
|
||||
# plot du nuage
|
||||
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, *u2, 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, ec="orange", fc="white")
|
||||
# ax.set_aspect('equal')
|
||||
plt.show()
|
||||
|
||||
@ -103,10 +158,11 @@ def animation_nuage(l_pts, loops=10, time_sleep=2, delta_bruit=3):
|
||||
fig.canvas.draw()
|
||||
# nuage courant (pas de do while en Python)
|
||||
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])
|
||||
arr1 = ax.arrow(*bary, *u1, head_length=0.1*dist, head_width=0.1*dist, ec="black", fc="white")
|
||||
arr2 = ax.arrow(*bary, *u2, 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, ec="orange", fc="white")
|
||||
plt.title("itération 0")
|
||||
fig.canvas.flush_events()
|
||||
fig.canvas.draw()
|
||||
@ -119,15 +175,16 @@ def animation_nuage(l_pts, loops=10, time_sleep=2, delta_bruit=3):
|
||||
l_pts += ran
|
||||
# recalcul des données
|
||||
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_ylim(*y_range)
|
||||
# plot
|
||||
sc.set_offsets(l_pts) # repositionnement des points
|
||||
arr1.remove() # on enlève les vecteurs
|
||||
arr2.remove()
|
||||
arr1 = ax.arrow(*bary, *u1, head_length=0.1*dist, head_width=0.1*dist, ec="black", fc="white")
|
||||
arr2 = ax.arrow(*bary, *u2, 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, ec="orange", fc="white")
|
||||
fig.canvas.flush_events()
|
||||
fig.canvas.draw() # on redessine
|
||||
fig.canvas.flush_events()
|
||||
@ -141,17 +198,19 @@ def main(argv):
|
||||
gpi.add_argument("-i", "--input",
|
||||
help="input file for dots - if none, generate dots")
|
||||
gpi.add_argument("-f", "--function",
|
||||
help="function to use to generate dots, ex -f 3*x+4")
|
||||
parser.add_argument("-N", "--nb-dots", type=int, default=500,
|
||||
help="number of dots to generate (from 0 to NB_DOTS) from function")
|
||||
help="function to use to generate dots, ex -f \"3*x**2+cos(x)\"")
|
||||
parser.add_argument("-m", "--max-dot-xval", type=float, default=10,
|
||||
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",
|
||||
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")
|
||||
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,
|
||||
help="amount of time between each loop")
|
||||
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:
|
||||
parser.print_usage()
|
||||
sys.exit(0)
|
||||
@ -164,10 +223,13 @@ def main(argv):
|
||||
l_pts = acquérir_depuis_fichier(args.input)
|
||||
else:
|
||||
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
|
||||
delta_bruit = 0 # bruit généré, 0 si on en veut aucun
|
||||
for i in range(n):
|
||||
if args.generate_with_noise:
|
||||
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
|
||||
l_pts.append([i, y])
|
||||
l_pts = np.array(l_pts)
|
||||
|
Reference in New Issue
Block a user