From 2e3a2f89adaf3cff591fc6452c3bf2ac95c54ce4 Mon Sep 17 00:00:00 2001 From: DylanVsn <43576618+DylanVsn@users.noreply.github.com> Date: Wed, 29 Jan 2020 22:55:11 +0100 Subject: [PATCH] =?UTF-8?q?bon,=20le=20code=20est=20'bon',=20j'ai=20plus?= =?UTF-8?q?=20qu'=C3=A0=20l'=C3=A9purer=20et=20=C3=A0=20mettre=20un=20peu?= =?UTF-8?q?=20d'aide=20au=20d=C3=A9but,=20l=C3=A0=20les=20fl=C3=A8ches=20n?= =?UTF-8?q?e=20d=C3=A9passeront=20jamais=20un=20certain=20seuil,=20d'aille?= =?UTF-8?q?urs=20c'est=20plus=20des=20fl=C3=A8ches?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3/TP3_voisin.py | 108 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/3/TP3_voisin.py b/3/TP3_voisin.py index 1c586aa..7f3b58b 100755 --- a/3/TP3_voisin.py +++ b/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)