VIII. Des objets plus complexes▲
VIII-A. function▲
L'objet function ne peut pas être dessiné, c'est une fonction. Par contre il peut etre utilisé dans d'autres objets comme les height_field et les isosurfaces. Il y a plusieurs syntaxes pour décrire une fonction, voici la plus simple, pour une fonction de 3 variables :
#declare func = function {x+y+z/2}
Les 3 variables sont notees x,y,z. Et pour obtenir la valeur de la fonction en un point donné, il faut appeler
#declare resultat = func(1,2,3);
VIII-B. superellipsoid▲
Le superellipsoid est une cube érodé. Il est défini par un indice compris en 0 et 1.
0
donne un cube parfait et 1 donne une sphère. Le superellipsoid est compris dans l'objet box{<-1,-1,-1>,
<1,1,1>}. Exemple :
superellpsoid
{
// indice du superellipsoid
.2
// pigment du superellipsoid
pigment{Red}
// translation suivant le vecteur 2*(1,-2,5)
translate 2*<1,-2,5>
}
VIII-C. height_field▲
Le height_field est un objet très particulier, il correspond à la representation 3D d'une image dans laquelle les pixels clairs symbolisent des points élevés et les pixels foncés symbolisent des points bas. Un height_field est un ensemble de triangles et la finesse du tracé depend de la résolution de l'image. Le height_field supporte, entre autres, les formats d'image bmp, jpeg, gif, png et tiff. Pour rendre le height_field plus lisse il est possible de le faire utiliser des smooth_triangles au lieu des triangles, en rajoutant l'option smooth dans sa déclaration.
Attention, un height_field avec l'option smooth n'est pas lisse, il en a juste l'apparence.
Exemple de height_field:
height_field{
// type de l'image en entree
png
// nom de l'image en entree
"machin.png"
// option facultative permettant de lisser le height_field
smooth
// couleur du height_field
pigment{Green}
// agrandissement du height_field
scale <10,1,10>
}
Le height_field est contenu dans l'objet box{<0,0,0>,<1,1,1>}. Il faut donc utiliser
les transformations géometriques pour le mettre à la bonne taille et à la bonne place dans votre scène.
sans l'option smooth | avec l'option smooth |
---|---|
Et voici l'image png qui a donné ces deux height_fields :
Un height_field peut aussi se baser sur une fonction. La syntaxe est differente :
height_field{
function
nombre de triangles suivant x, nombre de triangles suivant z
{func(x,0,z)}
}
VIII-D. mesh▲
Un mesh est un ensemble de triangles ou de smooth_triangles. Syntaxe :
mesh
{
// liste de triangles (ou de smooth_triangles)
triangle{ coordonnées des 3 points du triangle }
triangle{ coordonnées des 3 points du triangle }
....
pigment{...}
}
Les meshs sont généralement générés par d'autres logiciels de modeling ou bien par des par des boucles générant des triangles. Des logiciels comme Wings3D ou Rhinoceros3D permettent directement d'exporter au format POV-Ray, ils fournissent alors un fichier .inc qu'il vous suffit d'inclure dans votre script. Vous avez dès lors une variable qui représente votre mesh. Le mesh se dessinera avec la commande
object
{
variable representant l'objet
// modificateurs d'aspect
texture{...}
// transformations geonetriques
scale ...
translate ...
...
}
Vous pouvez aussi importer des fichiers 3D dans d'autres formats (par exemple 3ds, obj) en utilisant un
convertisseur de format du genre de PoseRay qui va créer le fichier POV-Ray correspondant.
Exemple de génération de mesh par une boucle (image ci-dessus):
#declare func = function {sin((x+2.5)/2.5)+sin(z/3)+.1*cos(x*x+6*z)}
mesh
{
/*
deux boucles imbriquées pour créer une nappe d'une fonction
il suffit de diminuer les pas pour augmenter la finesse du mesh mais aussi le temps de calcul
*/
#declare i=-2.5;
#declare pasi = .25;
#declare pasj = 1;
#declare taillei = 5;
#declare taillej = 25;
#while(i<2.5)
#declare j=0;
#while (j<25)
triangle{ <i,func(i,0,j),j> ,<i+pasi,func(i+pasi,0,j),j> ,<i,func(i,0,j+pasj),j+pasj> }
triangle{ <i+pasi,func(i+pasi,0,j+pasj),j+pasj> ,<i+pasi,func(i+pasi,0,j),j> ,<i,func(i,0,j+pasj),j+pasj> }
#declare j=j+pasj;
#end
#declare i=i+pasi;
#end
// rotation / agrandissement / rotation
rotate x*90
scale <2,1,3>
rotate y*-50
pigment{Red}
}
VIII-E. Des objets à base de splines▲
Pour definir une spline, il faut specifier le type de la spline (linéaire, quadratique, cubique, naturelle) ainsi que les points par lesquels elle doit passer. Il faut aussi associer à chacun des points un indice permettant par la suite d'obtenir n'importe quel point de la spline. Exemple :
#declare ma_spline = spline{
quadratic_spline
0 <0,0,0>
.1 <0,2,1>
.6 <2,2,1>
1 <3,1,2>
}
// [...]
// ma_spline(.5) renverra <1.33,3.33,1.66>
VIII-E-1. lathe▲
Cet objet correspond à la surface décrite lorsqu'une spline tourne autour de l'axe y. La spline n'a besoin que d'être definie en 2 dimensions. Exemple :
lathe{
linear_spline
// nombre de points de la spline
4,
// coordonnées (x,z) des points de la spline
<2,0>,<1,.5>,<2,1>,<2.5,2>
pigment{Red}
}
VIII-E-2. sphere_sweep▲
Cet objet correspond à l'extrusion d'une sphère à rayon variable le long d'une spline. Il faut definir le type de spline, le nombre de points décrivant la spline, puis les points avec pour chacun d'eux le rayon de la sphère en ce point. Exemple :
sphere_sweep{
cubic_spline
8 // nombre de points de la spline
<0,0,0> ,.3,
<2,2,0> ,.4,
<3,3,0> ,.4,
<2,5,0> ,.5,
<4,5,0> ,.3,
<5,3,0> ,.2,
<4,2,0> ,.3,
<3,1,0> ,.1
pigment{Red}
}
VIII-F. isosurface▲
Une isosurface est une surface solution d'une équation. La syntaxe est la suivante :
isosurface {
function { bla bla bla }
contained_by { un objet }
}
Cet objet correspond à l'ensemble des points (x,y,z) pour lesquels la fonction passée en argument est nulle. Pour ne pas obtenir un objet infini, celui-ci est restreint aux points contenus dans l'objet passé à l'attribut contained_by (une sphere ou une box). Exemple d'utilisation :
#declare func = function {x*x+y}
isosurface {
function { func(x,y,z) }
contained_by{box{<-1,-2,-1>,<1,1,1>}}
pigment {Red}
scale <2,1,1>
}