CH 3
CH 3
CHAPITRE 3
EXEMPLES GRAPHIQUES
Représentation de courbes
Les exemples donnés ici ne posent pas de grand problème de programmation, il faut savoir,
pour les lire qu'on accède aux bibliothèques de fonctions graphiques avec "uses graph ;" sur
PC et "uses memtypes, quickdraw ;" sur MAC.
Les différents modes graphiques sont tellement variés qu'il vaut mieux toujours poser
d'emblée des constantes L et H signifiant largeur et hauteur d'écran. Ainsi, le programme peut
commencer par l'attribution de deux valeurs, ce qui permet d'avoir une grille, par exemple, de
L = 640 colonnes numérotées de 0 à 639 et H = 200 lignes numérotées de 0 à 199 de haut en
bas.
Les instructions utilisées ici sont "moveto (u, v)" pour se placer à un point quelconque
(colonne u, ligne v) de l'écran, et "lineto (u, v)" pour tracer un segment dans la couleur
considérée, depuis le dernier point placé jusqu'à celui (u, v) qui est donné en paramètre.
Rappelons, en outre, que "trunc" est la fonction de troncature, trunc (45.123) = 45 par
exemple, et que "div" est la division entière 45 div 6 = 7.
Afin d'éviter les confusions nous écrirons systématiquement les coordonnées d'écran u et v ou
bien c (colonne) et l (ligne), et nous réserverons x, y pour le point de vue du dessin réel sur le
papier. C'est sur ce dessin que l'on doit définir la fenêtre A < x < B et C < y < D.
Dans ce premier programme, la fenêtre est fixée par le programme proprement dit, il faut y
remarquer la séparation très nette entre les déclarations : les deux fonctions f et g, et les deux
sous-programmes de tracé d'axes et de tracé de courbes. Le programme proprement dit n'est
constitué que par la dernière ligne fournissant des arguments à la procédure de trace. Ce point
sera examiné plus en détail au chapitre 4 .
program courbes ; {Courbes paramétrées X=f(t) et Y=g(t) l'exemple donné est une épicycloïde "rallongée" ou
trochoïde }
const L = 640; H = 200; {dimensions de l'écran}
Exécution
Remarques
Les multiples versions de Pascal et les multiples cartes grahiques obligent au maximum de
souplesse, c'est à dire qu'il est préférable de conserver les vraies coordonnées x, y dans
l'utilisation de procédures que l'on appelera "place (x, y)" et "trace(jusqu'à) (x, y)" lesquelles
seront fonction d'une fenêtre [A, B]*[C, D] que l'on définira en constantes, variables globales
ou paramètres suivant la souplesse désirée.
On pourra utiliser aussi une procedure "grospoint" placant cinq ou neuf point autour de (x, y).
Dans l'ancienne version de Turbo-Pascal, on accède au mode graphique par "hires", un point
est placé par plot (U, V, couleur) et un segment de droite est décrit par draw (U1, V1, U2, V2,
couleur).
Chapitre 3 - Exemples graphiques 31
procedure axes; begin if A*B <0 then begin place (0,D); trace (0,C) end;
if C*D <0 then begin place (A,0); trace (B,0) end end ;
Essayer x = cos 3t - 2sin3t, y = ln|sin2t - cos5t| pour une belle architecture, ρ = √(2|cos2θ) - 1
pour avoir les pétales avec la fleur et 1/ρ = √(1+sin2θ) + √(1-sin2θ) vous aurez une surprise!
32 512 Problèmes corrigés - Pascal
3-2° Tracer une famille de courbes sur un même repère, exemple : f(x) = e-x|x|m pour m
allant de -2 à 4 de 1/2 en 1/2
begin famille (-2, 4, 0.5) end. {©ette ligne constituant le programme pour les 13 courbes ci-dessous}
Ou bien, si f(x) = 1/(1 + x 2m) pour 1 < m < 9, on peut voir la convergence de cette suite de
fonction vers une fonction discontinue.
3-3° Dans un cadre carré où chaque côté est régulièrement subdivisé en 10, tracer des
segments joignant des points de deux côtés adjacents correspondant aux mêmes subdivisions,
à la façon des tableaux de fils tendus par des clous.
3-4° Produire une série de carrés emboîtés, chacun ayant ses sommets en des points divisant
dans le même rapport les côtés du carré dans lequel il s'inscrit.
Chapitre 3 - Exemples graphiques 33
On a représenté les tracés superposés de f 2, f8 et f30 sur les deux dernières arches.
3-7° Tracé de la clothoïde x = a ∫ 0,t cos πu2 /2 du y = a ∫0,t sin πu2/2 du (Intégrales de
Fresnel, u est la variable d'intégration). Cette courbe a un rayon de courbure proportionnel à
la distance parcourue sur la courbe (son équation intrinsèque R = πs/a2 est directement
utilisable si l'on dispose des instructions de manipulations de "tortues" au chapitre suivant.)
On se servira de :
function integrale (a, b : real; n: integer) : real; {donne l'intégrale de F sur [a, b]}
var s, h : real; i : integer;
begin h := (b-a)/n/2; s := f(a) + f(b) + 4*f(a + h);
for i := 1 to n-1 do s := s + 2*f(a + 2*i*h) + 4*f(a + (2*i+1)*h);
integ := h*s/3 end;
3-8° Tracé des fn(x) = 1/π ∫[0,π] cos|nu - sin xu| du, pour les entiers 1 ≤ n ≤ 5 et 0 ≤ x ≤ 10
avec Simpson.
34 512 Problèmes corrigés - Pascal
3-10° Ensemble de Mandelbrot : On cherche l'ensemble des complexes c de [-2, 1]2 tel que
l'itération de la suite déterminée par z0 = 0 et zn+1 = f(zn ) = zn 2 + c ait ses 10, 30, ou 60
premiers termes (différence entre les deux figures) dans un cercle de centre O et de rayon 3
(ce qui ne veut pas dire qu'elle converge, ni que cette "convergence" ait lieu pour les autres
complexes que 0, c'est l'ensemble des c tels que Kc ensemble de Julia, soit connexe). Pour
chaque point c d'une fenêtre de l'écran. (L'axe des x est dirigé ici vers le bas, l'axe des y vers
la droite. Par ailleurs la borne 2 peut suffire.)
Program mandelbrot; uses memtypes, quickdraw; {Accès aux fonctions graphiques sur Macintosh }
const A = - 3; B = 2; C = - 1.2; D = 1.2 ; L = 480; H = 270; { On définit une fenêtre }
procedure point(x, y : real);
var u, v : integer;
{Pour x entre A et B, et y entre C et D les coordonnées à l'écran sont U=L*(X-A)/(B-A) et V=H*(Y-D)/(C-D)}
begin u := round(L*(x-A)/(B-A)); v := round(H*(y-D)/(C-D)); moveto(u, v); lineto(u, v) end;
function conv (x, y : real) : boolean; {dit si la suite zn+1 = zn2+x+iy converge, le départ étant toujours 0}
var x0, y0, x1, y1 : real; it : integer;
begin x1 := x; y1 := y; it := 1;
repeat it := it + 1; x0 := x1; y0 := y1; x1:=x+x0*x0-y0*y0; y1 := y + 2*x0*y0
until ( abs(x0)+abs(y1) > 3) or (it > 30);
conv := (it > 30) end;
3-11° Un autre programme inspiré de ce dernier produit de magnifique résultats, c'est l'étude
des points z0 de convergence de la suite zn+1 = f(zn ) = zn 2 + 0,78+ 0,2i. On calcule les
parties réelle et imaginaire x, y de zn avec n limité à 20, dès que x2 + y2 > 5, on considère
qu'il y a divergence, sinon on place le point et ses symétriques par rapport aux axes.
procedure f (x, y : real; var re, im : real); { calcule le complexe (re, im) image de (x, y) par f }
begin re := sqr(x) - sqr(y) - 0.8; im := 2*x*y - 0.2 end;
3-12° Pour construire un diaphragme, on trace un polygone régulier de n côtés mesurés par c.
Puis en avançant sur l'un des côtés de rc (avec 0 < r < 1) on trace un autre polygone régulier
de n sommets dont chacun se trouve sur un côté du polygone précédent au même rapport r.
(Elégante solution dans le langage Logo disposant d'instructions pour fixer un cap et calculer
une distance parcourue.)
36 512 Problèmes corrigés - Pascal
3-13° Enveloppes de droite, sur un cercle de rayon r, on joint les points de coordonnées
polaires (r, θ) et (r , nθ) en faisant varier θ de p en p (par exemple p = 5°). Pour n = 2 on
obtient une cardioïde, n = 3 une néphroïde etc...
procedure env (p : real ; n : real ); {lancée avec : n = 1,5 ou env (0.1 , 4.5) pour le dernier dessin.}
var a : real;
begin a := 0;
repeat place (cos (a), sin (a)) ; trace (cos (n*a), sin (n*a)) ; a := a + p
until a > 8*pi
end;
3-14° (Rien à voir avec π) Simulation d'un vol de mouettes, [Bonabeau 94] on place
aléatoirement, mais vers le coin gauche en haut de l'écran, n = 20 points. Chacun ayant une
vitesse entre 2 et 20 pixels par intervalle de temps et une direction (initialement vers le coin
en bas à droite). Chaque oiseau doit contrôler ses camarades dans un rayon de 10 pixels et
éviter les collisions en modifiant sa direction (±5° par exemple), puis (règle moins prioritaire)
atteindre leur vitesse moyenne en modifiant éventuellement la sienne de ±1, sinon il doit
modifier sa direction pour s'approcher de leur centre de gravité.
Chapitre 3 - Exemples graphiques 37
function max (a, b : integer) : integer ; begin if a < b then max := b else max := a end ;
function min (a, b : integer) : integer ; begin if a < b then min := a else min := b end ;
function interieur (l, c , a : integer ; T : tab) : boolean ; {teste si tous les éléments de T autour de (l = ligne, c =
colonne) dans un "rayon" de a, sont dans T }
var i, j : integer ; test : boolean ; {test = "tout ce qui a été vu est dans T"}
begin i := max (l - a, 1); test := true ;
while (i <= min (l + a, m)) and test do
begin j := max (c - a, 1);
while T[i, j] and (j <= min (c + a, m)) do j := j + 1;
test := (j > min (c + a, m)) ;
i := i+1 end ;
interieur := (i > min (l+a, m)) end;
function adherent (l, c , a : integer ; T : tab) : boolean ; { teste si au moins un élément autour de (l = ligne, c =
colonne) dans un "rayon" de a, est dans T }
var i, j : integer ; test : boolean ;
begin i := max (l-a, 1);
repeat j := max (c-a, 1);
repeat test := T [i, j] ; j := j + 1 until test or (j > min (c+a, m)) ; i := i + 1
until test or (i > min (l + a, m)) ;
adherent := test end;
38 512 Problèmes corrigés - Pascal
Pour ne pas avoir à rentrer une image point par point, on peut aussi en créer une
aléatoirement.
Naturellement il faut expérimenter sur une véritable image (bruitée) pour pouvoir juger. Ici
epsilon était fixé à 1, ce qui signifie qu'au cours d'une transformation, pour chaque point, 9
appartenances à l'image de points voisins ont été testés.
Chapitre 3 - Exemples graphiques 39
Exemples de trajectoires
x' = (x-cos y)(y-cos x) et y' = sin x x' = (x2+y 2-1)(x2+y 2-9) et y' = x2+y2-4
40 512 Problèmes corrigés - Pascal
procedure segment (x, y : real); { Si on donne x entre A et B, et y entre C et D alors les coordonnées sur l'écran
sont U = 510*(X-A)/(B-A) et V = 340*(Y-D)/(C-D) }
begin lineto ( 510*(x-A) div (B-A) , 340*(y-D) div (c-d)) end;
procedure euler (S : integer; var err : boolean; x0, y0 : real;var x1, y1 : real);
{calcule un point M1 voisin du point M0 donné, S=±1 est le sens}
var dx, dy, dt : real;
begin err := false; dx := f (x0, y0); dy := g (x0, y0);
if abs(dx) + abs(dy) < eps
then err := true
else begin dt := ds/sqrt(dx*dx+dy*dy); x1 := x0 + S*dt*dx; y1 := y0 + S*dt*dy end
end ;
procedure dessin ; { On distribue les points de passage de trajectoires en les disposant régulièrement sur des
cercles centrés dans l'écran, toutes sortes d'autres choix sont possibles. }
var i, j, diviseur : integer;
begin
diviseur := 10 ;
for j:= 2 to 5 do for i:= 1 to diviseur do
trajectoire((B+A)/2 + (B-A)*cos(2*pi*i/diviseur)/j, (C+D)/2 + (D-C)*sin(2*pi*i/diviseur)/j )
end;
var ds : real;
begin {le programme} ds := (B-A)/50; dessin end.
3-18° Les lignes équipotentielles pour deux champs de gravitation comme la terre et la
lune sont données par U(x, y) = K(m/√[(x - xf)2 + y2] + m'/√[(x - xf')2 + y2]) constant.
Cela donne le système différentiel x' = -Ky (m/√[(x - xf)2 + y2] + m'/√[(x - xf')2 + y2]) et y' =
K (m(x - xf)/√[(x - xf)2 + y2] + m'(x - xf')/√[(x - xf')2 + y2]). En faire des tracés.
3-19° Equations du second ordre, par la même méthode, on pourra traiter des problèmes
tels que:
Pendule de Foucault x'' = -kx + eps*sin(lat*y')
y'' = -ky - eps*sin(lat*x')
où latitude en radian = π/4, k = 1, eps = 0.05 et initialement x0 = 0,5, y0 = 0, x'0 = 0, y'0 = 1
Pendule sphérique x'' = -kx/√(1-x2-y2) + eps sin(lat*y')
y'' = -ky /√(1-x2-y2) - eps sin(lat*x')
Champ en r2 x'' = -krx - qx'
y'' = -kry - qy'
Champ newtonien x'' = -kx/r3 - qx'
y'' = -ky/r3 - qy'
42 512 Problèmes corrigés - Pascal
function f (dx, dy : real) : real; begin f := -0.01*sqrt (sqr (dx) + sqr (dy)) * dx + 0.01*N*dy end;
function g (dx, dy : real) : real; begin g := -0.01*sqrt (sqr (dx) + sqr (dy)) * dy - 0.01*N*dx - 9.81 end;
procedure euler ( pas : real; var x, y, dx, dy : real) ; {trace un segment et modifie le point et ses dérivées}
begin place (x, y); x := x + pas*dx; y := y + pas*dy;
dx := dx + pas*f(dx, dy); dy := dy + pas*g(dx, dy); trace(x,y) end;
procedure trajectoire (cote, vitesse, angle, r : real ; var n : real); {trace une courbe avec des données initiales et
toujours abscisse=0, n est la vitesse de rotation initiale, r le coefficient d'amortissement}
var x, y, dx, dy : real;
begin x := 0; y := cote; dx := vitesse*cos (angle); dy := vitesse*sin (angle);
while (0<=x) and (0<= y) and (x < B) and (y < D) do begin euler (pas, x, y, dx, dy); n := n*r end
end;
begin writeln ('Lancer d''une balle de tennis ou de golf');
write ('Donnez la cote initiale d''où est lancée la balle en mètres '); readln (y0);
write ('Donnez la vitesse initiale (m/s) '); readln (v0);
write ('Donnez l''angle initial (degrés) '); readln (a0);
write ('Quelle est l''altitude maximale ? '); readln (D); C := 0;
write ('Quelle est la distance maximale ? '); readln (B); A := 0; pas := (B-A)/1000;
write ('Rotation initiale en nb de tours/s ? '); readln (n);
write ('Coefficient d''amortissement de cette rotation (ex. 1 ou 0,9) ? '); readln (r);
clearscreen; axes; trajectoire(y0, v0, pi*a0/180, r, n) end.
Un résultat pour une balle tirée de 1m de haut à 10° de l'horizontale à 30 m/s et N=-150 sur
une distance de 200 m. (r = 1)
Chapitre 3 - Exemples graphiques 43
3-21° L'évolution de populations telles que les pucerons et les coccinelles peut être
modèlisée de la façon suivante :
Soit P l'effectif des prédateurs et V celui des victimes, partant des équations dV/dt = aV -bP
et dP/dt = cP - dP où a est le taux de croissance des proies en l'absence de prédateurs, b est le
nombre de proies capturées par prédateur et par unité de temps, c le taux de conversion de
proies en prédateurs et d le taux de mortalité des prédateurs par manque de proies.
On dispose du modèle de Lokta-Volterra pour lequel a est constant, b = b'V, c est négatif et
constant, d = b'd'V, alors pour des valeurs données de a, b', c et d' les trajectoires convergent
vers un point P = a/b' et V = -c/b'd'.
Le modèle à densité et satiété dépendant est : dV/dt = r(1-V/k)V - c(1- exp(-aV/c))VP
dP/dt = -mP + bc(1- exp(-aV/c))VP
3-25° Une suite chaotique. soit une suite pn vérifiant une relation de récurrence très simple
pn+1 = mpn.(1 - pn) Avec p0 = 0.1 ou 0.4 par exemple, représenter pn en abscisse et le nombre
de générations en ordonnées logarithmiques. On observera alors que cette suite converge pour
m < 3, puis qu'elle est alternée, puis vers m = 3.5 elle est alternée sur 4 valeurs d'adhérences,
enfin vers m = 3.6, elle se met à parcourir très rapidement 4, 8, 16 ... valeurs d'adhérences, ce
qui produit le dessin d'un bel arbre binaire.
program chaos ;
uses memtypes, quickdraw;
const A = 0.1; B = 1; C = - 0.1; D = 7 ; L = 480; H = 270;
3-26° Courbes de Bezier. Etant donnés des points de contrôles ou pôles P0, P1, .... Pn, l'idée
est de construire une courbe qui soit "attirée" par ces pôles, sans nécessairement y passer. (Le
problème de trouver la courbe passant vraiment par des points est résolu avec les polynôme
de Lagrange) L'application évidente étant la possibilité en CAO de créér des formes à partir
de points que l'utilisateur pourra déplacer à son gré dans un but technique ou artistique.
Ce problème a reçu une solution sous la forme de courbe de Bezier associée aux points P0, P1
.... Pn : c'est la courbe définie grâce au paramètre t par :
n
OM(t) = ∑ B k,n(t).OP k kk
où B k,n(t)= C nt (1-t)
n-k
sont les polynômes de Bernstein
k=0
On vérifie que la somme des poids vaut 1, que cette courbe passe en M0 et en Mn, elle est
tangente en M0 à M0 M 1 , et en Mn à Mn-1 M n , par ailleurs, si n = 2, M1 a une tangente
parallèle à M0M2.
Construction récurrente, par un jeu de factorisations, on peut montrer que :
OM(t) = B 0,n-1(t)[(1-t)OP 0 + tOP 1] + B 1,n-1(t)[(1-t)OP 1 + tOP 2] + ......
+ B n-1,n-1(t)[(1-t)OP n-1 + tOP n]
On en déduit le résultat suivant que le point Mt relatif aux n+1 points de départ, est le même
que celui relatif à la courbe de Bezier déterminée par les n points P' tels que:
OP' k(t) = (1-t)OP k + tOP k+1
En réitérant cette propriété, on arrive à déduire Mt comme relatif à deux seuls points, puis
pour finir, à un seul, en déduire un algorithme de tracé (algorithme de De Casteljau).
program bezier;
uses memtypes, quickdraw; {turbo-pascal sur macintosh}
const A = 0 ; B = 10 ; C = 0 ; D = 10 ; M = 10 ; {tout à fait conventionnel}
type matrice = array [0..M, 1..2] of real;
var nb : integer ; poles : matrice;
function col (X : real) : integer ; begin col:= 480 * (X-A) div (B-A))end;
function lgn (Y : real) : integer; begin lgn := (270 * (Y-D) div (C-D) end;
procedure points (N : integer ; P: matrice); {On place les N points de la matrice P sur l'écran}
var i : integer;
procedure grospoint (l, c : integer) ; { trace un petit carré}
begin moveto (l-1, c-1); lineto (l-1, c+1); lineto (l+1, c+1); lineto (l+1, c-1); lineto (l-1, c-1) end;
begin for i := 0 to N do grospoint (col (P [i, 1]), lgn (P [i, 2])) end;
Chapitre 3 - Exemples graphiques 45
procedure trace (N : integer ; P : matrice); {On reçoit N+1 points rangés dans la matrice P}
var M : matrice; t, h : real; i, j : integer;
begin t := 0; h := 1 / (6*N) ; moveto (col (P[0, 1]), lgn (P[0, 2]));
repeat t := t + h ;
for i := 0 to N do begin M[i, 1] := P[i, 1] ; M[i, 2] := P[i, 2] end;
{On recopie les points initiaux dans M afin de les modifier}
for i := 1 to N do for j := 0 to N-i do
begin M[j, 1]:=(1-t)*M[j, 1]+ t*M[j+1, 1]; M[j, 2]:=(1-t)*M[j, 2]+ t*M[j+1, 2] end;
lineto (col (M[0, 1]) , lgn (M[0, 2]))
until t >= 1 end;
procedure entree (var N : integer ; var P : matrice);
var i : integer;
begin clearscreen; write('Combien de points allez vous donner ? '); readln (N); N := N -1;
for i := 0 to N do begin write ('abscisse du point n° ', i ,' = '); read (P[i, 1]);
write (' ordonnée = '); readln (P[i, 2]) end;
end;
begin entree (nb, poles); clearscreen; points (nb, poles); trace (nb, poles) end.
procedure demo2; {On fixe un point de départ et un point d'arrivée. On fait varier deux points intermédiaires,
l'un monte, tandis que celui de droite descend}
var i : integer;
begin poles [0, 1] := 0; poles [0, 2] := 0; poles [3, 1] := 10; poles [3, 2] := 3;
for i := 0 to 10 do
begin poles [1, 1] := 2; poles [1, 2] := i; poles [2, 1] := 3+i/2; poles [2, 2] := 10-i;
points (3, poles); trace (3, poles) end end;
46 512 Problèmes corrigés - Pascal
3-27° Les courbes Splines. En deux mots, c'est une généralisation de ce qui précede, si P0 ....
Pn sont les n + 1 points de contrôle, la courbe "spline" est donnée par :
n
OM(t ) = ∑ OP i N i,j (t ) pour 0 ≤ t ≤n
i=0
Formule dans laquelle est choisie un degré i (généralement 2 ou 3 en CAO), et une
subdivision (vecteur des noeuds) t 0 = 0 ≤ t1 ≤ t2 ≤ ... pour le paramètre t, dans laquelle on a
des entiers consécutifs où seuls le premier 0 et le dernier peuvent être répétés m fois. Le plus
souvent on prend m = j + 1, car en ce cas la courbe passera aux points extrêmes. Chaque Ni,j
est un polynôme (de Riesenfield) de degré j calculé par :
N i,0 (t ) = si t i ≤ t ≤t i+1 alors 1 sinon 0
(t - t i)N i,j-1 (t ) (t i+j+1 - t)N i+1,j-1 (t ) 0
N i,j (t ) = + (avec = 0)
(t i+j - t i) (t i+j+1 - t i+1) 0
Les transformations sur les points de contrôle restent locales à ces points et leurs voisins, et
on peut changer l'ordre j sans changer les points de contrôles. Si pour n + 1 points, le vecteur
noeud est formé par n + 1 fois 0 puis n + 1 fois 1, alors on retrouve les courbes de Bezier où
les polynômes Ni,n sont les polynômes de Bernstein de degré n.
Programmer le calcul des polynômes puis le tracé des splines. Tester avec la spline carrée
(ordre 2) pour les points (-1, 0), (-1, 2), (2, 2), (3, 1), (1, 0), et le vecteur noeud (0 0 0 1 2 3 3
3). Vérifier que la courbe est tangente aux milieux des côtés du polygone, sauf aux deux
extrémités où elle est tangente à ces deux côtés en leur extrémité.
n m
Surface Spline : OM(u, v ) = ∑ ∑ OP i,j N i,k (u)N j,l (v) pour 0 ≤ u ≤ n et 0 ≤ v ≤ m
i = 0j = 0
3-30° Représentation de surfaces, si l'objet à représenter est dans le repère Oxyz, que le
point de vue est O' dont les coordonnées sphériques (r, θ, φ ) et que la fenêtre d'écran est
figurée par le plan perpendiculaire à OO' situé à la distance d de O', le but est de définir la
transformation M (x, y, z) --> M' (X, Y) dans l'écran.
z
O'
X
M'
O φ M
y
Y
θ
x
r permet de donner l'aspect du dessin à l'écran, si r est infini c'est une projection, sinon une
perspective.
d permet de régler la taille du dessin sans changer son aspect.
Les formules sont issues de la composition d'une translation de l'origine en O', d'une rotation
de - θ autour de O'z, d'une rotation de φ + π/2 autour de O'y et d'un passage en repère
indirect. Les coordonnées homogènes en facilitent l'écriture puisqu'elles permettent d'écrire
une translation en dimension 3 par un produit maticiel en dimension 4. Touver les formules
de transformation. On représentera en faisant une double boucle sur x et y, des surfaces telles
que z = (sin ρ ) / ρ pour un bel effet ou encore z = (sin x)(sin y) / (xy) ou le paraboloïde
hyperbolique z = x2 - y2