225 lines
5.7 KiB
Python
225 lines
5.7 KiB
Python
#!/usr/bin/env python
|
|
|
|
"""
|
|
TP n°2 MNI
|
|
20 janvier 2020
|
|
Franck Palacios
|
|
Dylan Voisin
|
|
"""
|
|
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
|
|
def norme(u):
|
|
return sum(i**2 for i in u) ** 0.5
|
|
|
|
def produit_scalaire(u, v):
|
|
return sum(i*j for i, j in zip(u, v))
|
|
|
|
def produit_vectoriel(u, v):
|
|
return [0, 0, u[0]*v[1] - v[0]*u[1]]
|
|
|
|
def cos_vect(u, v):
|
|
return produit_scalaire(u, v) / (norme(u) * norme(v))
|
|
|
|
def sin_vect(u, v):
|
|
return norme(produit_vectoriel(u, v)) / (norme(u) * norme(v))
|
|
|
|
def signe_angle(u, v):
|
|
"""renvoie le signe de l'angle orienté (u, v)"""
|
|
return -1 if u[0]*v[1] - v[0]*u[1] < 0 else 1
|
|
|
|
def points_vers_vecteur(p1, p2):
|
|
"""renvoie le vecteur formé par p1 et p2"""
|
|
return [p2[0] - p1[0], p2[1] - p1[1]]
|
|
|
|
def polygone_convexe(P):
|
|
"""Renvoie True si le polygone P est convexe, False sinon
|
|
le premier et le dernier sont différents !"""
|
|
signe = 0
|
|
for i in range(len(P)):
|
|
u = points_vers_vecteur(P[i], P[(i+1)%len(P)])
|
|
v = points_vers_vecteur(P[(i+1)%len(P)], P[(i+2)%len(P)])
|
|
if signe == 0:
|
|
signe = signe_angle(u, v)
|
|
if signe != signe_angle(u, v):
|
|
return False
|
|
return True
|
|
|
|
def affiche_polygone(P):
|
|
"""affiche un polygone P via pyplot et met en titre l'état de convexité"""
|
|
convexité = "convexe" if polygone_convexe(P) else "non convexe"
|
|
P = np.array(list(P) + [P[0]])
|
|
x = P[:,0]
|
|
y = P[:,1]
|
|
plt.title("Polygone " + convexité)
|
|
plt.plot(x, y)
|
|
plt.show()
|
|
|
|
def intersection_segments(pa, pb, pc, pd):
|
|
"""retourne vrai si AB et CD se croisent"""
|
|
# erreur car pas conservation sens vecteur
|
|
ab = points_vers_vecteur(pa, pb)
|
|
ac = points_vers_vecteur(pa, pc)
|
|
ad = points_vers_vecteur(pa, pd)
|
|
cd = points_vers_vecteur(pc, pd)
|
|
cb = points_vers_vecteur(pc, pb)
|
|
ca = points_vers_vecteur(pc, pa)
|
|
|
|
intersect = None
|
|
if signe_angle(ab, ac) == signe_angle(ab, ad):
|
|
intersect = False
|
|
else:
|
|
if signe_angle(cd, ca) == signe_angle(cd, cb):
|
|
# pas intersection
|
|
intersect = False
|
|
else:
|
|
intersect = True
|
|
return intersect
|
|
|
|
def affiche_segments(pa, pb, pc, pd):
|
|
"""affiche un segment avec pyplot et met en titre l'état de l'intersection"""
|
|
intersection = "se croisent" if intersection_segments(pa, pb, pc, pd) else "ne se croisent pas"
|
|
x_ab = [pa[0], pb[0]]
|
|
y_ab = [pa[1], pb[1]]
|
|
x_cd = [pc[0], pd[0]]
|
|
y_cd = [pc[1], pd[1]]
|
|
plt.title("Les segments " + intersection)
|
|
plt.plot(x_ab, y_ab)
|
|
plt.plot(x_cd, y_cd)
|
|
plt.show()
|
|
|
|
def sous_matrice(m, i, j=0):
|
|
"""renvoie la sous-matrice issue de m sans la ligne i et colonne j"""
|
|
sm = []
|
|
for k in range(len(m)):
|
|
if k != i:
|
|
sm.append([])
|
|
for l in range(len(m[i])):
|
|
if l != j:
|
|
sm[-1].append(m[k][l])
|
|
return sm
|
|
|
|
def det(m):
|
|
"""renvoie le déterminant de m"""
|
|
if len(m) == 1:
|
|
return m[0][0] # ici on a [[a]], a scalaire
|
|
if len(m) == 2:
|
|
return m[0][0] * m[1][1] - m[0][1] * m[1][0]
|
|
else:
|
|
signe = 0
|
|
det_ = 0
|
|
for i in range(len(m)):
|
|
det_ += (-1) ** signe * m[i][0] * det(sous_matrice(m, i))
|
|
signe ^= 1 # changement de signe
|
|
return det_
|
|
|
|
def inversion_matrice(m):
|
|
"""renvoie l'inverse de la matrice m"""
|
|
inv_m = [[0 for i in range(len(m))] for j in range(len(m))]
|
|
for i in range(len(m)):
|
|
for j in range(len(m[0])):
|
|
sm = sous_matrice(m, i, j)
|
|
d = det(sm)
|
|
inv_m[j][i] = (-1) ** ((i+j)%2) * d
|
|
return inv_m
|
|
|
|
def affiche_matrice(m):
|
|
"""affiche la matrice m de façon «jolie»"""
|
|
max_ = max(len(str(m[i][j])) for i in range(len(m)) for j in range(len(m)))
|
|
space = max_ + 2
|
|
for i in range(len(m)):
|
|
for j in range(len(m)):
|
|
if j != len(m) - 1:
|
|
print("{:{}}".format(m[i][j], space), end = '')
|
|
else:
|
|
print("{:{}}".format(m[i][j], space))
|
|
|
|
|
|
def main():
|
|
u = (2, 3)
|
|
v = (-2, 7)
|
|
print("u=", u)
|
|
print("v=", v)
|
|
print("produit scalaire:", produit_scalaire(u, v))
|
|
print("produit vectoriel:", produit_vectoriel(u, v))
|
|
print("cos²(u, v) + sin²(u, v)=", cos_vect(u, v)**2 + sin_vect(u, v)**2)
|
|
|
|
carré = (
|
|
(0, 0),
|
|
(1, 0),
|
|
(1, 1),
|
|
(0, 1)
|
|
)
|
|
affiche_polygone(carré)
|
|
|
|
non_convexe = (
|
|
(0, 0),
|
|
(0.5, 0.5),
|
|
(1, 0),
|
|
(1, 1),
|
|
(0, 1)
|
|
)
|
|
affiche_polygone(non_convexe)
|
|
|
|
a = (0, 2)
|
|
b = (3, 3)
|
|
c = (2, 2)
|
|
d = (4, 0)
|
|
affiche_segments(a, b, c, d)
|
|
affiche_segments(c, d, a, b)
|
|
|
|
a = (0, 0)
|
|
b = (1, 1)
|
|
c = (0, 1)
|
|
d = (1, 0)
|
|
affiche_segments(a, b, c, d)
|
|
|
|
m22 = (
|
|
(1, 2),
|
|
(3, 4)
|
|
)
|
|
m33 = (
|
|
(1, 2, 3),
|
|
(4, 5, 6),
|
|
(7, 8, 9)
|
|
)
|
|
print("m22:")
|
|
affiche_matrice(m22)
|
|
print("det(m22)=", det(m22))
|
|
print("m33:")
|
|
affiche_matrice(m33)
|
|
print("son déterminant:", det(m33))
|
|
print("mineur de m33 sans la ligne 1 et col 1:")
|
|
affiche_matrice(sous_matrice(m33, 1, 1))
|
|
print("son déterminant:", det(sous_matrice(m33, 1, 1)))
|
|
|
|
A = (
|
|
(5, 7),
|
|
(2, 3)
|
|
)
|
|
print("A:")
|
|
affiche_matrice(A)
|
|
print("A^{-1}:")
|
|
affiche_matrice(inversion_matrice(A))
|
|
|
|
M3 = (
|
|
(1, 2, 3),
|
|
(0, 1, 4),
|
|
(5, 6, 0)
|
|
)
|
|
# source M3: https://fr.wikihow.com/calculer-l%27inverse-d%27une-matrice-3x3
|
|
# M3⁻¹
|
|
# -24 18 5
|
|
# 20 -15 -4
|
|
# -5 4 1
|
|
print("M3:")
|
|
affiche_matrice(M3)
|
|
print("M3^{-1}")
|
|
affiche_matrice(inversion_matrice(M3))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|