Formes suivant des courbes.
Il s'agit ici de faire suivre une courbe à une forme donnée. La forme est un polygone. Tous les points de ce polygonne sont conservés dans un tableau. Pour un triangle par exemple on pourra écrire :
#declare NumberOfVertices = 3;
#declare ShapePoints = array[NumberOfVertices];
#declare i = 0;
#while ( i < NumberOfVertices)
#declare ShapePoints[i] = RotateX(<0, ShapeRadius, 0>, Angle*i);
#declare i = i + 1;
#end
Les points sont dans la tableau
ShapePoints. Notez que la forme est définie dans le plan
y-z. Les points peuvent aussi être définis manuellement :
#declare ShapePoints[0] = <0, y1, z1>;
#declare ShapePoints[1] = <0, y2, z2>;
#declare ShapePoints[2] = <0, y3, z3>;
#declare ShapePoints[3] = <0, y4, z4>;
#declare ShapePoints[4] = ...;
Ensuite il faut calculer les positions des points sur la courbe. Il suffit de définir la ou les fonctions et passer à cette ou ces fonctions la variation de le variable \(t\) ou \(\theta\). Exemple :
#declare Fx = function(a, _t) { a*((sin(_t))/(1+ P2(cos(_t)))) }
#declare Fy = function(a, _t) { a*((sin(_t)*cos(_t))/(1+P2(cos(_t)))) }
La variable
t est une variable pre-definie dans POVRay que nous ne pouvons pas utiliser librement. Elle est donc remplacée dans la fonction par
_t.Pour parcourir la courbe, une simple boucle suffit :
#declare thetaMin = 0;
#declare thetaMax = 2*pi;
#while ( theta <= thetaMax )
#declare Shape1 = ShapePoints;
#declare p = <Fx(SizeOfLem, theta), 0, Fz(SizeOfLem, theta)>;
#declare theta = theta + steep;
#end
Ayant les points sur la courbe, on doit ajouter dans cette boucle :
- L'initialisation de la première forme.
- Le déplacement de la forme au point de la courbe. Ayant la position, on calcule la distance depuis l'origine. Cette distance servira à deplacer la forme.
- L'orientation de la forme. Là on doit calculer la tangente en ce même point. C'est le coefficient directeur de cette tangente qui permettra d'orienter la forme. Pour les courbes paramétrées et en coordonnées polaire le calcul est spécifique mais demande toujours de connaitre les dérivées. Notre source devrat donc aussi comporter la ou les dérivées sous forme de function. On doit donc dériver à la main. Vu les fonctions utilisées, les calculs restent simples. On peut aussi implémenter des méthodes de dérivation numériques. Mais ce n'est pas le sujet ici.
Avec ces informations, notre code s'écrit maintenant :
// les 'function' pour les dérivées
#declare dFx = function(a, _t) { a*cos(_t)*(3-P2(cos(_t))) / P2(1+P2(cos(_t))) }
#declare dFy = function(a, _t) { a*(3*P2(cos(_t))-1) / P2(1 + P2(cos(_t)) ) }
// la premiere forme Shape0
#declare Shape0 = ShapePoints;
#while ( theta <= thetaMax )
// on part toujour de la forme d'origine
#declare Shape1 = ShapePoints;
#declare p = <Fx(SizeOfLem, theta), 0, Fz(SizeOfLem, theta)>;
// distance du point de la courbe à l'origine
#declare d = vlength(p);
#declare dx = dFx(SizeOfLem, theta);
#declare dz = dFz(SizeOfLem, theta);
#declare Angle = atan2d(dz,dx);
// orientation de la forme autor de l'axe y
RotateYShape(Shape1, 180-Angle)
// déplacement de la forme sur la courbe
TranslateShape(Shape1, p)
#declare theta = theta + steep;
#end
On a alors toutes nos formes positionnées et correctement orientées sur la courbe. Il reste plus qu'à relier ces formes entre elles. Ce qui donne :
#declare theta = thetaMin;
#declare Shape0 = ShapePoints;
#while ( theta <= thetaMax )
#declare Shape1 = ShapePoints;
#declare p = <Fx(SizeOfLem, theta), 0, Fz(SizeOfLem, theta)>;
#declare d = vlength(p);
#declare dx = dFx(SizeOfLem, theta);
#declare dz = dFz(SizeOfLem, theta);
#declare Angle = atan2d(dz,dx);
// rotate around y-axis
RotateYShape(Shape1, 180-Angle)
// déplacement de la forme sur la courbe
TranslateShape(Shape1, p)
// raccordement de deux formes consécutives
ConnectShapes(Shape0,Shape1)
// la forme actuelle devient la forme précédente.
#declare Shape0 = Shape1;
#declare theta = theta + steep;
#end
Remarques :
- la macro RotateYShape(Array,Angle) applique une rotation d'un angle Angle à tous les points du tableau Array.
- la macro TranslateShape(Array,a) déplace d'une valeur a tous les points du tableau Array.
- la macro ConnectShapes(ShapeA, ShapeB) raccorde les deux formes contenues dans ShapeA et ShapeB en construisant les triangles{} reliant les somments et les arrètes de chacune d'entre elles. La forme finale est donc un mesh{} qui est rès rapide en terme rendu et facilement enregistrable dans un fichier si l'on ne veut pas refaire les calculs à chaque fois.
- Toutes ces macros, ne présentant aucune difficulté, ne seront pas plus développées ici. Si vous voulez approfondir ces points, vous pouvez me contacter.
Voila pour l'essentiel de la méthode employée ici. Quelques exemple ci-dessous.
Encore une chose : beaucoup d'informations sur les courbes et les équations ont été trouvées sur l'excellent site de Robert Ferréol
mathcurve.com/.
Le
Lemniscate de Bernouilli. Son équation paramétrique est :
$$x(t) = a{sin(t)\over 1+cos^2(t) } $$
$$y(t) = a{sin(t)cos(t)\over 1+cos^2(t) } $$

La forme qui suit la courbe est un losange ayant les sommets coupés.
Hypotrochoïde. Son équation paramétrique est :
$$x(t) = (R-r)\,cos(t) + d\,cos({R-r\over r}t)$$
$$y(t) = (R-r)\,sin(t) - d\,cos({R-r\over r}t)$$
$$R = 17,\quad r = 7,\quad d = 4$$

La forme qui suit la courbe est un triangle.
Limaçon de Pascal. Son équation paramétrique est :
$$x(t) = 4acos(t) - kcos(2t)$$
$$y(t) = 4a sin(t) - k sin(2t)$$

La forme qui suit la courbe est un carré aux angles biseautés.
Le trèfle à quatres feuilles et ses variations..
Cette fois, la courbe est définie en coordonnées polaire. C'est un losange qui la suit.

$$\rho(\theta) = a\left(sin(2\theta)+\frac{sin(6\theta)}{4}\right)$$

$$\rho(\theta) = a\left(\vert{sin(2\theta)}\vert+\frac{sin^2(4\theta)}{4}\right)$$

$$\rho(\theta) = a\left(\sqrt{\vert{sin(2\theta)}\vert}+\frac{sin^2(4\theta)}{4}\right)$$

$$\rho(\theta) = a\left(sin^2(2\theta)+\frac{sin^2(4\theta)}{2}\right)$$
Et pour finir, deux exemples ou j'ai ajouté de la torsion.

Un simple cercle :\begin{align}&x(t)\,=\,r\,cos(t),\,y(t)\,=\,r\,sin(t)\\&Polygonne\;étoilé\;12\;sommets.\;Coeficent\;de\;torsion\;1.\end{align}

Un trifolium :\begin{align}&x(t)\,=\,a\,cos(t)\,cos(3t),\;y(t)\,=\,a\,sin(t)\,cos(3t),\\ &Polygonne\;étoilé\;13\;sommets.\;Coeficent\;de\;torsion\;8.\end{align}