<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>libimage: les height_fields de POVray</title> <link rel="stylesheet" type="text/css" href="libimage.css"> <meta name="generator" content="Vim et huile de phalange"> <meta name="keywords" content="libimage, 3d de merde, POVRAY"> </head> <body> <a name="top"><h1>libimage / les height_fields de POVray</h1></a> <p align=center> <tt>dernière mise à jour: 16 octobre 2013</tt><br> <i> <a href="http://tboudet.free.fr/libimage/img-povhf15.html">#</a> et <a href="http://la.buvette.org/devel/libimage/img-povhf15.html">#</a> </i> </p> <p class="menuhaut"> [<a href="libimage.html">libimage</a>] [<a href="#fonctions">fonctions</a>] [<a href="#traitements">traitements</a>] [<a href="#mixages">mixages</a>]<br> [<a href="image77.html#povray">fortran</a>] [<a href="#bruit">bruitage</a>] [<a href="#synth">synthèse</a>] [<a href="#liens">liens</a>] </p> <p> Pour savoir ce qu'est un <b>height_field</b>, consultez le site de <a href="http://www.povray.org/">POVray</a>, et fouillez la doc. Vous pouvez aussi en <a href="http://krabulator.free.fr/exPOV/current/ex13.jpg">regarder un</a> pour vous faire une idée... </p> <p> En fait, un <b>height_field</b> est un "champ d'altitude", une sorte de matrice à deux dimensions dont chaque cellule représente une hauteur. Cette hauteur est un nombre codé sur 15 bits, donc entre 0 et 32767. Les gens de <a href="http://www.povray.org/">POVray</a> ont choisi, entre autres solutions, de stocker cette altitude dans des images .TGA en mettant les 7 bits de poids fort dans le canal rouge et les 8 bits de poids faible dans le canal vert. </p> <a name="fonctions"><h2>fonctions de base</h2></a> <dl class="proto"> <dt>int Image_hf15_plot(Image_Desc *im, int x, int y, int h); <dd>Place un point de hauteur <b>h</b> (entre 0 et 32768) aux coordonnées x et y. Les valeurs de <b>h</b> hors intervalle seront bornées. <dt>int Image_hf15_height(Image_Desc *img, int x, int y); <dd>Lecture de la hauteur du point aux coordonnées x et y. Cette hauteur est automatiquement limitée à l'intervalle autorisé. <dt>int Image_hf15_hf2gray(Image_Desc *src, Image_Desc *dst, int mode); <dd>Conversion d'un height_field en une image en niveaux de gris. Le paramètre <tt>mode</tt> n'est pas utilisé et doit être égal à 0. <dt>int Image_hf15_rgb2hf(Image_Desc *src, Image_Desc *dst, int mode); <dd>Conversion d'une image RGB en height_field. Le paramètre <tt>mode</tt> n'est pas utilisé. On doit le mettre à 0. Cette fonction va probablement évoluer dans un proche (ou lointain) avenir. <dt>int Image_hf15_save_PGM(char *nom, Image_Desc *img, char *comment); <dd>Sauvegarde un height_field en format <a href="img-fichiers.html#pnm">PGM</a> ascii. Le suffixe recommandé étant <tt>.pgm</tt>, mais vous faites comme vous voulez... <i>Bien que le fichier soit conforme aux spécifications du PGM, Povray n'arrive pas à le lire. Ce bug devrait être corrigé dans la version 3.x qui est actuellement disponible, mais je n'ai pas encore testé.</i> </dl> <p align=right><a href="#top">haut de page</a></p> <a name="traitements"><h2>traitements</h2></a> <dl class="proto"> <dt>int Image_hf15_lissage(Image_Desc *s, Image_Desc *d, int coef, int flag); <dd>Lissage d'un height_field. Le paramètre <tt>coef</tt> représente le poids du point central de la matrice 3x3. Les huit autres points ont un coefficient de 1, ce qui n'est peut-être pas idéal. <dt>int Image_hf15_calc_minmax(Image_Desc *img, char *txt, int *pmin, int *pmax); <dd>Calcul des extrèmes d'un height_field. Si <tt>txt!=NULL</tt>, un message est affiché. Si <tt>pmin</tt> et/ou <tt>pmax</tt> sont à <tt>NULL</tt>, le résultat correspondant n'est pas retourné. <i>ah ah, no more segfault !</i> <dt>int Image_hf15_normalize(Image_Desc *src, Image_Desc *dst, int min, int max); <dd>Ajustement linéaire d'un height-field afin que toutes les valeurs soient comprises entre <tt>min</tt> et <tt>max</tt>. <dt>int Image_hf15_mul_add(Image_Desc *src, Image_Desc *dst, int mul, int add); <dd> A tester plus en détails... <dt>int Image_hf15_dilate(Image_Desc *src, Image_Desc *dst, int coef); <dd>Dilatation d'un HF: chaque point est remplacé par le point le plus haut de son voisinage 3x3. Cela a pour effet d'amplifier les sommets. Le paramètre <tt>coef</tt> n'est pas utilisé, il est bon de mettre 1, pour rester compatible avec les évolutions en projet... <dt>int Image_hf15_erode(Image_Desc *src, Image_Desc *dst, int coef); <dd>Opération inverse de la dilation: amplification des vallées. <tt>coef</tt> n'est pas utilisé, mettre 1. <dt>int Image_hf15_mult_i(Image_Desc *s1, Image_Desc *s2, Image_Desc *dst); <dd>Multiplication de deux height-fields, avec remise à l'échelle pour ne pas faire de dépassements. Pas trop testé ;( <dt>int Image_hf15_sqrt(Image_Desc *src, Image_Desc *dst); <dd>Racine carré normalisée de l'altitude normalisée. Peu testée, mais visuellement prometteuse. <dt>int Image_hf15_pow(Image_Desc *src, Image_Desc *dst, double p0w44) <dd>En quelque sorte la fonction complémentaire de la racine carré. Et là aussi on opère sur des valeurs normalisées. </dl> <p align=right><a href="#top">haut de page</a></p> <a name="mixages"><h2>mixages</h2></a> <p> Bien entendu, quand on commence à faire des height-fields, on se demande si on peut les combiner, les mélanger entre eux, faire du hfmix... Et effectivement, c'est possible. Il y a même un <a href="http://foo.buvette.org/bf/hf/">début de démonstration</a> qui donne parfois de bonnes idées bien mouvantes. </p> <dl class="proto"> <dt>int Image_hf15_mix(Image_Desc *s1, Image_Desc *s2, Image_Desc *d, int k); <dd> Mélange de deux HF. Le coefficient <tt>k</tt> va de 0 à 10000, mais rien ne vous empèche d'essayer d'autres valeurs. En principe, les débordements sont correctement gérés. <dt>int Image_hf15_mult(Image_Desc *s1, Image_Desc *s2, Image_Desc *dst); <dd> Multiplication de deux hf15. Il risque d'y avoir des problèmes de dépassement de capacité dans cette fonction. Si cela vous arrive, il faut me faire <a href="mailto:oulala@chez.com">signe</a>. <dt>int Image_hf15_getmin(Image_Desc *s1, Image_Desc *s2, Image_Desc *d); <dd>Recopie dans l'image de destination de la valeur minimale des deux points correspondants dans les images s1 et s2. Il existe aussi la fonction <tt>Image_hf15_getmax</tt> dont la sémantique est évidente. </dl> <p align=right><a href="#top">haut de page</a></p> <a name="bruit"><h2>bruitages</h2></a> <dl class="proto"> <dt>int Image_hf15_noise_0(Image_Desc *dst, int hi, int lo, int pr100); <dd>Avec une probabilité de <tt>(pr100 % 100)</tt>, l'altitude sera mise entre <tt>hi</tt> et <tt>lo</tt> pour tout les points de l'image. <dt>int Image_hf15_noise_1(Image_Desc *dst, int mo, int of, int pr100); <dd>Cette fonction déplace une atltitude de 'mo' avec un offset de 'of'. Le paramètre 'pr100' n'est pas utilisé. <dt>int Image_hf15_noise_2(Image_Desc *dst, int pr100, int di, int k1, int k2); <dd>Remplacement aléatoire du point courant par un de ses proches voisins. Le code n'est hélas pas encore vraiment optimisé. <dt>int Image_hf15_noise_3(Image_Desc *dst, double coef, int flag); <dd>Léger bruitage proportionnel à la hauteur du point concerné. Cette fonction a été inventée pour la montagne de <a href="http://foo.buvette.org/bf/pm/sonia.avi">Sonia</a>. </dl> <a name="synth"><h2>Synthèses</h2></a> <p> Nous pouvons également songer à fabriquer des height-fields à partir de calculs divers et plus ou moins abscons. Actuellement, il y a deux fonctions à peu près opérationnelles, mais pas encore figées. </p> <dl class="proto"> <dt>int Image_hf15_synth_0(Image_Desc *dst, Image_PtList *ptl); <dd>Pas très fini, en cours de démoulage. Et vous ne savez pas ce qu'est une <i>PtList</i> ? Voici un petit <a href="img-ptlist.html">topo</a>. <dt>int Image_hf15_synth_fromfunc0(Image_Desc *dst, int k, double(*func)(int x, int y, int k)) <dd>Vous avez sous la main une fonction du genre <tt>h = func(x, y)</tt> ? Vous souhaitez la transformer en height-field ? No souçaï. Vous écrivez votre fonction, vous créez une image des dimensions voulues, et vous utilisez ce générateur magique, quoique pas encore fini. Son principal avantage est de recadrer les valeurs fournies par votre fonction dans la <i>dynamique</i> complète du hf. </dl> <p align=right><a href="#top">haut de page</a></p> <a name="liens"><h2>liens</h2></a> <ul> <li>Il existe une <a href="image77.html#povray">interface G77</a> pour ces fonctions. <li><a href="http://www.povray.org/">POVray</a>, and have a look at the new 3.5 version... <li><a href="http://pov.monde.free.fr/">Pov Monde</a> les POVeurs francophones. <li><a href="http://tontonth.free.fr/pov/">tTh</a> fait quelques raytracings. <li>Comment faire des <a href="img-stereo.html">images en relief</a>. <li>un début de <a href="http://tontonth.free.fr/pov/hf/">howto</a> pour faire des images avec les hf15s. <li>Il y a d'autres choses étranges dans POV: les <a href="img-df3.html">df3</a> (<i>aka</i> density files) en font partie. </ul> <p> Dans un autre domaine <i>povesque</i>, si vous créez deux images en déplaçant légerement le point de vue, vous pouvez les <a href="img-stereo.html">combiner</a> en une image, que vous verrez en relief avec une paire de lunettes munie des <a href="img-stereo.html#filtres">filtres</a> adéquats. </p> <p align=right><a href="#top">haut de page</a></p> <p class="footer"> Votre demande est traçante, <a href="http://foo.bar.quux.over-blog.com/">je</a> lance mon <a href="http://www.vim.org">Vim</a>,<br> et je passe à l'action altitudisante. </p> </body> </html>