Courbes B-Spline

Objectifs d'apprentissage

À la fin de cette leçon, vous serez en mesure de :

  • Expliquer l'avantage du contrôle local des B-splines par rapport à Bézier
  • Construire les fonctions de mélange cubiques
  • Tracer une courbe B-spline à partir de points de contrôle
  • Assurer le passage par les extrémités (points triplés)
  • Comparer les courbes de Bézier et B-spline

Prérequis

  • Courbes de Bézier
  • Polynômes cubiques par morceaux

Motivation : le contrôle local

Limitation des courbes de Bézier

Dans une courbe de Bézier, chaque point de contrôle influence toute la courbe. Modifier un seul point change l'ensemble de la forme.

Pour les applications de conception (CAO), cela pose problème : un designer qui veut ajuster une petite partie de la courbe doit anticiper les effets globaux.

L'avantage des B-splines

Les B-splines (Basis splines) offrent un contrôle local : modifier un point de contrôle n'affecte qu'une portion limitée de la courbe.

💡

Comparaison

  • Bézier : 1 point modifié → toute la courbe change
  • B-spline : 1 point modifié → seule la région voisine change

Les fonctions de mélange cubiques

Définition

Une B-spline cubique uniforme utilise 4 fonctions de mélange définies sur :

Propriétés

PropriétéDescription
Partition de l'unité pour tout
Non-négativité
Support localChaque fonction ne couvre que 4 segments
Symétrie,

Valeurs aux extrémités

Fonctionu = 0u = 1
1/60
4/61/6
1/64/6
01/6
4(degré = 3)

Support compact

Chaque Nᵢ,ₖ est non-nulle sur k intervalles

Partition de l'unité

Σ Nᵢ,ₖ(t) = 1 pour tout t


Définition d'une courbe B-spline

Formulation

Une courbe B-spline cubique définie par les points de contrôle est :

pour .

Courbe complète

Pour points de contrôle , la courbe est composée de segments B-spline raccordés :


Représentation matricielle

Forme matricielle

où :

Comparaison avec Bézier

AspectBézierB-spline
Matrice
Facteur11/6
Passage aux extrémitésOui (toujours)Non (par défaut)

Le problème du passage par les extrémités

Observation

Contrairement aux courbes de Bézier, une B-spline ne passe pas automatiquement par ses points de contrôle extrêmes.

En :

Solution : les points triplés

Pour forcer le passage par , on triple le premier point de contrôle :

Ainsi, le segment utilise trois fois :

Visualisation interactive

P0
P1
P2
P3
P4
P5

Contrôle local

Bouger un point n'affecte que 4 segments voisins

vs Bézier

Bézier : tout point affecte toute la courbe

En pratique

Pour une courbe B-spline passant par ses extrémités avec points de contrôle « utiles », on définit :

  • (début)
  • (fin)

Propriétés des B-splines

Contrôle local

Un point de contrôle n'influence que les segments .

Continuité automatique

Aux jonctions entre segments, la courbe B-spline est automatiquement continue (fonction, dérivée première et dérivée seconde continues).

Convexité locale

Chaque segment est contenu dans l'enveloppe convexe de ses 4 points de contrôle.


Jonction de segments B-spline

Principe

Quand passe de 1 (fin d'un segment) à 0 (début du suivant), les groupes de points se décalent :

  • Segment : utilise
  • Segment : utilise

Les 3 points communs assurent la continuité .

Visualisation

Si les points sont alignés, la courbe passe « droit » entre les segments. Sinon, elle tourne de manière fluide.


Exemple numérique

Points de contrôle

Pointxy
00
12
32
40

Avec points triplés

Pour le passage par les extrémités :

Calcul en u = 0.5 (segment central)

Le segment central utilise :


Comparaison Bézier vs B-spline

AspectBézierB-spline
ContrôleGlobalLocal
Passage aux extrémitésAutomatiqueNécessite points triplés
Continuité aux jonctionsÀ gérer manuellementAutomatiquement C²
IntuitivitéPlus simple à comprendrePlus puissant pour le design
ApplicationsPolices, icônesCAO, animation 3D

Extension aux surfaces

Surfaces B-spline

Une surface B-spline bicubique est définie par une grille de points de contrôle :

Ces surfaces sont très utilisées en modélisation 3D pour créer des formes organiques.


Algorithme Python

bspline.pypython
import numpy as np

def blend_functions(u):
  """
  Calcule les 4 fonctions de mélange B-spline cubiques.
  """
  u2, u3 = u * u, u * u * u

  b_m1 = (1 - u) ** 3 / 6
  b_0 = (3 * u3 - 6 * u2 + 4) / 6
  b_1 = (-3 * u3 + 3 * u2 + 3 * u + 1) / 6
  b_2 = u3 / 6

  return np.array([b_m1, b_0, b_1, b_2])

def bspline_segment(P, u):
  """
  Évalue un segment B-spline cubique.

  Paramètres:
      P : 4 points de contrôle [P_{i-1}, P_i, P_{i+1}, P_{i+2}]
      u : paramètre dans [0, 1]

  Retourne:
      point sur la courbe
  """
  b = blend_functions(u)
  return sum(b[i] * P[i] for i in range(4))

def bspline_curve(control_points, num_points=100, closed=False):
  """
  Génère une courbe B-spline complète.

  Paramètres:
      control_points : liste de points [(x, y), ...]
      num_points : nombre de points à générer par segment
      closed : si True, ferme la courbe

  Retourne:
      curve : tableau des points de la courbe
  """
  P = np.array(control_points, dtype=float)
  n = len(P) - 1

  if closed:
      # Ajouter des points pour fermer
      P = np.vstack([P[-1], P, P[0], P[1]])
  else:
      # Tripler les extrémités
      P = np.vstack([P[0], P[0], P, P[-1], P[-1]])

  n_segments = len(P) - 3
  curve = []

  for seg in range(n_segments):
      segment_points = P[seg:seg + 4]
      for u in np.linspace(0, 1, num_points, endpoint=(seg == n_segments - 1)):
          curve.append(bspline_segment(segment_points, u))

  return np.array(curve)

def bspline_matrix(P, u):
  """
  Évalue un segment B-spline par la forme matricielle.
  """
  M_b = np.array([
      [-1,  3, -3, 1],
      [ 3, -6,  3, 0],
      [-3,  0,  3, 0],
      [ 1,  4,  1, 0]
  ]) / 6

  U = np.array([u**3, u**2, u, 1])

  return U @ M_b @ P

# Exemple
control_points = [(0, 0), (1, 2), (3, 2), (4, 0)]

curve = bspline_curve(control_points, num_points=20)

print("Courbe B-spline :")
for i in range(0, len(curve), 10):
  print(f"  Point {i}: ({curve[i, 0]:.3f}, {curve[i, 1]:.3f})")

# Comparaison avec segment central
P = np.array(control_points)
print("\nSegment central (u=0.5):")
pt = bspline_segment(P, 0.5)
print(f"  ({pt[0]:.3f}, {pt[1]:.3f})")

Résumé

ConceptDescription
Fonctions de mélange4 fonctions cubiques
Contrôle local1 point affecte seulement 4 segments
ContinuitéAutomatiquement
Passage aux extrémitésPoints triplés :
Représentation matricielle

Pour aller plus loin

La prochaine leçon abordera l'interpolation de surfaces, où nous verrons comment étendre les techniques d'interpolation polynomiale aux fonctions de deux variables .