Obsolete (plus d'applets Java)

Autres courbes

Courbe y=f(x)

On doit se fixer bien entendu un repère xOy. Il n'est pas obligatoire qu'il soit orthonormé.
Traçons une sinusoïde y = A.sin(ωx), normalisée à y = sin(2π x) par un choix judicieux des vecteurs "unitaires" OU et OV.
Ici le domaine de définition est ]-∞, +∞[ c'est à dire la droite Ox toute entière.
On va se limiter par exemple à un segment [-1, +2]

Désolé, votre navigateur n'est pas compatible Java.

{ domaine de variation }
{min} Dilation (U,O,-1)[hidden];
{max} Dilation (U,O,2)[hidden];
{range} Segment (max,min)[hidden];

{ point courant }
{X} Point on object (range, 0)[hidden];
{x} Ratio/Points (O,U,X,0,0,' ')[hidden];
{y} Calculate (0,0,' ','1@atan8*A*@sin_')(x)[hidden];

{ report Y }
{Y} Dilation/MarkedRatio (V,O,y)[hidden];
{M} VectorTranslation (Y,O,X)[hidden];
{loc} Locus (M,X,range, 200)[red];
De façon général, le domaine de variation de x est lié au domaine de définition de f.
Si c'est par morceaux, ce n'est pas dramatique, les points en dehors rendent "undefined" par le Calculate !

Désolé, votre navigateur n'est pas compatible Java. Traçons ainsi la courbe y² = x(x-1)(x-2)
Le domaine de définition est [0, 1] ∪ [2, +∞[ que l'on simplifie en [0, 3], le Calculate rendra simplement "undefined" dans ]1, 2[
Comme on obtient la seule valeur y ≥ 0, une symétrie y → -y donne la deuxième moitié de la courbe.

{ point courant }
{X} Point on object (range, 0.2)[label('X')];
{x} Ratio/Points (O,U,X,50,15,'x = ');
{y} Calculate (50,30,'y = ','A3-A*2+A*@sqrt')(x);

{ report Y }
{Y} Dilation/MarkedRatio (V,O,y)[yellow,label('Y')];
{M} VectorTranslation (Y,O,X)[label('M'),yellow];
{loc} Locus (M,X,range, 100)[red,layer(2)];
{M!} Reflection (M,Ou)[label('M'''),yellow];
{loc2} Locus (M!,X,range, 100)[red,layer(2)];

Un petit problème d'intervalles apparaît ici : il faut un point du Locus exactement en 0, 1 et 2. Sinon un "trou" apparaît sur la courbe
On est ainsi amené à ajuster au mieux le nombre de points du Locus.
Ce phénomène est mis en évidence dans l'applet en traçant un Locus avec 200 points au lieu de 100
Il faut ici 3n+1 points, soit 3n intervalles, mais la division par 3 ne tombe pas juste ! Il est ainsi impossible d'avoir les points exactement en x = 1 et 2.
Selon la distance des points voisins de 1 et 2, le trou est plus ou moins visible.
Bien entendu 200 n'est pas du tout 3n+1, le trou est invisible avec 202 ou 199 points !

Nota : le calcul de y² est fait par la formule y² = ((x - 3)×x + 2)×x (calcul de polynôme par la méthode de Horner)

Courbe paramètrée

C'est à dire sous la forme x = f(t), y = g(t)
On peut avoir intérêt à se fixer t dans [0, 1], c'est à dire sur un segment.
Au besoin, on effectue un changement de variable sur t.

Désolé, votre navigateur n'est pas compatible Java. Donnons l'exemple d'une courbe fermée : une épicycloïde, d'équation
x = (R/3) (4 cos(2πt) - cos(8πt))     t∈[0, 1]
y = (R/3) (4 sin(2πt) - sin(8πt))

{OU} Segment (U,O)[hidden];
{t!} Point on object (OU, 0)[hidden];
{t1} Ratio/Points (O,U,t!,0,0,' ')[hidden];
{ entre 0 et 2pi }
{t} Calculate (0,0,' ','1@atan8*A*')(t1)[hidden];

{ Calcul coordonnées }
{x} Calculate (85,15,'x = ','A@cos_4*A4*@cos_-3/')(t)[hidden];
{y} Calculate (165,15,'y = ','A@sin_4*A4*@sin_-3/')(t)[hidden];

{X} Dilation/MarkedRatio (U,O,x)[hidden];
{Y} Dilation/MarkedRatio (V,O,y)[hidden];
{P} VectorTranslation (X,O,Y)[hidden];
{loc} Locus (P,t!,OU, 200);

Si comme ici, le repère utilisé est orthonormé, on peut utiliser les systèmes de coordonnées de JavaSketchpad :

...
{xOy} Origin&Unit (O,U)[hidden];
{P} PlotXY (y, xOy, x)[hidden];
{loc} Locus (P,t!,OU, 200);

Une courbe infinie sera toujours limitée, et si on veut éviter des points aberrants, il faut s'arrêter avant les points donnant des valeurs infinies pour x ou y, si possible...

Courbe en polaire ρ = f(θ)

Par exemple une strophoïde d'équation polaire ρ = a/tan(θ/2) + b

Désolé, votre navigateur n'est pas compatible Java.

{ segment unité ]0, 1[ }
{O!} Dilation (U,O,0.001)[hidden];
{U!} Dilation (O,U,0.001)[hidden];
{OU} Segment (U!,O!)[hidden];
{t!} Point on object (OU, 0.6)[hidden];
{t1} Ratio/Points (O,U,t!,0,0,' ')[hidden];

{ dans ]0, 2pi[ }
{t} Calculate (0,0,' ','1@atan8*A*')(t1)[hidden];

{ paramètres }
{a} Parameter (0.2,0,0,' ')[hidden];
{b} Parameter (1,0,0,' ')[hidden];

{ Calcul coordonnées polaires }
{r} Calculate (0,0,' ','BA2/@tan_/C+')(t,a,b)[hidden];
{X} Dilation/MarkedRatio (U,O,r)[hidden];
{P} Rotation/MeasuredAngle (X,O,t)[hidden];
{loc} Locus (P,t!,OU, 200);

Courbe f(x,y) = 0

On ne peut tracer une telle courbe que si on peut résoudre f en x ou y : y = F(x).
C'est à dire pratiquement si c'est une équation au pire du second degré en yn (resp. xn), ou si on peut trouver une paramétrisation de la courbe, avec des fonctions usuelles (rationnelles, trigonométriques, exponentielles et logarithmes) :
Une résolution numérique de y = F(x), par exemple avec Newton, est impossible par un simple Calculate !
Les équations générales de degré 3 ou 4 sont bien résolubles par radicaux, mais les formules sont pratiquement inutilisables, et nécessitent de nombreux tests de cas particuliers (l'utilisation de nombres complexes étant exclue).
Bien entendu des équations de degré plus élevé, ou même non algèbriques, peuvent être résolues dans des cas particuliers exceptionnels.
Sinon, aucun espoir... il faut remplacer la courbe par une approximation, ou en obtenir une construction purement géométrique.

Désolé, votre navigateur n'est pas compatible Java. A titre d'exemple arbitraire, la courbe y4 - x2y2 + x4 - 1 = 0
Cette courbe est de degré 2 en Y = y² : Y2 - x2Y + x4 - 1 = 0
Le discriminant est Δ = x4 - 4(x4 - 1) = 4 - 3x4 et donc la courbe est nécessairement avec |x| ≤ 44/3.
On va la tracer sous forme de quatre Locus : y = ±√(x² ± √Δ)/2 , avec les ± indépendants.
En fait il faut de plus que l'expression sous le radical soit ≥0, on ne va pas trop se poser de question et laisser faire le Calculate (qui retournera "undefined" si <0)

{ mesure bidon pour le Calculate (4/3)^0.25 }
{un} Distance (O,U,0,0,' ')[hidden];
{max} Calculate (0,0,' ','4 3/0.25^')(un);
{Xmax} Dilation/MarkedRatio (U,O,max)[hidden];
{Xmin} Dilation (Xmax,O, -1)[hidden];
{XX} Segment (Xmax,Xmin)[hidden];

{ point courant }
{X} Point on object (XX, 0)[hidden];
{x} Ratio/Points (O,U,X,0,0,' ')[hidden];
{y1} Calculate (0,0,' ','AA* 4AAAA***3*-@sqrt + 2/ @sqrt')(x)[hidden];
{Y1} Dilation/MarkedRatio (V,O,y1)[hidden];
{P1} VectorTranslation (Y1,O,X)[hidden];
{loc1} Locus (P1,X,XX, 200);

{ autre branche }
{y2} Calculate (225,30,'y2 = ','AA* 4AAAA***3*-@sqrt - 2/ @sqrt')(x)[hidden];
{Y2} Dilation/MarkedRatio (V,O,y2)[hidden];
{P2} VectorTranslation (Y2,O,X)[hidden];
{loc2} Locus (P2,X,XX, 200);

{ symétrie y / -y }
{P3} Reflection (P1,OU)[hidden];
{loc3} Locus (P3,X,XX, 200);
{P4} Reflection (P2,OU)[hidden];
{loc4} Locus (P4,X,XX, 200);

Cette méthode "sauvage" fait apparaître un problème général : la courbe est largement trouée au voisinage des points à tangente verticale.
Une solution est d'augmenter très fortement le nombre de points du Locus : il faut ainsi plus de 2000 points pour combler le trou au voisinage de (1,0) !
Un peu d'astuce ici montre que la courbe est symétrique en x,y et qu'il suffit donc de tracer la branche supérieure avec -1≤x≤1 pour la tracer toute entière par symétrie, sans aucun trou, avec moins d'une centaine de points par Locus.
(la tracer pour 0≤x≤1 suffirait, mais il faudrait répéter 8 morceaux au lieu de 4)

{U!} Dilation (U,O, -1)[hidden];
{UU!} Segment (U,U!)[hidden];
{X!} Point on object (UU!, 0)[hidden];
{x!} Ratio/Points (O,U,X!,5,30,'x = ')[hidden];
{y!} Calculate (105,30,'y = ','AA* 4AAAA***3*-@sqrt + 2/ @sqrt')(x!)[hidden];
{Y1!} Dilation/MarkedRatio (V,O,y!)[hidden];
{P1!} VectorTranslation (Y1!,O,X!)[hidden];
{loc1!} Locus (P1!,X!,UU!, 50);
{ reflexion d'axe horizontal }
{P2!} Reflection (P1!,OU)[hidden];
{loc2!} Locus (P2!,X!,UU!, 50);

{ echange x,y }
{X3!} Dilation/MarkedRatio (U,O,y!)[hidden];
{Y3!} Dilation/MarkedRatio (V,O,x!)[hidden];
{P3!} VectorTranslation (Y3!,O,X3!)[hidden];
{loc3!} Locus (P3!,X!,UU!, 50);
{ reflexion d'axe vertical }
{P4!} Reflection (P3!,OV)[hidden];
{loc4!} Locus (P4!,X!,UU!, 50);

Intérieur

L'intérieur d'une courbe peut être rempli avec les mêmes techniques que pour un secteur de cercle : soit par un polygone approchant la courbe, soit par un Locus d'un segment intérieur à la courbe.
L'inconvénient est le nombre élevé de segments pour "remplir" la courbe, et impossible d'éviter le moirage si les segments sont inclinés.
Un polygone approché nécessite de dupliquer de nombreuses fois la construction d'un point...

Désolé, votre navigateur n'est pas compatible Java. A titre d'exemple, nous allons peindre l'intérieur d'une ellipse.
Reprenons le tracé de l'ellipse par affinité d'un cercle. Si on peint à l'aide du segment P'H', les segments successifs ne sont pas régulièrement répartis si le point de contrôle décrit le cercle principal.
Le remplissage est plus propre si le point de contrôle décrit le grand axe (ou le petit d'ailleurs). Le contour de l'ellipse doit ici être tracé en deux parties, par symétrie autour de l'axe.

{ tracé ellipse }
{AA} Segment (A,A!)[hidden];
{H!} Point on object (AA,0)[hidden];
{hp!} Perpendicular (AA,H!)[hidden];
{M!} Intersect1 (hp!,C)[hidden];
{P!} Dilation/3PtRatio (M!,H!,H,M,P)[hidden];
{P2!} Reflection (P!,AA)[hidden];

{ Ellipse }
{ell} Locus (P!,H!,AA,200)[layer(2)];
{ell2} Locus (P2!,H!,AA,200)[layer(2)];

{remplissage }
{PP!} Segment (P!,P2!)[hidden];
{area} Locus (PP!,H!,AA,200)[layer(1)];

Pour ne pas cacher le contour, mettre le Locus de remplissage en dessous (layer).
Le nombre de points du Locus de remplissage doit être > nombre de pixels le long de AA' (sinon trous, voire hachures).
En tout cas, si l'axe n'est pas horizontal, apparait un effet de moire.
Il vaut mieux remplir dans tous les cas par des segments verticaux ou horizontaux.
Ici cela nécessite de construire un balayage par une droite différente de l'axe de l'ellipse.
Une verticale est transformée en OY par l'affinité inverse P→M, on balaye alors par une droite parallèle à cette direction,
coupant le cercle en M1 et M2 qui sont transformés par l'affinité M→P pour obtenir un segment vertical P1P2 balayant l'ellipse.
Le point de controle H* balaye le segment définit par les tangentes au cercle parallèles à OY.

{x} Translation (O, 100, 0)[hidden];
{y} Translation (O, 0, 50)[hidden];
{ox} Line (x,O)[hidden];

{ transformée d'une verticale }
{ky} Perpendicular (aa,y)[hidden];
{K} Intersect (ky,aa)[hidden];
{Y} Dilation/3PtRatio (y,K,H,P,M)[hidden];
{yy} Line (Y,O)[hidden];

{ tangentes au cercle }
{xx} Perpendicular (yy,O)[hidden];
{T1} Intersect1 (xx,C)[hidden];
{ty1} Perpendicular (xx,T1)[hidden];

{ domaine }
{min} Intersect (ty1,ox)[hidden];
{max} Dilation (min,O, -1)[hidden];
{XX} Segment (max,min)[hidden];

{ point courant }
{H*} Point on object (XX, 0.15)[hidden];
{Hy} Perpendicular (xx,H*)[hidden];
{Y1} Intersect1 (Hy,C)[hidden];
{hy1} Perpendicular (aa,Y1)[hidden];
{H1} Intersect (hy1,aa)[yellow,hidden];
{P1} Dilation/3PtRatio (Y1,H1,H,M,P)[hidden];
{Y2} Intersect2 (Hy,C)[hidden];
{hy2} Perpendicular (aa,Y2)[hidden];
{H2} Intersect (hy2,aa)[hidden];
{P2} Dilation/3PtRatio (Y2,H2,H,M,P)[hidden];
{PP} Segment (P1,P2)[hidden];
{area} Locus (PP,H*,XX, 250)[layer(1)];
{ell1} Locus (P1,H*,XX, 250)[layer(2)];
{ell2} Locus (P2,H*,XX, 250)[layer(2)];

Evidemment, un polygone approché évite ces inconvénients, mais il faut transformer explicitement une bonne vingtaine de points du cercle.

 

Accueil Arithmétiques Géométrique Divers Thèmes Scripts Jeux Exercices Sujet précédent Sujet suivant   Parent