Les enveloppes de courbes
Grand Oral · mathématiques, HGGSP, sciences de l'ingénieur, physique-chimie, NSI
Un support de connaissances pour construire sa propre question
← Tous les textes du Grand Oral
MathsHGGSPSIPCNSI
Tendez des fils entre deux règles graduées, et une courbe apparaît alors qu'aucun fil n'est courbe. Tirez au canon sous tous
les angles possibles, et les trajectoires dessinent la frontière de la zone que l'on peut atteindre. Faites passer une fraise
le long d'un trajet, et la pièce prend la forme tracée par les positions successives de l'outil. Dans les trois cas, une
courbe est tangente à toutes les courbes d'une famille : c'est leur enveloppe. Cette notion relie le calcul
des tangentes, la géométrie de Gaspard Monge, l'artillerie des guerres de la Révolution, l'usinage des pièces mécaniques et
le dessin des carrosseries. Ce texte rassemble ces connaissances ; à chacun d'y choisir une direction et d'y construire sa
question.
Sommaire
- Une courbe faite de tangentes
- Un exemple calculé : des paraboles de sommet sur un cercle
- La parabole de sûreté : jusqu'où porte un canon ?
- Gaspard Monge, la géométrie, la guerre et la paix
- Fabriquer une pièce par enveloppe : l'usinage
- Le fil tendu et les courbes de Bézier
- Les caustiques : la lumière dans une tasse
- Programmer
- Des directions pour construire sa question
Une courbe faite de tangentes
Prenons deux segments qui se rejoignent, gradués de la même façon. Relions la graduation $1$ de l'un à la graduation $n - 1$ de
l'autre, puis $2$ à $n - 2$, et ainsi de suite. Chaque fil est droit, et pourtant une courbe se dessine : chaque fil la
touche en un point et y est tangent. Plus on met de fils, plus la courbe est nette. C'est le principe de l'« art filaire », que
l'on pratique avec des clous et du fil de couleur.
var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, cssStyle: 'background:#fff;padding:0 3px;border-radius:3px'};
var voir = false;
var n = board.create('slider', [[1.6, 4.1], [3.6, 4.1], [3, 12, 40]], {snapWidth: 1, withLabel: false});
board.create('text', [1.6, 3.7, function () { return Math.round(n.Value()) + ' fils'; }], opt);
board.create('segment', [[0, 4], [0, 0]], {strokeColor: '#37474f', strokeWidth: 2, fixed: true, highlight: false});
board.create('segment', [[0, 0], [4, 0]], {strokeColor: '#37474f', strokeWidth: 2, fixed: true, highlight: false});
var fils = board.create('curve', [[0], [0]], {strokeColor: '#c62828', strokeWidth: 1.2});
fils.updateDataArray = function () {
var N = Math.round(n.Value()), X = [], Y = [];
for (var k = 0; k <= N; k++) { var t = k/N; X.push(0, 4*t, NaN); Y.push(4 - 4*t, 0, NaN); }
this.dataX = X; this.dataY = Y;
};
var env = board.create('curve', [function (t) { return 4*t*t; }, function (t) { return 4*(1 - t)*(1 - t); }, 0, 1], {strokeColor: '#1565c0', strokeWidth: 3, visible: function () { return voir; }});
board.create('button', [1.6, 3.25, 'montrer l\'enveloppe', function () { voir = !voir; board.update(); }], {fontSize: 11, useKatex: false, useMathJax: false, parse: false});
Des fils tendus entre deux segments gradués. Le curseur change le nombre de fils ; le bouton fait apparaître la courbe qu'ils enveloppent, un arc de parabole.
La même construction avec un fil et une planchette à clous. Photo : Leopoldkumar, Wikimedia Commons, domaine public (CC0).
Enveloppe d'une famille de courbes
On considère une famille de courbes qui dépendent d'un paramètre $t$. Une courbe est une enveloppe de
cette famille si, en chacun de ses points, elle est tangente à l'une des courbes de la famille, et si chaque courbe de la
famille lui est tangente en un point.
« Tangentes » veut dire ici que les deux courbes passent par un même point et y ont la même tangente. Quand les courbes sont
les représentations graphiques de deux fonctions $f$ et $g$, elles sont tangentes au point d'abscisse $x_0$ si
$f(x_0) = g(x_0)$ et $f'(x_0) = g'(x_0)$. Tout le calcul des enveloppes repose donc sur la dérivée et l'équation de la
tangente.
L'idée est ancienne. En 1673, Christiaan Huygens étudie la développée d'une courbe, l'enveloppe de ses normales, pour
construire des horloges à pendule plus régulières. En 1682, Ehrenfried Walther von Tschirnhaus étudie les caustiques,
enveloppes de rayons lumineux. En 1692 et 1694, Gottfried Wilhelm Leibniz pose la question en général et donne une méthode de
calcul. Au siècle suivant, Gaspard Monge étend la notion aux surfaces de l'espace et en fait un outil pour les ingénieurs.
Un exemple calculé : des paraboles de sommet sur un cercle
Dans un repère
orthonormé, on considère le cercle $\mathscr{C}$ de centre $(0\,;1)$ et de rayon $1$, d'équation
$x^2 + (y-1)^2 = 1$. Pour tout réel $t$ de $]0\,;1]$, le cercle a deux points d'abscisse $t$ : en résolvant
$(y-1)^2 = 1 - t^2$, on trouve les ordonnées
$$h = 1 \pm \sqrt{1 - t^2}.$$
Pour chacun de ces points, on trace la parabole qui passe par l'origine et dont le sommet est ce point. La figure montre la
famille obtenue : une courbe semble la border par le haut. On conjecture que c'est la parabole d'équation
$y = 2 - \dfrac{x^2}{2}$, qui a son sommet en $(0\,;2)$ et coupe l'axe des abscisses en $2$.
var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, cssStyle: 'background:#fff;padding:0 3px;border-radius:3px'};
board.create('segment', [[-0.4, 0], [3.4, 0]], {strokeColor: '#90a4ae', strokeWidth: 1, fixed: true, highlight: false});
board.create('segment', [[0, -1.2], [0, 2.6]], {strokeColor: '#90a4ae', strokeWidth: 1, fixed: true, highlight: false});
var tt = board.create('slider', [[1.6, 2.4], [3.2, 2.4], [0.05, 0.6, 1]], {snapWidth: 0.01, withLabel: false});
board.create('text', [1.6, 2.1, function () { return 't = ' + tt.Value().toFixed(2).replace('.', ','); }], opt);
board.create('curve', [function (s) { return Math.cos(s); }, function (s) { return 1 + Math.sin(s); }, -Math.PI/2, Math.PI/2], {strokeColor: '#78909c', strokeWidth: 1.5, dash: 2, highlight: false});
function P(t, h, x) { return h - h/(t*t)*(x - t)*(x - t); }
var fam = board.create('curve', [[0], [0]], {strokeColor: '#b0bec5', strokeWidth: 1});
fam.updateDataArray = function () {
var X = [], Y = [];
for (var k = 1; k <= 20; k++) {
var t = k/20, hs = [1 + Math.sqrt(1 - t*t), 1 - Math.sqrt(1 - t*t)];
for (var q = 0; q < 2; q++) { for (var x = -0.1; x <= 3.4; x += 0.03) { var y = P(t, hs[q], x); X.push(x); Y.push(y < -1.3 ? NaN : y); } X.push(NaN); Y.push(NaN); }
}
this.dataX = X; this.dataY = Y;
};
board.create('functiongraph', [function (x) { return 2 - x*x/2; }, -0.4, 3.4], {strokeColor: '#c62828', strokeWidth: 2.5, dash: 2, highlight: false});
var hH = function () { var t = tt.Value(); return 1 + Math.sqrt(1 - t*t); }, hB = function () { var t = tt.Value(); return 1 - Math.sqrt(1 - t*t); };
board.create('functiongraph', [function (x) { return P(tt.Value(), hH(), x); }, -0.1, 3.4], {strokeColor: '#1565c0', strokeWidth: 2.5, highlight: false});
board.create('functiongraph', [function (x) { return P(tt.Value(), hB(), x); }, -0.1, 3.4], {strokeColor: '#2e7d32', strokeWidth: 2.5, highlight: false});
board.create('point', [function () { return tt.Value(); }, hH], {name: '', size: 3, color: '#1565c0', fixed: true});
board.create('point', [function () { return tt.Value(); }, hB], {name: '', size: 3, color: '#2e7d32', fixed: true});
var x0 = function (h) { return 2*(2 - h)/tt.Value(); };
board.create('point', [function () { return x0(hH()); }, function () { var x = x0(hH()); return 2 - x*x/2; }], {name: '', size: 4, face: 'x', color: '#c62828', fixed: true});
board.create('point', [function () { return x0(hB()); }, function () { var x = x0(hB()); return 2 - x*x/2; }], {name: '', size: 4, face: 'x', color: '#c62828', fixed: true});
La famille de paraboles (en gris), le cercle des sommets (pointillés) et l'enveloppe conjecturée $y = 2 - \dfrac{x^2}{2}$ (en rouge). Le curseur choisit $t$ : la parabole de sommet haut (bleue) et celle de sommet bas (verte) touchent l'enveloppe aux points marqués d'une croix, quand ils sont dans le cadre.
L'équation des paraboles. Une parabole de sommet $(t\,;h)$ a une équation de la forme $y = h + a(x-t)^2$. Elle
passe par l'origine si et seulement si $h + at^2 = 0$, c'est-à-dire $a = -\dfrac{h}{t^2}$. La parabole de la famille est donc
la courbe de
$$P(x) = h - \frac{h}{t^2}(x - t)^2.$$
Comme le point $(t\,;h)$ est sur le cercle, $t^2 + (h-1)^2 = 1$, soit $t^2 = 2h - h^2 = h(2-h)$. On en déduit
$\dfrac{h}{t^2} = \dfrac{1}{2-h}$ : c'est cette relation qui va tout faire marcher.
La démonstration. Étudions l'écart entre la courbe conjecturée et une parabole de la famille :
$$D(x) = 2 - \frac{x^2}{2} - P(x).$$
En développant $\dfrac{h}{t^2}(x-t)^2 = \dfrac{h}{t^2}x^2 - \dfrac{2h}{t}x + h$, les termes $h$ et $-h$ se compensent et il reste un
polynôme du second degré :
$$D(x) = \left(\frac{h}{t^2} - \frac{1}{2}\right)x^2 - \frac{2h}{t}\,x + 2.$$
Son coefficient dominant vaut $\dfrac{1}{2-h} - \dfrac{1}{2} = \dfrac{h}{2(2-h)}$, qui est strictement positif car $0 < h < 2$.
Calculons son discriminant :
$\Delta$ & $=$ & $\dfrac{4h^2}{t^2} - 4 \times \dfrac{h}{2(2-h)} \times 2$ &
& $=$ & $\dfrac{4h^2}{t^2} - \dfrac{4h}{2-h}$ &
& $=$ & $\dfrac{4h^2}{t^2} - \dfrac{4h^2}{h(2-h)}$ &
& $=$ & $\dfrac{4h^2}{t^2} - \dfrac{4h^2}{t^2} = 0.$ &
Le discriminant est nul : $D$ a une racine double $x_0$, et $D(x) = \dfrac{h}{2(2-h)}(x - x_0)^2$ avec
$x_0 = \dfrac{2(2-h)}{t}$. Deux conséquences :
- $D(x) \geqslant 0$ pour tout $x$ : chaque parabole de la famille est située sous la courbe $y = 2 - \dfrac{x^2}{2}$ ;
- $D(x_0) = 0$ et $D'(x_0) = 0$ : au point d'abscisse $x_0$, les deux courbes ont la même ordonnée et la même dérivée,
donc la même tangente. Elles sont tangentes.
Enfin, quand $t$ parcourt $]0\,;1]$, le point de contact $x_0$ parcourt tout l'intervalle $]0\,;2]$ pour les paraboles de sommet
haut, et $[2\,;+\infty[$ pour celles de sommet bas : tous les points de la courbe d'abscisse positive sont atteints. La parabole
$y = 2 - \dfrac{x^2}{2}$ est bien l'enveloppe de la famille.
Cette démonstration n'utilise que le second degré et la dérivée. Il existe une méthode générale, au-delà du programme : si la
famille a pour équation $F(x, y, t) = 0$, on dérive cette équation par rapport au paramètre $t$ en gardant $x$ et $y$ fixes, et
l'on élimine $t$ entre les deux équations obtenues. C'est la méthode de Leibniz.
La parabole de sûreté : jusqu'où porte un canon ?
Un canon tire ses boulets toujours à la même vitesse $v$, mais on peut choisir l'angle $\alpha$ de tir. En négligeant les
frottements de l'air, la deuxième loi de Newton donne la trajectoire, une parabole découverte par Galilée en 1638 :
$$y = x\tan\alpha - \frac{g}{2v^2\cos^2\alpha}\,x^2,$$
où $g \approx 9{,}81$ m/s² est l'intensité de la pesanteur. Quand $\alpha$ varie, on obtient une famille de paraboles. Quels
sont les points que l'on peut atteindre ?
Un calcul de second degré. Posons $u = \tan\alpha$ et $k = \dfrac{g}{2v^2}$. Comme
$\dfrac{1}{\cos^2\alpha} = 1 + \tan^2\alpha$, la trajectoire s'écrit $y = xu - kx^2(1 + u^2)$. Fixons un point $(x\,;y)$ avec
$x > 0$. Il est atteint s'il existe un angle, donc un réel $u$, tel que
$$kx^2\,u^2 - x\,u + \left(y + kx^2\right) = 0.$$
C'est une équation du second degré en $u$. Elle a une solution si et seulement si son discriminant est positif ou nul :
$$x^2 - 4kx^2\left(y + kx^2\right) \geqslant 0.$$
En divisant par $x^2$, qui est strictement positif, on obtient $1 - 4k\left(y + kx^2\right) \geqslant 0$, c'est-à-dire
$$y \leqslant \frac{1}{4k} - kx^2.$$
En remplaçant $k$ par sa valeur :
$$y \leqslant \frac{v^2}{2g} - \frac{g}{2v^2}\,x^2.$$
La courbe d'équation $y = \dfrac{v^2}{2g} - \dfrac{g}{2v^2}x^2$ est une parabole : c'est la parabole de sûreté. Les
points situés en dessous sont atteints par deux angles de tir (deux solutions $u$), les points situés au-dessus ne sont jamais
atteints, et les points de la courbe le sont par un seul angle : la trajectoire correspondante y est tangente. La parabole de
sûreté est l'enveloppe des trajectoires. Ce résultat est dû à Evangelista Torricelli, l'élève de Galilée, en 1644.
On lit sur la formule les deux records. La hauteur maximale, atteinte en tirant à la verticale, est $\dfrac{v^2}{2g}$ ; la
portée maximale au sol, pour $y = 0$, est $\dfrac{v^2}{g}$, obtenue en tirant à $45^\circ$. Un ballon lancé à
$20$ m/s monte au plus à environ $20$ m et va au plus à environ $41$ m. Dans le vide, un boulet tiré à $400$ m/s irait à plus de
$16$ km ; dans l'air, les canons de la fin du XVIIIe siècle portaient à quelques kilomètres seulement. Les frottements
changent la forme des trajectoires et de leur enveloppe, mais l'idée reste la même : il existe une frontière de la zone
atteignable, et un abri situé au-delà est sûr. D'où le nom.
var actif = false, i = 0, p = 0, pause = 0, fini = false, N = 15;
board.create('segment', [[-0.3, 0], [4.6, 0]], {strokeColor: '#78909c', strokeWidth: 1.5, fixed: true, highlight: false});
var zone = board.create('curve', [[0], [0]], {strokeWidth: 0, fillColor: '#ef9a9a', fillOpacity: 0.35, visible: function () { return fini; }});
zone.updateDataArray = function () { var X = [-0.3], Y = [2.5]; for (var x = -0.3; x <= 4.61; x += 0.05) { X.push(x); Y.push(Math.max(-0.3, 2 - x*x/8)); } X.push(4.6, -0.3); Y.push(2.5, 2.5); this.dataX = X; this.dataY = Y; };
var env = board.create('functiongraph', [function (x) { return 2 - x*x/8; }, -0.3, 4.6], {strokeColor: '#c62828', strokeWidth: 2.5, dash: 2, visible: function () { return fini; }, highlight: false});
function traj(a, x) { var u = Math.tan(a); return x*u - x*x*(1 + u*u)/8; }
var tr = board.create('curve', [[0], [0]], {strokeColor: '#1565c0', strokeWidth: 1.4});
tr.updateDataArray = function () {
var X = [], Y = [];
for (var k = 0; k <= Math.min(i, N - 1); k++) {
var a = (10 + 5*k)*Math.PI/180, portee = 4*Math.sin(2*a), xm = k < i ? portee : p*portee;
for (var s = 0; s <= 60; s++) { var x = xm*s/60; X.push(x); Y.push(traj(a, x)); }
X.push(NaN); Y.push(NaN);
}
this.dataX = X; this.dataY = Y;
};
var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, cssStyle: 'background:#fff;padding:0 3px;border-radius:3px'};
board.create('text', [2.7, 2.3, 'hors d\'atteinte'], Object.assign({}, opt, {visible: function () { return fini; }}));
board.create('point', [0, 0], {name: '', size: 3, color: '#000', fixed: true});
if ('IntersectionObserver' in window) {
new IntersectionObserver(function (e) { if (e[0].isIntersecting) { actif = true; } }, {threshold: 0.4}).observe(board.containerObj);
} else { actif = true; }
setInterval(function () {
if (!actif) { return; }
if (!fini) { p += 0.15; if (p >= 1) { p = 0; i++; if (i >= N) { fini = true; } } }
else if (++pause > 70) { fini = false; pause = 0; i = 0; p = 0; }
board.update();
}, 50);
Trajectoires d'un projectile lancé à la même vitesse sous des angles de $10^\circ$ à $80^\circ$. Quand toutes sont tracées apparaît leur enveloppe, la parabole de sûreté (en rouge) : au-dessus, la zone hors d'atteinte.
Gaspard Monge, la géométrie, la guerre et la paix
Un fils de marchand à l'école du génie. Gaspard Monge naît à Beaune en 1746, fils d'un marchand. Remarqué très
jeune (il enseigne la physique à seize ans au collège de la Trinité, à Lyon), il dessine un plan de sa ville qui attire
l'attention d'un officier du génie. Il entre en 1765 à l'école royale du génie de Mézières, où l'on forme les officiers chargés
des fortifications. Il n'y est que dessinateur : n'étant pas noble, il ne peut pas devenir officier. On lui confie alors un
problème capital, le défilement des fortifications : comment élever les remparts pour qu'une position ne puisse
pas être vue et atteinte par l'artillerie ennemie installée sur les hauteurs voisines ? On le résolvait par tâtonnements ou par
de longs calculs. Monge propose une construction géométrique simple, fondée sur une surface tangente au terrain environnant.
Ses supérieurs, la trouvant trop rapide pour être juste, la croient bâclée ; il insiste, et elle s'impose. Il devient
répétiteur, puis professeur.
Gaspard Monge (1746-1818), lithographie de François-Séraphin Delpech. Wikimedia Commons, domaine public.
La géométrie descriptive, un secret militaire. À Mézières, Monge invente la géométrie descriptive :
une méthode pour représenter sans ambiguïté un objet de l'espace par deux projections orthogonales sur deux plans, une vue de
face et une vue de dessus, et pour résoudre sur le papier les problèmes d'espace (intersections, ombres, tailles de pierre ou de
charpente). Elle est jugée si utile à la construction des fortifications qu'elle est tenue secrète : elle ne doit pas parvenir
aux ennemis du royaume. Elle n'est enseignée publiquement qu'en 1795. Le dessin technique d'aujourd'hui, avec ses vues de face, de
dessus et de côté, en descend directement.
Les guerres de la Révolution. Républicain convaincu, Monge devient ministre de la Marine en 1792. La France est en
guerre contre une coalition européenne et soumise à un blocus : il manque des armes, du salpêtre pour la poudre, du métal. À la
demande du Comité de salut public, Monge organise la fabrication : la production de salpêtre est multipliée et il rédige en 1794,
avec les chimistes Berthollet et Vandermonde, une Description de l'art de fabriquer les canons, un manuel d'une grande
clarté destiné aux ouvriers des fonderies. La même année, il participe à la fondation de l'École polytechnique, chargée de former
les ingénieurs dont l'État et l'armée ont besoin ; il y enseigne la géométrie avec passion. Il suit ensuite Bonaparte en Italie,
puis en Égypte, où il préside l'Institut d'Égypte fondé au Caire ; il reste fidèle à l'Empereur, qui le fait comte de Péluse. Exclu
de l'Institut à la Restauration, il meurt en 1818. Ses cendres sont transférées au Panthéon en 1989, pour le bicentenaire de la
Révolution.
La même science pour la paix. Les savoirs de Monge servent aussi la paix et la vie civile. La géométrie descriptive
devient l'outil des architectes, des tailleurs de pierre, des charpentiers et des constructeurs de machines. Monge fait partie de
la commission qui crée le système métrique, instrument d'unification du commerce. En 1781, il publie un Mémoire sur la théorie
des déblais et des remblais : comment transporter de la terre d'un endroit à un autre (pour une route, un canal ou un rempart)
en minimisant l'effort total ? Ce problème du transport optimal, repris en 1942 par le mathématicien soviétique
Leonid Kantorovitch pour l'économie planifiée, est aujourd'hui un domaine de recherche très actif : il a valu la médaille Fields
à Cédric Villani en 2010 et à Alessio Figalli en 2018. L'histoire de Monge illustre une question au cœur du thème « faire la
guerre, faire la paix » : un même savoir scientifique peut servir l'une et l'autre, et l'État révolutionnaire puis impérial a
organisé la science pour la mettre au service de sa puissance.
Les surfaces développables. En mathématiques, Monge étend les enveloppes à l'espace. Une famille de plans qui
dépend d'un paramètre a, en général, une surface enveloppe, tangente à chacun des plans le long d'une droite. Ces surfaces sont
exactement celles que l'on peut dérouler sur un plan sans déchirer ni étirer la matière : les cylindres, les
cônes, et des surfaces plus étonnantes. On les appelle surfaces développables, étudiées au début des années 1770
par Euler et par Monge. Monge classe les surfaces selon la façon dont on peut les fabriquer : les surfaces de révolution sont
celles qu'un tourneur obtient sur son tour, les surfaces développables celles qu'un chaudronnier façonne dans une tôle sans
l'abîmer.
var actif = false, th = 0;
var view = board.create('view3d', [[-5.5, -5.5], [11, 11], [[-1.6, 1.6], [-1.6, 1.6], [0, 2.4]]], {
projection: 'central', az: {slider: {visible: false}}, el: {slider: {visible: false, start: 0.45}}, bank: {slider: {visible: false}},
xAxis: {visible: false}, yAxis: {visible: false}, zAxis: {visible: false},
xPlaneRear: {visible: false}, yPlaneRear: {visible: false}, zPlaneRear: {visible: false}
});
var m = 0.65;
view.create('parametricsurface3d', [
function (u, v) { return m*v*Math.cos(u); }, function (u, v) { return m*v*Math.sin(u); }, function (u, v) { return v; },
[0, 2*Math.PI], [0, 2.2]
], {strokeColor: '#90a4ae', strokeWidth: 0.6, strokeOpacity: 0.7, stepsU: 28, stepsV: 6});
view.create('parametricsurface3d', [
function (s, w) { return s*m*Math.cos(th) - w*Math.sin(th); },
function (s, w) { return s*m*Math.sin(th) + w*Math.cos(th); },
function (s, w) { return s; },
[0, 2.3], [-1.1, 1.1]
], {strokeColor: '#1e88e5', strokeWidth: 0.8, strokeOpacity: 0.6, stepsU: 6, stepsV: 6});
view.create('curve3d', [function (s) { return s*m*Math.cos(th); }, function (s) { return s*m*Math.sin(th); }, function (s) { return s; }, [0, 2.3]], {strokeColor: '#c62828', strokeWidth: 3});
if ('IntersectionObserver' in window) {
new IntersectionObserver(function (e) { actif = e[0].isIntersecting; }, {threshold: 0.2}).observe(board.containerObj);
} else { actif = true; }
setInterval(function () { if (!actif) { return; } th += 0.025; board.update(); }, 50);
Un plan (en bleu) tourne autour du sommet du cône en restant tangent à sa surface le long d'une droite (en rouge). Le cône est l'enveloppe de cette famille de plans : c'est une surface développable, que l'on peut fabriquer en roulant une feuille.
Fabriquer une pièce par enveloppe : l'usinage
Dans les ateliers, de nombreuses pièces sont obtenues par enveloppe : la forme de la pièce n'est pas celle de
l'outil, mais l'enveloppe des positions successives de l'outil qui se déplace. C'est le cœur des métiers de l'usinage (fraiseur,
tourneur, régleur de machines à commande numérique), de la découpe et de la conception mécanique.
Le fraisage. Une fraise est un outil cylindrique qui tourne très vite et enlève la matière. Vue de dessus, c'est un
disque de rayon $r$. Quand son centre suit un trajet, le bord de la rainure creusée est l'enveloppe des cercles de rayon
$r$ centrés sur ce trajet : deux courbes « parallèles » au trajet, à la distance $r$. Inversement, pour obtenir un contour
voulu, la machine doit faire passer le centre de l'outil à la distance $r$ de ce contour : c'est la correction de
rayon d'outil, calculée automatiquement par les machines à commande numérique. Une conséquence pratique : un coin
intérieur usiné ne peut jamais être plus pointu que la fraise. Il est arrondi, avec un rayon au moins égal à $r$ ; les
concepteurs le prévoient sur leurs plans.
var actif = false, s = 0, pause = 0, r = 0.45;
function c(x) { return [x, 0.9*Math.sin(x)]; }
function nrm(x) { var dx = 1, dy = 0.9*Math.cos(x), l = Math.hypot(dx, dy); return [-dy/l, dx/l]; }
var bande = board.create('curve', [[0], [0]], {strokeWidth: 0, fillColor: '#ffcc80', fillOpacity: 0.6});
bande.updateDataArray = function () {
var X = [], Y = [], x;
for (x = 0; x <= s; x += 0.04) { var n = nrm(x), p = c(x); X.push(p[0] + r*n[0]); Y.push(p[1] + r*n[1]); }
for (x = s; x >= 0; x -= 0.04) { var n2 = nrm(x), p2 = c(x); X.push(p2[0] - r*n2[0]); Y.push(p2[1] - r*n2[1]); }
this.dataX = X; this.dataY = Y;
};
var bords = board.create('curve', [[0], [0]], {strokeColor: '#c62828', strokeWidth: 2});
bords.updateDataArray = function () {
var X = [], Y = [], x, q;
for (q = -1; q <= 1; q += 2) { for (x = 0; x <= s; x += 0.04) { var n = nrm(x), p = c(x); X.push(p[0] + q*r*n[0]); Y.push(p[1] + q*r*n[1]); } X.push(NaN); Y.push(NaN); }
this.dataX = X; this.dataY = Y;
};
board.create('curve', [function (x) { return x; }, function (x) { return 0.9*Math.sin(x); }, 0, 2*Math.PI], {strokeColor: '#546e7a', strokeWidth: 1, dash: 2, highlight: false});
var traces = board.create('curve', [[0], [0]], {strokeColor: '#90a4ae', strokeWidth: 0.7});
traces.updateDataArray = function () {
var X = [], Y = [];
for (var x = 0; x <= s; x += 0.5) { var p = c(x); for (var a = 0; a <= 2*Math.PI + 0.01; a += 0.2) { X.push(p[0] + r*Math.cos(a)); Y.push(p[1] + r*Math.sin(a)); } X.push(NaN); Y.push(NaN); }
this.dataX = X; this.dataY = Y;
};
board.create('circle', [function () { return c(s); }, r], {strokeColor: '#263238', strokeWidth: 2, fillColor: '#78909c', fillOpacity: 0.7, highlight: false});
if ('IntersectionObserver' in window) {
new IntersectionObserver(function (e) { if (e[0].isIntersecting) { actif = true; } }, {threshold: 0.4}).observe(board.containerObj);
} else { actif = true; }
setInterval(function () {
if (!actif) { return; }
if (s < 2*Math.PI) { s = Math.min(2*Math.PI, s + 0.04); } else if (++pause > 50) { s = 0; pause = 0; }
board.update();
}, 50);
Une fraise (disque gris) dont le centre suit le trajet en pointillés. La rainure creusée (en orange) est bordée par l'enveloppe des positions successives de l'outil (en rouge).
La découpe. Les machines de découpe au laser, au plasma ou au jet d'eau fonctionnent de la même façon. Le faisceau
n'est pas infiniment fin : il enlève une bande de matière, la saignée, de quelques dixièmes de millimètre pour un laser
et de l'ordre du millimètre pour un jet d'eau. La pièce découpée est bordée par l'enveloppe des positions du faisceau ; pour
obtenir la cote exacte, la machine décale sa trajectoire d'une demi-saignée, c'est la compensation de saignée.
Les engrenages taillés par génération. Les dents d'un engrenage ne sont pas taillées une à une à la forme voulue.
On utilise un outil à dents droites, une crémaillère ou une fraise-mère (une sorte de vis dont les filets sont coupants),
qui tourne en même temps que la roue à tailler, comme si les deux engrenaient. À chaque instant, le flanc droit de l'outil
occupe une nouvelle position par rapport à la roue, et le flanc de la dent obtenue est l'enveloppe de toutes ces
positions. On parle de taillage par génération. La courbe obtenue est une développante de cercle :
celle que décrit l'extrémité d'un fil que l'on déroule en le gardant tendu autour d'un cylindre. Étudié par Euler au
XVIIIe siècle, ce profil a deux qualités précieuses : les dents roulent l'une sur l'autre en transmettant une vitesse
parfaitement régulière, et cela reste vrai même si l'écart entre les deux roues est légèrement imprécis. Presque tous les
engrenages des voitures, des vélos et des machines l'utilisent.
var actif = false, ph = 0, pause = 0, M = 1.6;
board.create('circle', [[0, 0], 1], {strokeColor: '#546e7a', strokeWidth: 2, fillColor: '#eceff1', fillOpacity: 1, fixed: true, highlight: false});
function I(f) { return [Math.cos(f) + f*Math.sin(f), Math.sin(f) - f*Math.cos(f)]; }
var flancs = board.create('curve', [[0], [0]], {strokeColor: '#90a4ae', strokeWidth: 1.2});
flancs.updateDataArray = function () {
var X = [], Y = [];
for (var f = 0.1; f <= ph + 1e-9; f += 0.1) { var p = I(f), d = [Math.cos(f), Math.sin(f)]; X.push(p[0] - 0.55*d[0], p[0] + 0.55*d[0], NaN); Y.push(p[1] - 0.55*d[1], p[1] + 0.55*d[1], NaN); }
this.dataX = X; this.dataY = Y;
};
var dev = board.create('curve', [[0], [0]], {strokeColor: '#c62828', strokeWidth: 3});
dev.updateDataArray = function () { var X = [], Y = []; for (var f = 0; f <= ph + 1e-9; f += 0.02) { var p = I(f); X.push(p[0]); Y.push(p[1]); } this.dataX = X; this.dataY = Y; };
board.create('segment', [function () { return [Math.cos(ph), Math.sin(ph)]; }, function () { return I(ph); }], {strokeColor: '#ef6c00', strokeWidth: 2.5, highlight: false});
board.create('point', [function () { return I(ph)[0]; }, function () { return I(ph)[1]; }], {name: '', size: 3, color: '#ef6c00', fixed: true});
if ('IntersectionObserver' in window) {
new IntersectionObserver(function (e) { if (e[0].isIntersecting) { actif = true; } }, {threshold: 0.4}).observe(board.containerObj);
} else { actif = true; }
setInterval(function () {
if (!actif) { return; }
if (ph < M) { ph = Math.min(M, ph + 0.02); } else if (++pause > 50) { ph = 0; pause = 0; }
board.update();
}, 50);
Un fil (orange) se déroule en restant tendu autour d'un cercle : son extrémité décrit une développante de cercle (en rouge). Les segments gris sont les positions successives du flanc droit de l'outil vues depuis la roue ; leur enveloppe est la même courbe.
Taillage d'une roue dentée par une fraise-mère (à gauche, en bas) : l'outil et la roue tournent ensemble, et chaque dent est l'enveloppe des positions de l'outil. Photo : Kolossos, Wikimedia Commons, licence CC BY-SA 3.0.
D'autres métiers. Les cames d'un moteur, qui ouvrent et ferment les soupapes, ont un profil calculé
comme enveloppe des positions du poussoir qui les suit. Les chaudronniers et les tôliers tracent à plat les
surfaces développables de Monge (conduits, trémies, coques) avant de les rouler ou de les plier ; les tailleurs de pierre et
les charpentiers, notamment chez les Compagnons du Devoir, pratiquent encore le « trait », héritier de la géométrie descriptive.
Enfin, les logiciels de conception assistée par ordinateur (CAO) calculent les surfaces balayées par les outils pour simuler
l'usinage avant de lancer la machine.
Le fil tendu et les courbes de Bézier
Au début des années 1960, les constructeurs automobiles veulent dessiner les carrosseries par ordinateur et commander
directement les machines qui fraisent les maquettes. Il faut pour cela décrire des courbes souples avec peu de nombres. Chez
Citroën, Paul de Casteljau trouve une méthode dès 1959, mais l'entreprise la garde secrète. Chez Renault, l'ingénieur Pierre
Bézier développe la même idée et la publie : ces courbes portent aujourd'hui son nom.
Une courbe de Bézier du second degré est définie par trois points $P_0$, $P_1$ et $P_2$. Pour chaque
réel $t$ de $[0\,;1]$, la construction de De Casteljau place :
- le point $A$ sur $[P_0P_1]$ tel que $\overrightarrow{P_0A} = t\,\overrightarrow{P_0P_1}$, et le point $B$ sur $[P_1P_2]$ tel
que $\overrightarrow{P_1B} = t\,\overrightarrow{P_1P_2}$ ;
- puis le point $M$ sur $[AB]$ tel que $\overrightarrow{AM} = t\,\overrightarrow{AB}$.
Quand $t$ va de $0$ à $1$, le point $M$ décrit la courbe. En coordonnées, on trouve que le point $M(t)$ est
$$(1-t)^2 P_0 + 2t(1-t)\,P_1 + t^2 P_2,$$
ce qui signifie que chaque coordonnée de $M$ est un polynôme du second degré en $t$ : la courbe est un arc de parabole. En
dérivant chaque coordonnée, on obtient
$$\begin{aligned} M'(t) &= 2(1-t)\,\overrightarrow{P_0P_1} + 2t\,\overrightarrow{P_1P_2} \\ &= 2\,\overrightarrow{AB}, \end{aligned}$$
car $\overrightarrow{AB} = (1-t)\,\overrightarrow{P_0P_1} + t\,\overrightarrow{P_1P_2}$. Le vecteur dérivé, qui dirige la
tangente, est colinéaire à $\overrightarrow{AB}$ : le segment $[AB]$ est tangent à la courbe en $M$. Or les segments
$[AB]$ sont exactement les fils tendus du début de ce texte. La courbe de Bézier est leur enveloppe.
var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, cssStyle: 'background:#fff;padding:0 3px;border-radius:3px'};
var t = board.create('slider', [[2.2, 3.25], [4.0, 3.25], [0, 0.35, 1]], {snapWidth: 0.01, withLabel: false});
board.create('text', [2.2, 2.95, function () { return 't = ' + t.Value().toFixed(2).replace('.', ','); }], opt);
var P0 = board.create('point', [0.2, 0.3], {name: 'P₀', size: 4, color: '#37474f', label: {offset: [-6, -14]}});
var P1 = board.create('point', [1.3, 3.0], {name: 'P₁', size: 4, color: '#37474f', label: {offset: [-20, 4]}});
var P2 = board.create('point', [3.9, 0.6], {name: 'P₂', size: 4, color: '#37474f', label: {offset: [4, -12]}});
board.create('segment', [P0, P1], {strokeColor: '#90a4ae', strokeWidth: 1.2});
board.create('segment', [P1, P2], {strokeColor: '#90a4ae', strokeWidth: 1.2});
function lerp(U, V, s) { return [U.X() + s*(V.X() - U.X()), U.Y() + s*(V.Y() - U.Y())]; }
var fils = board.create('curve', [[0], [0]], {strokeColor: '#cfd8dc', strokeWidth: 1});
fils.updateDataArray = function () { var X = [], Y = []; for (var k = 0; k <= 16; k++) { var a = lerp(P0, P1, k/16), b = lerp(P1, P2, k/16); X.push(a[0], b[0], NaN); Y.push(a[1], b[1], NaN); } this.dataX = X; this.dataY = Y; };
board.create('curve', [function (s) { return (1-s)*(1-s)*P0.X() + 2*s*(1-s)*P1.X() + s*s*P2.X(); }, function (s) { return (1-s)*(1-s)*P0.Y() + 2*s*(1-s)*P1.Y() + s*s*P2.Y(); }, 0, 1], {strokeColor: '#c62828', strokeWidth: 3});
var A = board.create('point', [function () { return lerp(P0, P1, t.Value())[0]; }, function () { return lerp(P0, P1, t.Value())[1]; }], {name: 'A', size: 3, color: '#1565c0', label: {offset: [-14, 4]}});
var B = board.create('point', [function () { return lerp(P1, P2, t.Value())[0]; }, function () { return lerp(P1, P2, t.Value())[1]; }], {name: 'B', size: 3, color: '#1565c0', label: {offset: [6, 4]}});
board.create('line', [A, B], {strokeColor: '#1565c0', strokeWidth: 2});
board.create('point', [function () { return A.X() + t.Value()*(B.X() - A.X()); }, function () { return A.Y() + t.Value()*(B.Y() - A.Y()); }], {name: 'M', size: 4, color: '#c62828', label: {offset: [4, -14]}});
La construction de De Casteljau. Le curseur fait varier $t$ ; on peut déplacer $P_0$, $P_1$ et $P_2$. La droite $(AB)$, en bleu, est toujours tangente à la courbe (en rouge) au point $M$, et les fils gris l'enveloppent.
Les courbes de Bézier sont partout. Les lettres de ce texte sont dessinées avec elles : les polices de caractères TrueType utilisent
des courbes du second degré, les polices PostScript des courbes du troisième degré, définies par quatre points. Les logiciels de
dessin vectoriel, le format d'image SVG, les animations et les logiciels de CAO reposent sur elles. Une courbe de Bézier du
troisième degré s'obtient en répétant la construction de De Casteljau un étage de plus.
Les caustiques : la lumière dans une tasse
Par une journée ensoleillée, on voit souvent à la surface du café ou du lait une courbe lumineuse en forme de cœur. Ce n'est
pas un reflet de la tasse, mais une caustique : les rayons du Soleil se réfléchissent sur la paroi intérieure,
cylindrique, et les rayons réfléchis ne se croisent pas en un seul point. Ils ont une enveloppe, et c'est le long de cette
enveloppe que la lumière se concentre le plus, puisque des rayons voisins s'y accumulent. Le mot vient du grec
kaustikos, « qui brûle ».
Une caustique à la surface d'un café. Photo : Daisychainnow, Wikimedia Commons, licence CC BY-SA 3.0.
Si les rayons arrivent parallèles, comme ceux du Soleil, la caustique d'un cercle de rayon $R$ est une courbe appelée
néphroïde (« en forme de rein ») ; sa pointe se trouve à la distance $\dfrac{R}{2}$ du centre. C'est exactement le
défaut des miroirs sphériques décrit dans le texte sur la parabole : un miroir en arc de cercle ne concentre pas la lumière en
un point, mais le long d'une caustique. La parabole est la seule courbe dont la caustique, pour des rayons parallèles à l'axe, se
réduit à un point : son foyer.
var opt = {fontSize: 12, useKatex: false, useMathJax: false, parse: false, cssStyle: 'background:#fff;padding:0 3px;border-radius:3px'};
var voir = false;
var n = board.create('slider', [[-1.1, -1.3], [0.1, -1.3], [4, 24, 70]], {snapWidth: 1, withLabel: false});
board.create('text', [0.25, -1.3, function () { return Math.round(n.Value()) + ' rayons'; }], opt);
board.create('circle', [[0, 0], 1], {strokeColor: '#5d4037', strokeWidth: 3, fillColor: '#3e2723', fillOpacity: 0.08, fixed: true, highlight: false});
var rays = board.create('curve', [[0], [0]], {strokeColor: '#f9a825', strokeWidth: 1, strokeOpacity: 0.8});
rays.updateDataArray = function () {
var N = Math.round(n.Value()), X = [], Y = [];
for (var k = 1; k <= N; k++) {
var c = -1 + 2*k/(N + 1), px = Math.sqrt(1 - c*c), py = c;
var rx = 1 - 2*px*px, ry = -2*px*py, tq = -2*(px*rx + py*ry);
X.push(-px, px, px + tq*rx, NaN); Y.push(c, py, py + tq*ry, NaN);
}
this.dataX = X; this.dataY = Y;
};
board.create('curve', [function (s) { return (3*Math.cos(s) - Math.cos(3*s))/4; }, function (s) { return (3*Math.sin(s) - Math.sin(3*s))/4; }, -Math.PI/2, Math.PI/2], {strokeColor: '#c62828', strokeWidth: 3, visible: function () { return voir; }});
board.create('button', [-1.1, -1.12, 'montrer la caustique', function () { voir = !voir; board.update(); }], {fontSize: 11, useKatex: false, useMathJax: false, parse: false});
Des rayons parallèles venus de la gauche se réfléchissent sur la paroi d'une tasse vue de dessus. Les rayons réfléchis enveloppent une néphroïde, que le bouton fait apparaître.
Les caustiques sont partout dans la nature : les réseaux lumineux qui dansent au fond d'une piscine sont les caustiques de la
surface ondulée de l'eau, et l'arc-en-ciel en est une aussi. Dans une goutte de pluie, les rayons du Soleil réfractés,
réfléchis puis réfractés ressortent dans toutes les directions, mais ils s'accumulent autour d'un angle d'environ $42^\circ$ avec
la direction opposée au Soleil : c'est là que l'arc apparaît. Descartes l'a calculé en 1637, en suivant des milliers de rayons à
la main.
Programmer
Le premier programme reprend le calcul de la parabole de sûreté : pour une cible donnée, il dit si elle est atteignable et
donne les angles de tir. Le second calcule des points d'une courbe de Bézier par la construction de De Casteljau. On peut changer
les valeurs et exécuter.
from math import sqrt, atan, degrees
v = 20 # vitesse en m/s
g = 9.81
x, y = 30, 5 # cible : 30 m plus loin, 5 m plus haut
k = g / (2 * v**2)
delta = x**2 - 4 * k * x**2 * (y + k * x**2)
if delta < 0:
print("Cible hors d'atteinte : elle est au-dessus de la parabole de sûreté.")
else:
for u in [(x - sqrt(delta)) / (2 * k * x**2), (x + sqrt(delta)) / (2 * k * x**2)]:
print("angle de tir :", round(degrees(atan(u)), 1), "degrés")
def casteljau(P0, P1, P2, t):
A = (P0[0] + t * (P1[0] - P0[0]), P0[1] + t * (P1[1] - P0[1]))
B = (P1[0] + t * (P2[0] - P1[0]), P1[1] + t * (P2[1] - P1[1]))
M = (A[0] + t * (B[0] - A[0]), A[1] + t * (B[1] - A[1]))
return M
for i in range(11):
t = i / 10
M = casteljau((0, 0), (1, 3), (4, 0), t)
print("t =", t, " M =", (round(M[0], 3), round(M[1], 3)))
Ce que l'on peut approfondir en NSI et en SI
- Récursivité : la construction de De Casteljau se programme récursivement pour un nombre quelconque de points
de contrôle : on remplace $n$ points par $n - 1$ points intermédiaires, jusqu'à n'en garder qu'un.
- Dessin vectoriel : une image SVG décrit ses formes par des points de contrôle ; agrandie, elle reste nette,
contrairement à une image en pixels.
- Commande numérique : une machine-outil reçoit une suite d'instructions de déplacement de l'outil, en tenant
compte de son rayon ; les logiciels de fabrication assistée calculent ces trajectoires à partir du modèle de la pièce.
Des directions pour construire sa question
Ce texte n'est pas un Grand Oral. Il rassemble des connaissances dans lesquelles chacun peut choisir une direction,
la creuser et formuler sa propre question. Quelques directions possibles :
- Mathématiques : démontrer qu'une courbe est l'enveloppe d'une famille avec le second degré et la dérivée,
la parabole de sûreté, les courbes de Bézier.
- HGGSP : Gaspard Monge et le thème « faire la guerre, faire la paix » : la science au service de l'État en
guerre, le secret militaire, la fondation de l'École polytechnique, les usages civils des mêmes savoirs.
- Sciences de l'ingénieur : le taillage des engrenages par génération, la développante de cercle, le fraisage
et la correction de rayon d'outil, la CAO.
- Physique-chimie : les trajectoires de projectiles, les caustiques et l'arc-en-ciel.
- NSI : les courbes de Bézier, l'algorithme de De Casteljau, les polices de caractères et le dessin vectoriel.
Pour l'échange avec le jury : les notions du cours à maîtriser
Le jury peut interroger sur les chapitres de spécialité mobilisés. Avec ce thème, il est utile de connaître
parfaitement : les fonctions du second degré, le discriminant et la factorisation ; le nombre dérivé, la fonction dérivée et
l'équation de la tangente ; les vecteurs, la colinéarité et les équations de droites ; les fonctions sinus et cosinus ; la
géométrie dans l'espace (plans, droites, représentations paramétriques) ; les boucles et les fonctions en Python.
Pour réviser ces chapitres, l'application Maths FlashBac
reprend tout le cours de spécialité en cartes.
Pour aller plus loin