Courbes de Bézier

Objectifs d'apprentissage

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

  • Comprendre l'origine et l'utilité des courbes de Bézier en CAO
  • Construire les polynômes de Bernstein
  • Tracer une courbe de Bézier cubique à partir de 4 points de contrôle
  • Identifier les propriétés géométriques des courbes de Bézier
  • Utiliser la représentation matricielle pour l'évaluation

Prérequis

  • Interpolation polynomiale
  • Courbes paramétriques
  • Multiplication matricielle

Contexte historique

L'industrie automobile et la CAO

Dans les années 1960, l'industrie automobile cherchait des moyens de représenter mathématiquement les carrosseries de voitures pour permettre leur conception assistée par ordinateur.

Pierre Bézier, ingénieur chez Renault, a développé un système révolutionnaire permettant aux designers de créer des courbes lisses en manipulant quelques points de contrôle.

💡

Avantage des courbes de Bézier

Contrairement à l'interpolation classique où le polynôme passe par tous les points, les courbes de Bézier permettent aux designers de sculpter une courbe en déplaçant des points de contrôle. La courbe est « attirée » vers ces points sans nécessairement les toucher.


Les polynômes de Bernstein

Définition

Les polynômes de Bernstein de degré nn sont définis par :

Bi,n(u)=(ni)ui(1u)ni,i=0,1,,nB_{i,n}(u) = \binom{n}{i} u^i (1-u)^{n-i}, \quad i = 0, 1, \ldots, n

u[0,1]u \in [0, 1] est le paramètre de la courbe.

Cas cubique (n = 3)

Pour les courbes de Bézier cubiques (les plus utilisées), les 4 polynômes de Bernstein sont :

B0,3(u)=(1u)3B_{0,3}(u) = (1-u)^3
B1,3(u)=3u(1u)2B_{1,3}(u) = 3u(1-u)^2
B2,3(u)=3u2(1u)B_{2,3}(u) = 3u^2(1-u)
B3,3(u)=u3B_{3,3}(u) = u^3

Propriétés fondamentales

PropriétéFormule
Partition de l'unitéi=0nBi,n(u)=1\sum_{i=0}^{n} B_{i,n}(u) = 1 pour tout uu
Non-négativitéBi,n(u)0B_{i,n}(u) \geq 0 pour u[0,1]u \in [0, 1]
Valeurs aux extrémitésB0,n(0)=1B_{0,n}(0) = 1, Bn,n(1)=1B_{n,n}(1) = 1
SymétrieBi,n(u)=Bni,n(1u)B_{i,n}(u) = B_{n-i,n}(1-u)

Définition d'une courbe de Bézier

Formulation paramétrique

Une courbe de Bézier de degré nn est définie par n+1n+1 points de contrôle P0,P1,,PnP_0, P_1, \ldots, P_n :

C(u)=i=0nPiBi,n(u),u[0,1]\mathbf{C}(u) = \sum_{i=0}^{n} P_i \cdot B_{i,n}(u), \quad u \in [0, 1]

Cas cubique détaillé

Pour 4 points de contrôle P0,P1,P2,P3P_0, P_1, P_2, P_3 :

C(u)=P0(1u)3+P13u(1u)2+P23u2(1u)+P3u3\mathbf{C}(u) = P_0(1-u)^3 + P_1 \cdot 3u(1-u)^2 + P_2 \cdot 3u^2(1-u) + P_3 u^3

En coordonnées :

x(u)=x0(1u)3+3x1u(1u)2+3x2u2(1u)+x3u3x(u) = x_0(1-u)^3 + 3x_1 u(1-u)^2 + 3x_2 u^2(1-u) + x_3 u^3
y(u)=y0(1u)3+3y1u(1u)2+3y2u2(1u)+y3u3y(u) = y_0(1-u)^3 + 3y_1 u(1-u)^2 + 3y_2 u^2(1-u) + y_3 u^3

Propriétés géométriques

Passage par les extrémités

La courbe passe par le premier et le dernier point de contrôle :

C(0)=P0etC(1)=Pn\mathbf{C}(0) = P_0 \quad \text{et} \quad \mathbf{C}(1) = P_n

Les points intermédiaires P1,,Pn1P_1, \ldots, P_{n-1} « attirent » la courbe mais ne sont généralement pas sur la courbe.

Tangentes aux extrémités

La tangente en u=0u = 0 est dirigée vers P1P_1 :

C(0)=n(P1P0)\mathbf{C}'(0) = n(P_1 - P_0)

La tangente en u=1u = 1 est dirigée depuis Pn1P_{n-1} :

C(1)=n(PnPn1)\mathbf{C}'(1) = n(P_n - P_{n-1})

Pour une courbe cubique :

dydxu=0=y1y0x1x0\frac{dy}{dx}\bigg|_{u=0} = \frac{y_1 - y_0}{x_1 - x_0}
dydxu=1=y3y2x3x2\frac{dy}{dx}\bigg|_{u=1} = \frac{y_3 - y_2}{x_3 - x_2}

Enveloppe convexe

La courbe de Bézier est entièrement contenue dans l'enveloppe convexe de ses points de contrôle.

Contrôle intuitif

Cette propriété garantit que la courbe ne s'éloigne jamais « trop » des points de contrôle. Les designers peuvent ainsi prédire approximativement où passera la courbe.

Invariance affine

Les transformations affines (translation, rotation, mise à l'échelle) peuvent être appliquées directement aux points de contrôle.


Représentation matricielle

Forme matricielle

La courbe de Bézier cubique peut s'écrire :

C(u)=UMBezP\mathbf{C}(u) = \mathbf{U} \cdot M_{Bez} \cdot \mathbf{P}

où :

U=(u3u2u1)\mathbf{U} = \begin{pmatrix} u^3 & u^2 & u & 1 \end{pmatrix}
MBez=(1331363033001000)M_{Bez} = \begin{pmatrix} -1 & 3 & -3 & 1 \\ 3 & -6 & 3 & 0 \\ -3 & 3 & 0 & 0 \\ 1 & 0 & 0 & 0 \end{pmatrix}
P=(P0P1P2P3)\mathbf{P} = \begin{pmatrix} P_0 \\ P_1 \\ P_2 \\ P_3 \end{pmatrix}

Vérification

Développons le produit pour u=0u = 0 :

U=(0001)\mathbf{U} = \begin{pmatrix} 0 & 0 & 0 & 1 \end{pmatrix}
UMBez=(1000)\mathbf{U} \cdot M_{Bez} = \begin{pmatrix} 1 & 0 & 0 & 0 \end{pmatrix}

Donc C(0)=P0\mathbf{C}(0) = P_0 \quad \checkmark


Exemple numérique

Points de contrôle

Pointxy
P0P_000
P1P_112
P2P_232
P3P_340

Calcul en u = 0.5

B0,3(0.5)=(0.5)3=0.125B_{0,3}(0.5) = (0.5)^3 = 0.125
B1,3(0.5)=3×0.5×(0.5)2=0.375B_{1,3}(0.5) = 3 \times 0.5 \times (0.5)^2 = 0.375
B2,3(0.5)=3×(0.5)2×0.5=0.375B_{2,3}(0.5) = 3 \times (0.5)^2 \times 0.5 = 0.375
B3,3(0.5)=(0.5)3=0.125B_{3,3}(0.5) = (0.5)^3 = 0.125
x(0.5)=0×0.125+1×0.375+3×0.375+4×0.125=2.0x(0.5) = 0 \times 0.125 + 1 \times 0.375 + 3 \times 0.375 + 4 \times 0.125 = 2.0
y(0.5)=0×0.125+2×0.375+2×0.375+0×0.125=1.5y(0.5) = 0 \times 0.125 + 2 \times 0.375 + 2 \times 0.375 + 0 \times 0.125 = 1.5

Le point milieu de la courbe est donc (2.0,1.5)(2.0, 1.5).


Raccordement de courbes

Continuité C⁰

Deux courbes sont raccordées en C0C^0 si elles partagent un point :

P3(1)=P0(2)P_3^{(1)} = P_0^{(2)}

Continuité C¹

Pour une continuité de la tangente, les trois points P2(1),P3(1)=P0(2),P1(2)P_2^{(1)}, P_3^{(1)} = P_0^{(2)}, P_1^{(2)} doivent être alignés :

P3(1)P2(1)=P1(2)P0(2)P_3^{(1)} - P_2^{(1)} = P_1^{(2)} - P_0^{(2)}

Cette égalité vient de C1(1)=3(P3(1)P2(1))\mathbf{C}_1'(1) = 3(P_3^{(1)} - P_2^{(1)}) et C2(0)=3(P1(2)P0(2))\mathbf{C}_2'(0) = 3(P_1^{(2)} - P_0^{(2)}) : les deux vecteurs dérivés doivent coïncider, pas seulement être parallèles. Avec P3(1)=P0(2)P_3^{(1)} = P_0^{(2)}, cela revient à dire que le point de jonction est le milieu de P2(1)P_2^{(1)} et P1(2)P_1^{(2)}.

Continuité G¹

Si on demande seulement la même direction (pas la même magnitude), on parle de continuité géométrique G1G^1 :

P3(1)P2(1)=α(P1(2)P0(2)),α>0P_3^{(1)} - P_2^{(1)} = \alpha(P_1^{(2)} - P_0^{(2)}), \quad \alpha > 0

L'alignement des trois points suffit alors, avec α>0\alpha > 0 pour garder le même sens. La continuité C1C^1 est le cas particulier α=1\alpha = 1.


Courbes de Bézier fermées

Construction

Pour créer une courbe fermée, on peut joindre plusieurs segments de Bézier en boucle, en assurant la continuité C1C^1 au point de fermeture.


Extension aux surfaces

Surfaces de Bézier

Une surface de Bézier bicubique est définie par une grille de 4×4=164 \times 4 = 16 points de contrôle :

S(u,v)=i=03j=03PijBi,3(u)Bj,3(v)\mathbf{S}(u, v) = \sum_{i=0}^{3} \sum_{j=0}^{3} P_{ij} \cdot B_{i,3}(u) \cdot B_{j,3}(v)

u,v[0,1]u, v \in [0, 1].

Cette formulation est très utilisée en modélisation 3D.


Algorithme Python

bezier.pypython
import numpy as np

def bernstein(n, i, u):
  """
  Calcule le polynôme de Bernstein B_{i,n}(u).
  """
  from math import comb
  return comb(n, i) * (u ** i) * ((1 - u) ** (n - i))

def bezier_curve(control_points, num_points=100):
  """
  Génère une courbe de Bézier.

  Paramètres:
      control_points : liste de points [(x0,y0), (x1,y1), ...]
      num_points : nombre de points à générer

  Retourne:
      points : tableau (num_points, 2) des coordonnées
  """
  P = np.array(control_points)
  n = len(P) - 1

  u_values = np.linspace(0, 1, num_points)
  curve = np.zeros((num_points, 2))

  for k, u in enumerate(u_values):
      point = np.zeros(2)
      for i in range(n + 1):
          point += P[i] * bernstein(n, i, u)
      curve[k] = point

  return curve

def bezier_matrix_cubic(control_points, u):
  """
  Évalue une courbe de Bézier cubique par la forme matricielle.
  """
  P = np.array(control_points)

  M_bez = np.array([
      [-1,  3, -3, 1],
      [ 3, -6,  3, 0],
      [-3,  3,  0, 0],
      [ 1,  0,  0, 0]
  ])

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

  return U @ M_bez @ P

def bezier_tangent_cubic(control_points, u):
  """
  Calcule la tangente à une courbe de Bézier cubique.
  """
  P = np.array(control_points)
  n = 3

  # Dérivée : utilise les différences des points de contrôle
  dP = n * np.diff(P, axis=0)  # Points de la courbe dérivée

  # La dérivée est une Bézier de degré n-1
  tangent = np.zeros(2)
  for i in range(n):
      tangent += dP[i] * bernstein(n - 1, i, u)

  return tangent

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

# Générer la courbe
curve = bezier_curve(points, 50)

print("Points de la courbe de Bézier :")
for u in [0, 0.25, 0.5, 0.75, 1.0]:
  pt = bezier_matrix_cubic(points, u)
  print(f"  C({u}) = ({pt[0]:.3f}, {pt[1]:.3f})")

print("\nTangentes :")
for u in [0, 0.5, 1.0]:
  tang = bezier_tangent_cubic(points, u)
  print(f"  C'({u}) = ({tang[0]:.3f}, {tang[1]:.3f})")

Résumé

ConceptDescription
Polynômes de BernsteinBi,n(u)=(ni)ui(1u)niB_{i,n}(u) = \binom{n}{i}u^i(1-u)^{n-i}
Courbe de BézierC(u)=PiBi,n(u)\mathbf{C}(u) = \sum P_i B_{i,n}(u)
Passage aux extrémitésC(0)=P0\mathbf{C}(0) = P_0, C(1)=Pn\mathbf{C}(1) = P_n
TangentesDirigées par P1P0P_1 - P_0 et PnPn1P_n - P_{n-1}
Enveloppe convexeLa courbe reste dans l'enveloppe des points

Pour aller plus loin

La prochaine leçon présentera les courbes B-spline, qui offrent un meilleur contrôle local : modifier un point de contrôle n'affecte qu'une partie de la courbe, contrairement aux courbes de Bézier où tout changement affecte l'ensemble.