Prérequis Python et Algèbre Linéaire pour la 3D
Commencez par le test
20 questions, 10 minutes, votre niveau tout de suite
Dix questions de Python, dix d'algèbre linéaire. À la fin, chaque réponse fausse vous renvoie à la section qui l'explique : vous ne révisez que ce qui vous manque. Le repère de confort est de 16/20 : le test est informatif, il ne conditionne pas l'inscription.
1. Installer Python : votre laboratoire de travail
La première étape est de disposer d'un environnement Python propre et reproductible. Miniconda est la référence pour la data science et le calcul scientifique, car il gère nativement les dépendances compilées (C++, CUDA, Fortran).
# 1. Télécharger Miniconda (Linux/macOS/Windows)
# https://docs.conda.io/en/latest/miniconda.html
# 2. Créer un environnement dédié
conda create -n prereq-3d python=3.12 -y
conda activate prereq-3d
# 3. Installer les bibliothèques essentielles
pip install numpy matplotlib
Miniconda (léger, ~80 Mo) à Anaconda (lourd, ~4 Go). Vous installerez uniquement les paquets dont vous avez besoin, ce qui réduit les conflits de dépendances.
Vérifiez que tout fonctionne en lançant python --version dans votre terminal. Vous devez obtenir Python 3.12.x. Passons maintenant aux briques fondamentales du langage.
2. Les fondamentaux Python en 30 minutes
Inutile de lire un livre de 500 pages. Pour la 3D, vous avez besoin de maîtriser un sous-ensemble précis du langage. Voici l'essentiel, condensé.
2.1 Variables et types
Python est un langage à typage dynamique. Les types fondamentaux pour la 3D sont int, float, str, bool et list.
# Variables numériques (coordonnées d'un point 3D)
x = 1.5
y = -3.2
z = 0.8
# Chaîne de caractères
label = "bâtiment"
# Booléen
est_classifie = True
# Vérifier le type
print(type(x)) # <class 'float'>
print(type(label)) # <class 'str'>
2.2 Listes et dictionnaires
Les listes stockent des séquences ordonnées. Les dictionnaires associent des clés à des valeurs. En 3D, une liste de coordonnées et un dictionnaire de métadonnées sont omniprésents.
# Liste : un point 3D
point = [1.5, -3.2, 0.8]
print(point[0]) # 1.5 (indexation commence à 0)
# Liste de points (nuage simplifié)
nuage = [
[1.5, -3.2, 0.8],
[2.1, 0.4, 1.2],
[-0.3, 1.7, 0.1],
]
# Dictionnaire : métadonnées d'un scan
scan_info = {
"source": "LiDAR Terrestre",
"nb_points": 5_000_000,
"format": "LAZ",
"crs": "EPSG:2154",
}
print(scan_info["nb_points"]) # 5000000
2.3 Boucles et conditions
Les boucles for parcourent des séquences. Les conditions if/elif/else contrôlent le flux. En 3D, on itère souvent sur des points pour les filtrer ou les transformer.
# Filtrer les points au-dessus de z = 0.5
points_hauts = []
for point in nuage:
if point[2] > 0.5:
points_hauts.append(point)
print(f"Points au-dessus de 0.5m : {len(points_hauts)}")
# Compréhension de liste (syntaxe compacte)
points_hauts = [p for p in nuage if p[2] > 0.5]
# La même syntaxe calcule une liste à partir d'une autre
carres = [x**2 for x in range(4)]
print(carres) # [0, 1, 4, 9]
# Boucle avec index (enumerate)
for i, p in enumerate(nuage):
print(f"Point {i} : x={p[0]}, y={p[1]}, z={p[2]}")
2.4 Fonctions
Les fonctions encapsulent une logique réutilisable. Dans un pipeline 3D, chaque étape de traitement est typiquement une fonction.
def distance_3d(p1, p2):
"""Calcule la distance euclidienne entre deux points 3D."""
dx = p1[0] - p2[0]
dy = p1[1] - p2[1]
dz = p1[2] - p2[2]
return (dx**2 + dy**2 + dz**2) ** 0.5
a = [0, 0, 0]
b = [1, 1, 1]
print(f"Distance : {distance_3d(a, b):.4f} m")
# Distance : 1.7321 m
3. NumPy : le moteur du calcul vectoriel
NumPy est la bibliothèque fondamentale pour le calcul numérique en Python. En 3D, vous manipulez des millions de points : les boucles Python sont trop lentes. NumPy exécute chaque opération en C compilé, sur tout le tableau d'un coup : c'est ce qui rend possible le traitement de millions de points.
3.1 Créer et manipuler des tableaux
import numpy as np
# Créer un array à partir d'une liste
point = np.array([1.5, -3.2, 0.8])
print(point.shape) # (3,) : vecteur 3D
# Nuage de 5 points (matrice 5x3)
nuage = np.array([
[1.5, -3.2, 0.8],
[2.1, 0.4, 1.2],
[-0.3, 1.7, 0.1],
[0.0, 0.0, 0.0],
[3.4, -1.1, 2.5],
])
print(nuage.shape) # (5, 3) : 5 points, 3 dimensions
# Accéder à toutes les coordonnées Z
z_coords = nuage[:, 2]
print(z_coords) # [0.8, 1.2, 0.1, 0.0, 2.5]
3.2 Opérations vectorisées et broadcasting
Le broadcasting est la capacité de NumPy à appliquer une opération entre des arrays de formes différentes. C'est ce qui rend le calcul 3D possible sans boucles.
# Translation : déplacer tout le nuage de (+10, +20, +5)
translation = np.array([10, 20, 5])
nuage_deplace = nuage + translation # Broadcasting automatique !
# Centrer le nuage sur son barycentre
centroid = np.mean(nuage, axis=0)
nuage_centre = nuage - centroid
# Calculer la distance de chaque point à l'origine
distances = np.linalg.norm(nuage, axis=1)
print(distances) # [3.62, 2.45, 1.73, 0.00, 4.36]
# Filtrage vectorisé : points à moins de 3m de l'origine
masque = distances < 3.0
points_proches = nuage[masque]
print(f"Points proches : {len(points_proches)}")
for sur un array NumPy, il y a probablement une opération vectorisée plus rapide. La règle d'or : pas de boucle Python sur des données 3D.
4. Lire et écrire des fichiers
En 3D, les données transitent souvent sous forme de fichiers texte (CSV, TXT) ou structurés (JSON). Savoir les lire et les écrire est un prérequis non négociable.
import numpy as np
import json
# ---- CSV : écrire puis relire un nuage de points ----
nuage = np.array([[ 1.5, -3.2, 0.8],
[ 2.1, 0.4, 1.2],
[-0.3, 1.7, 0.1]])
np.savetxt("points.csv", nuage, delimiter=",", header="x,y,z", comments="")
nuage_lu = np.loadtxt("points.csv", delimiter=",", skiprows=1)
print(f"Chargé {nuage_lu.shape[0]} points") # Chargé 3 points
# Sauvegarder les seuls points au-dessus de 0,5 m
np.savetxt("points_filtres.csv", nuage_lu[nuage_lu[:, 2] > 0.5],
delimiter=",", header="x,y,z", comments="")
# ---- JSON : métadonnées de projet ----
config = {"crs": "EPSG:2154", "nb_points": len(nuage_lu), "bbox": [0, 0, 100, 100]}
with open("projet.json", "w") as f:
json.dump(config, f, indent=2)
with open("projet.json") as f:
print(json.load(f)["crs"]) # EPSG:2154
5. Visualiser avec Matplotlib
Matplotlib permet de créer des graphiques 2D et 3D. Indispensable pour vérifier visuellement vos données avant de les injecter dans un pipeline de traitement.
import matplotlib.pyplot as plt
import numpy as np
# Générer un nuage de points aléatoire
np.random.seed(42)
nuage = np.random.randn(200, 3)
# Visualisation 3D
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(nuage[:, 0], nuage[:, 1], nuage[:, 2],
c=nuage[:, 2], cmap='viridis', s=5)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Nuage de Points 3D')
plt.show()
6. Exercice : charger et afficher des coordonnées 3D
Mettez en pratique tout ce que vous venez d'apprendre. L'objectif : créer un fichier CSV de coordonnées, le charger avec NumPy, calculer des statistiques, et afficher le résultat en 3D.
import numpy as np
import matplotlib.pyplot as plt
# 1. Créer un fichier CSV de test
np.random.seed(0)
points = np.random.uniform(-10, 10, size=(500, 3))
np.savetxt("nuage_test.csv", points, delimiter=",",
header="x,y,z", comments="")
# 2. Charger le fichier
data = np.loadtxt("nuage_test.csv", delimiter=",", skiprows=1)
print(f"Nombre de points : {data.shape[0]}")
# 3. Statistiques
print(f"Barycentre : {np.mean(data, axis=0)}")
print(f"Étendue Z : {data[:, 2].min():.2f} à {data[:, 2].max():.2f}")
# 4. Filtrer : garder seulement les points avec z > 0
data_filtre = data[data[:, 2] > 0]
print(f"Points avec z > 0 : {len(data_filtre)}")
# 5. Visualiser
fig = plt.figure(figsize=(12, 5))
ax1 = fig.add_subplot(121, projection='3d')
ax1.scatter(data[:, 0], data[:, 1], data[:, 2],
c=data[:, 2], cmap='coolwarm', s=2)
ax1.set_title('Nuage complet')
ax2 = fig.add_subplot(122, projection='3d')
ax2.scatter(data_filtre[:, 0], data_filtre[:, 1], data_filtre[:, 2],
c=data_filtre[:, 2], cmap='coolwarm', s=2)
ax2.set_title('Filtré (z > 0)')
plt.tight_layout()
plt.show()
7. Vecteurs 2D et 3D : la brique élémentaire
Un vecteur est une quantité qui a une direction et une magnitude. En 3D, un vecteur est un triplet (x, y, z). Les opérations sur les vecteurs sont le fondement de toute géométrie computationnelle.
import numpy as np
# Définir deux vecteurs 3D
u = np.array([3, 1, 4])
v = np.array([1, 5, -2])
# Addition et soustraction
somme = u + v # [4, 6, 2]
diff = u - v # [2, -4, 6]
# Multiplication par un scalaire
double_u = 2 * u # [6, 2, 8]
# Norme (longueur) du vecteur
norme_u = np.linalg.norm(u)
print(f"||u|| = {norme_u:.4f}") # 5.0990
# Vecteur unitaire (normalisation)
u_hat = u / norme_u
print(f"Direction de u : {u_hat}")
print(f"Vérification : ||u_hat|| = {np.linalg.norm(u_hat):.1f}") # 1.0
| Opération | Notation | NumPy | Résultat |
|---|---|---|---|
| Addition | u + v | u + v |
Vecteur |
| Soustraction | u - v | u - v |
Vecteur |
| Scalaire | k * u | k * u |
Vecteur |
| Norme | ||u|| | np.linalg.norm(u) |
Scalaire |
8. Produit scalaire
Le produit scalaire de deux vecteurs donne un nombre (scalaire). Il mesure à quel point deux vecteurs pointent dans la même direction. Son application 3D principale : calculer l'angle entre deux vecteurs.
import numpy as np
u = np.array([1, 0, 0]) # Axe X
v = np.array([0, 1, 0]) # Axe Y
w = np.array([1, 1, 0]) # Diagonale XY
# Produit scalaire
print(np.dot(u, v)) # 0 : vecteurs perpendiculaires !
print(np.dot(u, w)) # 1
# Angle entre u et w
cos_angle = np.dot(u, w) / (np.linalg.norm(u) * np.linalg.norm(w))
angle_rad = np.arccos(cos_angle)
angle_deg = np.degrees(angle_rad)
print(f"Angle entre u et w : {angle_deg:.1f}°") # 45.0°
9. Produit vectoriel et normale à un plan
Le produit vectoriel de deux vecteurs donne un troisième vecteur perpendiculaire aux deux premiers. C'est l'outil fondamental pour calculer la normale d'une surface en 3D.
import numpy as np
# Trois points définissent un plan
A = np.array([0, 0, 0])
B = np.array([1, 0, 0])
C = np.array([0, 1, 0])
# Deux vecteurs dans le plan
AB = B - A # [1, 0, 0]
AC = C - A # [0, 1, 0]
# Normale au plan = produit vectoriel
normale = np.cross(AB, AC)
print(f"Normale : {normale}") # [0, 0, 1] : pointe vers le haut
# Normaliser pour obtenir un vecteur unitaire
normale_unit = normale / np.linalg.norm(normale)
print(f"Normale unitaire : {normale_unit}")
# Aire du triangle ABC
aire = 0.5 * np.linalg.norm(normale)
print(f"Aire du triangle : {aire} m²") # 0.5 m²
u x v = -(v x u). Cela détermine le sens de la normale (vers le haut ou vers le bas).
10. Matrices : multiplication, transposée et inverse
Les matrices sont des tableaux 2D de nombres. En 3D, elles servent à représenter des transformations géométriques (rotation, mise à l'échelle) et à résoudre des systèmes d'équations.
import numpy as np
# Créer une matrice 3x3
M = np.array([
[2, 0, 0],
[0, 3, 0],
[0, 0, 1],
])
# Multiplication matrice x vecteur
v = np.array([1, 1, 1])
resultat = M @ v # Opérateur @ = multiplication matricielle
print(resultat) # [2, 3, 1] : mise à l'échelle !
# Transposée
print(M.T)
# Inverse (si elle existe)
M_inv = np.linalg.inv(M)
print(M_inv @ M) # Matrice identité (aux erreurs flottantes près)
# Déterminant
det = np.linalg.det(M)
print(f"Déterminant : {det}") # 6.0
| Opération | NumPy | Signification Géométrique |
|---|---|---|
| Multiplication | A @ B |
Composition de transformations |
| Transposée | A.T |
Miroir par rapport à la diagonale |
| Inverse | np.linalg.inv(A) |
Transformation inverse (annuler) |
| Déterminant | np.linalg.det(A) |
Facteur de changement de volume |
11. Transformations 3D : rotation, translation, échelle
Toute manipulation géométrique en 3D se ramène à une combinaison de trois opérations fondamentales. Comprendre comment les appliquer avec des matrices est essentiel pour travailler avec des nuages de points.
11.1 Matrice de rotation
Une rotation autour de l'axe Z d'un angle theta s'exprime par une matrice 3x3. Les rotations autour de X et Y suivent le même principe.
import numpy as np
def rotation_z(theta_deg):
"""Matrice de rotation autour de l'axe Z."""
theta = np.radians(theta_deg)
c, s = np.cos(theta), np.sin(theta)
return np.array([
[ c, -s, 0],
[ s, c, 0],
[ 0, 0, 1],
])
def rotation_x(theta_deg):
"""Matrice de rotation autour de l'axe X."""
theta = np.radians(theta_deg)
c, s = np.cos(theta), np.sin(theta)
return np.array([
[1, 0, 0],
[0, c, -s],
[0, s, c],
])
def rotation_y(theta_deg):
"""Matrice de rotation autour de l'axe Y."""
theta = np.radians(theta_deg)
c, s = np.cos(theta), np.sin(theta)
return np.array([
[ c, 0, s],
[ 0, 1, 0],
[-s, 0, c],
])
# Rotation de 45° autour de Z
R = rotation_z(45)
point = np.array([1, 0, 0])
point_tourne = R @ point
print(f"Avant : {point}")
print(f"Après : {point_tourne}") # [0.707, 0.707, 0]
11.2 Translation et changement d'échelle
# Translation : simple addition vectorielle
nuage = np.random.randn(100, 3)
translation = np.array([10, 20, 5])
nuage_deplace = nuage + translation
# Changement d'échelle : multiplication par une matrice diagonale
S = np.diag([2.0, 2.0, 0.5]) # Double en X/Y, moitié en Z
nuage_scale = (S @ nuage.T).T
# Combinaison : d'abord rotation, puis translation
R = rotation_z(30)
nuage_transforme = (R @ nuage.T).T + translation
12. Systèmes de coordonnées et projections
En géospatial, les données proviennent de capteurs utilisant différents systèmes de coordonnées. Il est crucial de savoir passer d'un repère à un autre.
| Système | Type | Usage Typique | Unité |
|---|---|---|---|
| WGS84 (EPSG:4326) | Géographique | GPS, données mondiales | Degrés |
| Lambert 93 (EPSG:2154) | Projeté | France métropolitaine | Mètres |
| UTM | Projeté | Universel par zones | Mètres |
| Local / Scanner | Cartésien | LiDAR terrestre, BIM | Mètres |
Le passage d'un repère local à un repère géoréférencé se fait par une transformation rigide (rotation + translation), souvent via une matrice 4x4 obtenue par recalage de cibles connues.
import numpy as np
# Projection orthogonale d'un vecteur u sur un vecteur v
def projection(u, v):
"""Projette u sur v."""
return (np.dot(u, v) / np.dot(v, v)) * v
u = np.array([3, 4, 0])
v = np.array([1, 0, 0]) # Axe X
proj = projection(u, v)
print(f"Projection de u sur X : {proj}") # [3, 0, 0]
# Composante perpendiculaire
perp = u - proj
print(f"Composante perpendiculaire : {perp}") # [0, 4, 0]
13. Exercice : faire tourner un nuage de points
Exercice de synthèse : générez un nuage de points en forme de "L", appliquez une rotation de 90 degrés autour de l'axe Z, puis visualisez le résultat avant/après.
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1) # même tirage pour tout le monde
# 1. Créer un nuage en forme de L
branche_h = np.random.uniform([0, 0, 0], [5, 1, 1], size=(200, 3))
branche_v = np.random.uniform([0, 0, 0], [1, 4, 1], size=(200, 3))
nuage = np.vstack([branche_h, branche_v])
# 2. Matrice de rotation (90° autour de Z)
theta = np.radians(90)
R = np.array([
[np.cos(theta), -np.sin(theta), 0],
[np.sin(theta), np.cos(theta), 0],
[0, 0, 1],
])
# 3. Appliquer la rotation à chaque point
# nuage.T = (3, 400), R @ nuage.T = (3, 400), .T = (400, 3)
nuage_tourne = (R @ nuage.T).T
# 4. Visualiser avant / après, vus de dessus et à la même échelle :
# une rotation autour de Z se lit alors directement dans le plan XY
fig = plt.figure(figsize=(12, 6))
for i, (pts, couleur, titre) in enumerate([(nuage, '#8b5cf6', 'Original'),
(nuage_tourne, '#d946ef', 'Après rotation 90° (Z)')]):
ax = fig.add_subplot(1, 2, i + 1, projection='3d')
ax.scatter(pts[:, 0], pts[:, 1], pts[:, 2], c=couleur, s=3)
ax.set_xlim(-5, 5); ax.set_ylim(-5, 5); ax.set_zlim(0, 1)
ax.view_init(elev=90, azim=-90)
ax.set_zticks([]) # vu de dessus, l'axe Z n'apporte rien
ax.set_title(titre)
ax.set_xlabel('X'); ax.set_ylabel('Y')
plt.tight_layout()
plt.show()
# Vérification : le barycentre a-t-il bien tourné ?
c_avant = np.mean(nuage, axis=0)
c_apres = np.mean(nuage_tourne, axis=0)
print(f"Barycentre avant : {c_avant}")
print(f"Barycentre après : {c_apres}")
print(f"Distance conservée : {np.linalg.norm(c_avant):.4f} vs {np.linalg.norm(c_apres):.4f}")
14. Le test de positionnement
Ce questionnaire vous permet d'évaluer votre niveau avant de rejoindre la formation. 20 questions, 4 choix, une seule bonne réponse. Répondez honnêtement : il n'y a aucun piège, juste une vérification de vos acquis.
Test de Positionnement
10 questions Python + 10 questions Algèbre Linéaire. Durée estimée : 10 minutes.
1 Quel est le résultat de type(3.14) en Python ?
2 Comment accéder au troisième élément d'une liste L ?
3 Quelle instruction crée un dictionnaire en Python ?
4 Que retourne len([1, 2, 3, 4]) ?
5 Quelle est la sortie de : [x**2 for x in range(4)] ?
6 Quelle bibliothèque utilise-t-on pour charger un fichier CSV sous forme de tableau numérique ?
7 Quel est le résultat de np.array([1,2,3]).shape ?
8 Comment sélectionner toutes les lignes de la deuxième colonne d'un array A de shape (100, 3) ?
9 Que fait np.mean(A, axis=0) sur un array de shape (100, 3) ?
10 Quelle fonction Python permet de définir un bloc de code réutilisable ?
11 Quelle est la norme du vecteur (3, 4, 0) ?
12 Quel est le produit scalaire de (1, 0, 0) et (0, 1, 0) ?
13 Que signifie un produit scalaire nul entre deux vecteurs non nuls ?
14 Quel est le produit vectoriel de (1, 0, 0) et (0, 1, 0) ?
15 Quelle est la dimension du résultat de la multiplication d'une matrice (3x3) par un vecteur (3x1) ?
16 Que représente la matrice identité (I) en géométrie 3D ?
17 Si une matrice de rotation R tourne un objet de 30 degrés, que fait R inverse ?
18 Quelle matrice effectue un changement d'échelle qui double toutes les dimensions ?
19 Quelle propriété est conservée par une matrice de rotation ?
20 En NumPy, quel opérateur effectue une multiplication matricielle ?
Votre score
À revoir en priorité
Vos prérequis sont validés. La suite logique : le programme complet, puis quinze minutes d'échange sur votre situation.
Ce n'est pas un refus, c'est une indication. Les points manqués se rattrapent en quelques heures : reprenez cet article, puis repassez le test quand vous voudrez.
Sur ce sujet : Le programme de la formation, module par module.
Et après les prérequis ?
Ces bases sont le premier maillon. Le guide gratuit Architecte IA de Systèmes 3D montre où elles mènent : du nuage de points brut au Smart Point Cloud et aux agents spatiaux, en 24 chapitres et 172 pages, à lire en ligne ou en PDF.
La formation, elle, reprend chaque maillon sur des projets concrets.