libimage / les height_fields de POVray

dernière mise à jour: 16 octobre 2013
# et #

Pour savoir ce qu'est un height_field, consultez le site de POVray, et fouillez la doc. Vous pouvez aussi en regarder un pour vous faire une idée...

En fait, un height_field 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 POVray 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.

fonctions de base

int Image_hf15_plot(Image_Desc *im, int x, int y, int h);
Place un point de hauteur h (entre 0 et 32768) aux coordonnées x et y. Les valeurs de h hors intervalle seront bornées.
int Image_hf15_height(Image_Desc *img, int x, int y);
Lecture de la hauteur du point aux coordonnées x et y. Cette hauteur est automatiquement limitée à l'intervalle autorisé.
int Image_hf15_hf2gray(Image_Desc *src, Image_Desc *dst, int mode);
Conversion d'un height_field en une image en niveaux de gris. Le paramètre mode n'est pas utilisé et doit être égal à 0.
int Image_hf15_rgb2hf(Image_Desc *src, Image_Desc *dst, int mode);
Conversion d'une image RGB en height_field. Le paramètre mode n'est pas utilisé. On doit le mettre à 0. Cette fonction va probablement évoluer dans un proche (ou lointain) avenir.
int Image_hf15_save_PGM(char *nom, Image_Desc *img, char *comment);
Sauvegarde un height_field en format PGM ascii. Le suffixe recommandé étant .pgm, mais vous faites comme vous voulez... 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é.

haut de page

traitements

int Image_hf15_lissage(Image_Desc *s, Image_Desc *d, int coef, int flag);
Lissage d'un height_field. Le paramètre coef 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.
int Image_hf15_calc_minmax(Image_Desc *img, char *txt, int *pmin, int *pmax);
Calcul des extrèmes d'un height_field. Si txt!=NULL, un message est affiché. Si pmin et/ou pmax sont à NULL, le résultat correspondant n'est pas retourné. ah ah, no more segfault !
int Image_hf15_normalize(Image_Desc *src, Image_Desc *dst, int min, int max);
Ajustement linéaire d'un height-field afin que toutes les valeurs soient comprises entre min et max.
int Image_hf15_mul_add(Image_Desc *src, Image_Desc *dst, int mul, int add);
A tester plus en détails...
int Image_hf15_dilate(Image_Desc *src, Image_Desc *dst, int coef);
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 coef n'est pas utilisé, il est bon de mettre 1, pour rester compatible avec les évolutions en projet...
int Image_hf15_erode(Image_Desc *src, Image_Desc *dst, int coef);
Opération inverse de la dilation: amplification des vallées. coef n'est pas utilisé, mettre 1.
int Image_hf15_mult_i(Image_Desc *s1, Image_Desc *s2, Image_Desc *dst);
Multiplication de deux height-fields, avec remise à l'échelle pour ne pas faire de dépassements. Pas trop testé ;(
int Image_hf15_sqrt(Image_Desc *src, Image_Desc *dst);
Racine carré normalisée de l'altitude normalisée. Peu testée, mais visuellement prometteuse.
int Image_hf15_pow(Image_Desc *src, Image_Desc *dst, double p0w44)
En quelque sorte la fonction complémentaire de la racine carré. Et là aussi on opère sur des valeurs normalisées.

haut de page

mixages

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 début de démonstration qui donne parfois de bonnes idées bien mouvantes.

int Image_hf15_mix(Image_Desc *s1, Image_Desc *s2, Image_Desc *d, int k);
Mélange de deux HF. Le coefficient k 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.
int Image_hf15_mult(Image_Desc *s1, Image_Desc *s2, Image_Desc *dst);
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 signe.
int Image_hf15_getmin(Image_Desc *s1, Image_Desc *s2, Image_Desc *d);
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 Image_hf15_getmax dont la sémantique est évidente.

haut de page

bruitages

int Image_hf15_noise_0(Image_Desc *dst, int hi, int lo, int pr100);
Avec une probabilité de (pr100 % 100), l'altitude sera mise entre hi et lo pour tout les points de l'image.
int Image_hf15_noise_1(Image_Desc *dst, int mo, int of, int pr100);
Cette fonction déplace une atltitude de 'mo' avec un offset de 'of'. Le paramètre 'pr100' n'est pas utilisé.
int Image_hf15_noise_2(Image_Desc *dst, int pr100, int di, int k1, int k2);
Remplacement aléatoire du point courant par un de ses proches voisins. Le code n'est hélas pas encore vraiment optimisé.
int Image_hf15_noise_3(Image_Desc *dst, double coef, int flag);
Léger bruitage proportionnel à la hauteur du point concerné. Cette fonction a été inventée pour la montagne de Sonia.

Synthèses

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.

int Image_hf15_synth_0(Image_Desc *dst, Image_PtList *ptl);
Pas très fini, en cours de démoulage. Et vous ne savez pas ce qu'est une PtList ? Voici un petit topo.
int Image_hf15_synth_fromfunc0(Image_Desc *dst, int k, double(*func)(int x, int y, int k))
Vous avez sous la main une fonction du genre h = func(x, y) ? 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 dynamique complète du hf.

haut de page

liens

Dans un autre domaine povesque, si vous créez deux images en déplaçant légerement le point de vue, vous pouvez les combiner en une image, que vous verrez en relief avec une paire de lunettes munie des filtres adéquats.

haut de page