Povray/tutorials/Loop

De TartareFR
Aller à la navigation Aller à la recherche

Introduction

Dans ce tutorial, je veux montrer quelques applications élémentaires de la boucle « tant que » [ While loops ] dans POV-Ray. La boucle While est employée pour le placement régulier des objets. Les exemples suivants montrent une boucle simple et des boucles imbriquées.

Note.png
Fichiers inclus
Tous les fichiers de scène de POV-Ray des échantillons suivants sont téléchargeables. La plupart des fichiers de scène de POV-Ray emploient le fichier d'inclusion pour le système de coordonnées. Ce dernier a besoin d'un fichier de font.

Transformations linéaires

D'abord nous considérons une boucle simple qui place de petites sphères le long de l'axe de x, de x = -5 à x = +5
//------------------------------------
#declare Ball =
 sphere{<0,0,0>,0.5
        texture{pigment{color Red}
                finish {ambient 0.15
                        diffuse 0.85
                        phong 1}
               }
        }
#declare NrX = -5;     // start
#declare EndNrX = 5; // end
#while (NrX < EndNrX+1)
 object{Ball translate <NrX,0,0>}

 #declare NrX = NrX + 1;  //next Nr

#end // ----------- fin de boucle ----
Si nous imbriquons une boucle existante dans une autre boucle, faisant un pas de la valeur z = 0 à z = +5, nous obtenons un champ rectangulaire couvert par des objets identiques
//------------------------------------
#declare Boxy =
 box {<0,0,0>,< 1,1,1> scale 0.5
         texture{pigment{color White}
                finish {ambient 0.1
                        diffuse 0.9}}}
#declare DistanceX = 1.00;
#declare DistanceZ = 1.00;
#declare NrX = 0;      // startX
#declare EndNrX = 7;   // endX
#while (NrX < EndNrX) // <-- loop X
 #declare NrZ = 0;     // start
 #declare EndNrZ = 7;  // end
 #while (NrZ < EndNrZ) // <- loop Z
 object{Boxy
        translate<NrX*DistanceX, 0,
                  NrZ*DistanceZ>}
  #declare NrZ = NrZ + 1;  // next NrZ
 #end // ------------- fin de boucle Z
 #declare NrX = NrX + 1;// next NrX
#end // ----------- fin de boucle X --
Il est posibble d'imbriquer une boucle dans une boucle additionnelle imbriquée, faisant un pas de la valeur y = 0 à y = +5. Avec ceci, nous obtenons une boîte constituée par les objets identiquement formés
//------------------------------------
#declare DX = 1.00;
#declare DY = 1.00;
#declare DZ = 1.00;
#declare NrX = 0;      // startX
#declare EndNrX = 5;   // endX
#while (NrX < EndNrX)
 #declare NrY = 0;     // startY
 #declare EndNrY = 5;  // endY
 #while (NrY < EndNrY)
  #declare NrZ = 0;    // startZ
  #declare EndNrZ = 5; // endZ
  #while (NrZ < EndNrZ)
  object{Boxy
         translate
            <NrX*DX,NrY*DY,NrZ*DZ>
        }
  #declare NrZ = NrZ+1;// next NrZ
  #end // -------- fin de boucle Z
 #declare NrY = NrY+1;// next NrY
 #end // -------- fin de boucle Y
 #declare NrX = NrX+1;// next NrX
#end // --------- fin de boucle X ----


Avec cet échantillon, nos possibilités, considérée comme de pures transformations linéaires avec imbrication de boucles, nous semblons bien avoir parcouru tout notre monde tridimensionnel.

Transformations Circulaires

Jusqu'ici la boucle while a été seulement employée avec le mouvement de translation. Un effet intéressant résulte si nous employons le mouvement de rotation de la même manière.
//----------------------------------
#declare Ball =
sphere{<0,0,0>,0.6
       texture{pigment{color Red}
               finish {ambient 0.15
                       diffuse 0.85
                       phong 1}
               }
        }
#declare Radius = 3.00;

#declare Nr = 0;     // start
#declare EndNr = 30; // end
#while (Nr< EndNr)
 object{Ball
        translate<Radius,0,0>
         rotate<0,Nr*360/EndNr,0>}
 #declare Nr=Nr+1;//next Nr_minor
#end // -------- fin de boucle ----
Si nous laissons en plus tourner les sphères autour de la direction de z, nous obtenons une spirale circulaire :
//----------------------------------
#declare Ball =
sphere{<0,0,0>,0.25
texture{..see above..}}}
#declare R_major = 3.00;
#declare R_minor = 1.00;
#declare N_major =  10;
#declare N_minor = 430;

#declare Nr = 0;             // start
#declare EndNr=N_major*N_minor;// end
#while (Nr < EndNr)
object{Ball
       translate<R_minor,0,0>
       rotate<0,0,Nr * 360/N_minor>
       translate<R_major,0,0>
       rotate<0,Nr * 360/EndNr,0>}
 #declare Nr = Nr+1;//next Nr
#end // ------ fin de boucle -------
Si nous continuons ce petit jeu, nous obtenons une double spirale ciorculaire - le nombre de sphères devient énorme - dans le paysage suivant là sommes environ 25 000 boules sur le champ et environ 17 Mo de RAM ont été employées.
#declare Ball =
sphere{<0,0,0>,0.1
       texture{.. see above..}}}
//--------------------------------
#declare R_major = 3.50;
#declare R_minor = 1.00;
#declare R_inner = 0.30;
#declare N_maj = 14;
#declare N_min = 18;
#declare N_in  = 100;
//--------------------------------
#declare Nr = 0;    // start loop
#while (Nr < N_maj*N_min*N_in)
object{Ball
 translate<0,0,R_inner>
 rotate<0,Nr * 360/N_inner,0>
 translate<R_minor,0,0>
 rotate<0,0,Nr * 360/(N_min*N_in)>
 translate<R_major,0,0>
 rotate<0,Nr*360/(N_maj*N_min*N_in),0>
 }
 #declare Nr=Nr+1;// next Nr
#end // --------- fin de boucle --


Moebius

Si nous utilisons pour la double rotation un bâton, au lieu d'une sphère, comme élément de base, et ramenons le nombre de rotations intérieures à 0.5, nous obtenons un ruban de Möbius - ce genre de ruban a seulement un côté
//---------------------------------
#declare P_R=0.2; #declare P_H=0.75;
#declare Profile =
union{
 sphere  {<0, P_H,0>,P_R}
 cylinder{<0,-P_H,0>,<0,P_H,0>,P_R}
 sphere  {<0,-P_H,0>,P_R }
 texture{pigment{color rgb<1,.3,.7>}
         finish {ambient 0.45
                 diffuse 0.55
                 phong 1}}}
//----------------------------------
#declare Radius_major = 3.00;
#declare N_major =  0.5;
#declare N_minor = 2000;
//----------------------------------
#declare Nr =0;              //start
#declare EndNr=N_major*N_minor;//end
#while (Nr< EndNr)
object{Profile
       rotate<0,0,Nr * 360/N_minor>
       translate<Radius_major,0,0>
       rotate<0,Nr * 360/EndNr,0>}
 #declare Nr = Nr+1;// next Nr_minor
#end // ---------- fin de boucle ----
Si nous changeons le nombre

de rotations intérieures en 2.5, voici ce qui suit

//----------------------------------
#declare N_major = 2.5;
//----------------------------------
Dans le cas de rotations intérieures en nombre pair de demi-tours, nous avons des bandes avec 2 surfaces. C'est uniquement dans le cas de 0.5, 1.5, 2.5 rotations intérieures etc... que nous avons seulement 1 côté.
//---------------------------------
#declare P_R = 0.2;
#declare P_H = 0.65;
#declare Profile =
union{
 sphere  {<0, P_H,0>,P_R  }
 cylinder{<0,-P_H,0>,<0,P_H,0>,P_R}
 cylinder{<0,-P_H,0>,<0,P_H,0>,P_R
          translate<0.01,0,0>
 texture{pigment{color rgb<1,.65,0>}
         finish {ambient 0.1
                 diffuse 0.9
                 phong 1}}}
 sphere  {<0,-P_H,0>,P_R }
 texture{pigment{color
                 rgb<1,0.3,0.7>}
         finish {ambient 0.45
                 diffuse 0.55
                 phong 1}}}
//---------------------------------
#declare N_major = 4;
//---------------------------------
Moebius à deux faces
Fichier POVRay correspondant