Prérequis Python et Algèbre Linéaire pour la 3D

Tout ce qu'il faut maîtriser avant de rejoindre la formation "Architecte IA de Systèmes 3D en Production".
Débutant
45 min
Python, NumPy, Algèbre Linéaire
"On ne construit pas un pipeline 3D industriel sans fondations solides. Python est votre outil ; l'algèbre linéaire est votre langage. Ce guide vous donne les deux en accéléré."

1. Installer Python : Votre Laboratoire de Travail

La première étape est de disposer d'un environnement Python propre et reproductible. En 2026, Miniconda reste 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).

installation.sh
# 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.11 -y
conda activate prereq-3d

# 3. Installer les bibliothèques essentielles
pip install numpy matplotlib
Conseil : Préférez 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.11.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.

types_bases.py
# 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.

structures.py
# 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.

boucles.py
# 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]

# 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.

fonctions.py
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 de 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 effectue les opérations en C compilé, offrant des gains de performance de x100 à x1000.

3.1 Créer et Manipuler des Arrays

numpy_bases.py
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.

numpy_ops.py
# 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.61, 2.44, 1.73, 0.00, 4.38]

# Filtrage vectorisé : points à moins de 3m de l'origine
masque = distances < 3.0
points_proches = nuage[masque]
print(f"Points proches : {len(points_proches)}")
Conseil : Pensez toujours "vectorisé". Si vous écrivez une boucle 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. Lecture et Écriture de 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.

fichiers_io.py
import numpy as np
import json

# ---- CSV : charger un nuage de points ----
# Fichier points.csv contient : x,y,z
nuage = np.loadtxt("points.csv", delimiter=",", skiprows=1)
print(f"Chargé {nuage.shape[0]} points")

# Sauvegarder un nuage filtré
np.savetxt("points_filtres.csv", nuage, delimiter=",",
           header="x,y,z", comments="")

# ---- JSON : métadonnées de projet ----
with open("projet.json", "r") as f:
    config = json.load(f)
    print(config["crs"])  # EPSG:2154

# Écrire un JSON
resultat = {"nb_points": 1234, "bbox": [0, 0, 100, 100]}
with open("resultat.json", "w") as f:
    json.dump(resultat, f, indent=2)

5. Visualisation 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.

visualisation.py
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. Mini Exercice Python : 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.

exercice_python.py
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()
Objectif atteint : Si vous pouvez exécuter ce script sans erreur et comprendre chaque ligne, vous possédez les bases Python nécessaires. Passons maintenant à l'algèbre linéaire.

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.

vecteurs.py
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 (Dot Product)

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.

dot_product.py
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°
Application 3D : Le produit scalaire sert à déterminer si une surface est face à la caméra (éclairage), à calculer des projections orthogonales, et à mesurer la planéité locale d'un nuage de points.

9. Produit Vectoriel (Cross Product) 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.

cross_product.py
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²
Attention : Le produit vectoriel n'existe qu'en 3D. L'ordre des opérandes compte : 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.

matrices.py
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.

rotations.py
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

transformations.py
# 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
Concept clé : En production, les transformations sont composées en une seule matrice 4x4 (matrice homogène) qui combine rotation, translation et échelle en une opération. C'est le standard dans tous les logiciels 3D (Blender, Unity, Open3D).

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.

projection.py
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. Mini Exercice : Rotation 3D d'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.

exercice_rotation.py
import numpy as np
import matplotlib.pyplot as plt

# 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
fig = plt.figure(figsize=(14, 6))

ax1 = fig.add_subplot(121, projection='3d')
ax1.scatter(nuage[:, 0], nuage[:, 1], nuage[:, 2],
            c='#8b5cf6', s=3)
ax1.set_title('Original')
ax1.set_xlabel('X'); ax1.set_ylabel('Y'); ax1.set_zlabel('Z')

ax2 = fig.add_subplot(122, projection='3d')
ax2.scatter(nuage_tourne[:, 0], nuage_tourne[:, 1], nuage_tourne[:, 2],
            c='#d946ef', s=3)
ax2.set_title('Après rotation 90° (Z)')
ax2.set_xlabel('X'); ax2.set_ylabel('Y'); ax2.set_zlabel('Z')

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}")
Vérification : Une rotation conserve les distances. La norme du barycentre avant et après doit être identique (aux erreurs de virgule flottante près). Si ce n'est pas le cas, votre matrice n'est pas une rotation valide.

14. QCM 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.

Python (Questions 1-10)

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 ?

Algèbre Linéaire (Questions 11-20)

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

Découvrir la Formation

Prêt à passer à la vitesse supérieure ?

Ce guide couvre les prérequis. La formation vous emmène de ces fondations vers la maîtrise complète des systèmes 3D en production.

Découvrir la Formation (120h)