Vous êtes sur la page 1sur 40

REPRESENTATION D’UN CHAMP DE DIAGRAPHIES

AVEC RACCORDEMENTS

Master ASIG et IASIG

Benoît ANTOINE, Maryse FANTIN Février 2008

1
TABLE DES MATIERES
I. INTRODUCTION 4
A. La Géomatique 4
B. Rapide description des diagraphies 4
1. Définition 4
2. Utilisation 5
II. OBJECTIFS 6
A. Objet à afficher 6
B. Hypothèses 6
C. Outils à employer 6
III. METHODE 7
A. Définition des grandes lignes du projet 7
B. Prise en main de l’outil Fortran95 8
1. Gestion des bases de données 9
a) Ecrire des fichiers .txt 9
b) Lire des fichiers.txt 9
2. Gestion de l’affichage 10
a) Appel des fonctions que renferment les bibliothèques OpenGL dans la
limite de ses aptitudes 10
b) Utilisation des bibliothèques d’IHM de Fortran95 10
C. Ecriture des algorithmes et construction des objets 11
1. Concepts 13
a) Construction de la surface au sol 13
b) Trouver le milieu du terrain 14
c) Position des puits et triangulation: généralités et construction de la base
de données 15
d) Les courbes de Béziers 17
e) Diagramme de récapitulation 18
2. Graphe d’appel 20
3. Réalisation des algorithmes 21
a) Algorithme de création d’un vecteur de nombres quasi aléatoires compris
entre 0 et 1 : 21
b) Obtention des valeurs extrémales des coordonnées terrain, ainsi que de
la position du centre et de l’échelle 21
c) Algorithme de l’IHM 21
d) Gestion des évènements de la souris 22
D. Utilisation des bibliothèques OpenGL avec Fortran95 : 23
E. Création de la boîte de dialogue 26
IV. RESULTATS 27
A. L’affichage 27
1. Mode d‘affichage 27
2. Le sol 28
3. Les puits 28
4. Les valeurs 29
5. Les limites de couches 29
6. Les couches 31
B. L’animation 32

2
1. Les rotations 32
2. Les translations 34
3. Réduction/ agrandissement 36
V. DISCUSSION 37
A. Définition des limites du projet 37
B. Phase de réalisation 37
C. Phase de manipulation 38
D. En équipe 39
VI. CONCLUSION 39
VII.REFERENCES 40

3
I. INTRODUCTION
A. La Géomatique
La géomatique est composée de l’ensemble des outils et méthodes utilisés pour
représenter, analyser et d'intégrer des données géographiques.
A notre niveau, les aspects de représentation et de traitement des données sont
développés pour répondre au sujet.

B. Rapide description des diagraphies

1. Définition

Une diagraphie est une technique de mesure des caractéristiques physiques de


roche. Elle peut être de deux types : instantanée ou différée. Elle consiste à effectuer
un forage dans un terrain puis à faire parcourir le puits par différents types de
sondes.

Figure 1 : Photo d’un forage. Utilisation à des fins géothermales (Learnz)

4
Selon les données enregistrées par la sonde,
il est possible d’évaluer la composition du
terrain sur la majeure partie du forage. Le
changement de nature de terrain lors du
passage d’une couche à une autre se traduit
par un saut de valeurs enregistrées par la
sonde.
Historiquement, cette technique était
dénommée carottage électrique et fût
inventée par Conrad et Marcel Schlumberger
au début du XXème siècle.

2. Utilisation
Les techniques de diagraphies permettent
entre autre de déterminer la densité, la
porosité, la perméabilité ainsi que la teneur en
hydrocarbure ou en eau d’un site.
Figure 2 : Principe de la diagraphie Elles peuvent se révéler utiles d’un point de
(Geological survey of Canada) vue géologique pour déterminer par exemple
le pendage des terrains rencontrés. Cependant, étant donné leur coût élevé de mise
en place et d’utilisation, elles sont essentiellement utilisées pour déterminer la valeur
économique d’un terrain. Un exemple d’application est la localisation des réservoirs
d’hydrocarbures par les groupes pétroliers. L’utilisation en hydrogéologie est aussi
commune pour localiser les nappes phréatiques et estimer leur capacité ou leur
propreté.

Figure 3 : Exemple d’utilisation en hydrogéologie


(Laynewater)

5
II. OBJECTIFS
A. Objet à afficher
Notre projet consiste à afficher un champ de diagraphies. Ceci implique de
représenter des puits de forages ainsi que les valeurs de diagraphies. Celles-ci
doivent caractériser les matériaux que la sonde rencontre lors de son voyage dans le
puits. Plusieurs puits sont forés dans le champ choisi, il existe donc un jeu de valeurs
de diagraphie pour tout le site. Lorsque les différentes valeurs de diagraphie sont
mises en corrélation, il apparaît des limites de profondeur entre les nombreux
terrains qui composent le site. Au final, les limites de terrain seront représentées
selon deux modes de vision : normal ou anaglyphique. Ce dernier mode de
représentation permettra à l’utilisateur de se donner une idée plus précise de la
scène en 3 dimensions.

B. Hypothèses
Les hypothèses suivantes ont été posées pour définir les limites du projet :

a) les valeurs de diagraphies sont analysées en amont par un ingénieur


géophysicien. Ceci implique que les limites de couches font parties du jeu
de données qui nous est fourni par le commanditaire.
b) Le jeu de données comprend donc :
• Un nombre de puits connu
• La localisation des puits
• la profondeur d’un puits: Ppuits
• le nombre de valeurs enregistrées: NVAL
• les valeurs qui sont enregistrées à chaque fois que la sonde a
parcouru un certain pas Dz constant en profondeur : Dz= Ppuits
/NVAL
c) toutes les valeurs de diagraphies sont utilisables
d) le puits de diagraphie est rigoureusement vertical

C. Outils à employer
Le projet doit être réalisé sous Fortran95 en utilisant la bibliothèque graphique
d’OpenGL. A la base de toute programmation, le langage algorithmique ADL a été
utilisé pour construire les
algorithmes.

Figure 4 : Représentation SIG d’un champ de diagraphie


construit à des fins hydrogéologiques pour localiser une nappe
phréatique (Burnside)
6
III. METHODE
A. Définition des grandes lignes du projet
Nous devons obtenir un objet 3D où sont référencées les interfaces entre les
différents terrains, tout comme les limites des liquides saturant le sol selon l’option
choisie.
Pour ce faire, nous avons choisi de travailler sur une base de :
• 12 puits
• 5 limites de couches (et donc 6 couches)
• Un sol en surface rectangulaire et plat dans un premier temps
• Une géologie simple : aucune lacune ni terrain de forme
lenticulaire.

Pour commencer, nous avons travaillé sur les algorithmes. Nous avons donc dû
déterminer précisément ce que nous voulions réaliser.
Nous imaginons dans un premier temps le bloc diagramme comme une
superposition de terrains continus de nature différente. Ce bloc est traversé par des
puits verticaux. Ceci est illustré par la figure qui suit :

Figure 5 : Représentation schématique du bloc diagramme traversé par des puits verticaux de
couleur noire.

La surface se situe en haut du bloc. Elle surmonte des couches de géométrie


variable mais conformes à nos hypothèses. Ces couches sont délimitées par les
lignes de différentes couleurs.

La réalisation du projet devra se faire selon les étapes suivantes :


• afficher les puits
• afficher les valeurs de diagraphie dans chaque puits par la
méthode des courbes de Bézier
• calculer les coordonnées écran d’un point dont on connaît les
coordonnées terrain

7
• créer automatiquement des tables qui seront utilisées pour
faire les calculs ou pour représenter l’objet
• utiliser un algorithme pour trouver le centre du bloc
diagramme

Sachant que pour qu’OpenGL dessine des triangles il faut lui renseigner des points
de tels sorte qu’il n’y ait pas de conflit entre deux triangles possédant un même bord,
nous pensions devoir utiliser des tables SIG et GD. Un algorithme a donc été créé à
cette fin.

Aucun algorithme ne peut être codé pour représenter le bloc diagramme sans base
de données. Il a donc fallu construire une base de données utilisables par Fortran.
Celle-ci est composée de fichier .txt que fortran ouvrira et lira pour copier les valeurs
renseignées dans des tables (vecteurs ou matrices) que le programme utilisera.
Les fichiers suivants ont été construits :
• Champ : possède les coordonnées cartésiennes (x,y,z) dans
l’espace 3D objet des points de surface de tous les puits.
• Couche : renseigne l’altitude absolue de toutes les limites de
couches, pour chaque puits.
• LP : renferme la colonne puis la ligne du tableau de valeurs qui
correspond à une limite de couche. Un seul tableau pour tous
les puits.
• Random : valeurs obtenues à partir d’un algorithme simple basé
sur les fonctions random_num, donnant une valeur entre 0 et
1 et date_and_time, qui fournit en sortie les dates et heures
d’exécution du programme. Les valeurs sont comprises entre
0.1 et 1. Ce fichier permettra la construction d’un tableau qui
gérera les couleurs affichées à l’écran : à chaque exécution,
les couleurs des couches sont ainsi différentes.
• Trian : possède des triplets de numéro de puits. Ces triplets
serviront à construire les triangles et ainsi permettre la
triangulation du terrain. Tous les triangles ont été organisés
de telle sorte qu’ils soient directs. Ainsi, si la réalisation du
projet nécessite de trouver le vecteur normal au domaine
délimité par les côtés d’un triangle, cette vérification ne sera
pas à faire.
• Val : enregistre l’ensemble des valeurs de diagraphie pour tous les
puits

B. Prise en main de l’outil Fortran95


Fortran95 a été choisi comme le langage de programmation qui servira à construire
le champ de diagraphie. Ce langage est essentiellement utilisé pour répondre à des
besoins scientifiques. Il commandera les fonctions OpenGL qu’il voudra bien prendre
en charge.
Fortran95 est conçu essentiellement pour des applications scientifiques, notamment
du traitement mathématique de données immenses. Nous avons donc appris à
manier ce langage et nous nous sommes appliqués à écrire le plus proprement
possible nos codes.

8
Avant toute programmation d’un nouveau code, un espace de travail (workspace)
doit être créé dans Fortran. Il y sera associé un projet (Fortran Console Application)
ainsi qu’un fichier (Fortran Free Format Source File).

Pour ce projet à forte composante d’affichage, Fortran a eu deux principales


utilisations:

1. Gestion des bases de données

a) Ecrire des fichiers .txt

Fortran écrit dans des fichiers grâce à la fonction open(). Celle-ci doit avoir
plusieurs arguments tels que :

• le numéro qu’elle doit attribuer au fichier, il est plus sage de choisir de grand
nombre pour éviter tout conflit avec un fichier qu’elle utilise déjà sans que l’utilisateur
en ait connaissance.

• l’action qu’elle doit mener sur ce fichier : lire ou écrire, ici WRITE

• le type de formatage.

• le nom du fichier renseigné en chaîne de caractères ou son chemin exact


(‘C:/…. Txt’ ou ‘D:/….txt’).

• l’état du fichier : préexistant ou à créer, ici OLD (préexistant) a été choisi parce
que les mêmes fichiers sont réutilisés à chaque utilisation du programme. Ecrire de
nouveaux fichiers à chaque fois nécessiterait de leur attribuer un nom différent à
chaque fois ou de les effacer manuellement à chaque fois que le programme est
lancé. Ceci rendrait son utilisation beaucoup moins fluide.

Une partie du code a été choisie comme illustration :

Programme censuré
b) Lire des fichiers.txt

Ici, Fortran utilise toujours open() pour ouvrir les fichiers. Les arguments utilisés sont
les suivant :

• le numéro qu’elle doit attribuer au fichier

• l’action qu’elle doit mener sur ce fichier : ici READ

• le type de formatage

• le nom du fichier renseigné en chaîne de caractères ou son chemin exact

9
• l’état du fichier : ici OLD (préexistant) parce qu’open ne fait que lire un fichier.

Un extrait de notre code a été choisi pour illustrer cette description :

Programme censuré

2. Gestion de l’affichage

a) Appel des fonctions que renferment les bibliothèques


OpenGL dans la limite de ses aptitudes

Pour être utilisables, les bibliothèques doivent être ajoutées à l’espace de travail de
Fortran dans le dossier Resource Files.
Au début de chaque module ou programme qui utilisera des fonctions d’OpenGL, il
sera nécessaire d’indiquer que ses bibliothèques doivent être mises à disposition.
Pour cela ‘use’ précédera open_gl, opengl_gl, opengl_glu et opengl_glut en chaque
tête de module ou programme.
La plupart des fonctions sont appelées par call (+ nom de la fonction). Néanmoins,
certaines tels que glutCreateWindow retourne un entier. Elles doivent donc être
affectées à un entier dont le type (integer) doit être précisé dans les déclarations.

b) Utilisation des bibliothèques d’IHM de Fortran95

10
C. Ecriture des algorithmes et construction des objets
Z2
Z4 Z6
Z3 Z5 Affichage
Z1 Tables de Ce qui doit écran de
valeurs être affiché tout ce qui a
Tables de IHM : été
Fichier texte pointeurs Ce qui est demandé
fourni avec qui mènent demandé
toutes les au bon par
données endroit l’utilisateur
nécessaires à dans les
l’affichage tables de
géomatique valeurs
du champ de Choix :
diagraphie - Nombre de
- Puits : NP puits
LP : position - Limites de - Affichage des
Définir le format dans la table couches : enregistrements
du fichier texte - Position Lesquelles ? ou pas
- Objets VAL
Mise en place … Enregistrement - Affichage de
d’un algorithme - Valeurs des : oui/non tout le bloc en
pour obtenir des diagraphies Stéréo : o/n stéréo
valeurs pseudo dans chaque - Calcul des - Limite de
aléatoires puits mouvements couches à
afficher
Utilisation de
fonctions
OpenGL

ETAPES MENANT À LA MISE EN PLACE DES ALGORITHMES

11
Z1 : Lecture de fichiers texte. Constitution des tableaux Champ, Couche, Trian et VAL.

Mise en place d’un algorithme de construction de tables de réels aléatoires.

Enregistrement potentiel de toutes les actions dans une dayfile.

Z2 : Calcul des données utiles, telles que la position dans l’espace des valeurs de diagraphie.

Z3 : Mise en place de table de pointeurs. Exemple : LP, qui indique le rang dans le tableau VAL de la ième couche.

Z4 : Détermination des variables, telles que :


• NP : Nombre de puits
• NL : Nombre de limites
• NVAL : Nombre de valeurs de diagraphie

Affichage uniquement des données demandées par l’utilisateur, par l’intermédiaire de l’IHM (Z5).
Calcul des mouvements et de l’affichage qui en résulte. Gestion des évènements souris et clavier.

Z5 : IHM : Choix de l’utilisateur quant aux données à afficher : les puits, les valeurs de diagraphie, le rectangle d’emprise du terrain,
les couches ou encore les limites de couches.
Possibilités d’affichage de l’IHM :
• Puits : 2 possibilités : oui/non
• Enregistrements : 2 possibilités : oui/non
• Limites de couche : tout ou rien, ou affichage des limites de couches voulues uniquement.
• Couches : tout ou rien, ou affichage des couches voulues uniquement.
• Stéréoscopie : 2 possibilités : oui/non. Si oui, on double les données à prendre en compte.

Demandes de l’utilisateur pour une rotation, translation ou encore un zoom (modification de l’échelle). Possibilités de revenir à la
position initiale.

Z6 : Utilisation des fonctions d’OpenGL pour l’affichage des données à l’écran.

12
Nos algorithmes ont pour la plupart repris des fonctionnalités qu’OpenGL prend en
charge. Ceux-ci se sont donc avérés moins productif que prévu à l’origine.

La liste des algorithmes qui ont été écrits est la suivante :


• affichage des puits
• affichage des valeurs de diagraphie dans chaque puits par la
méthode des courbes de Béziers
• calcul des coordonnées écran d’un point, dont on connaît les
coordonnées terrain
• calcul des coordonnées écran d’un point de surface de chaque puits
dont on connaît les coordonnées 3D
• calcul des coordonnées écran de l’ensemble des points de mesure de
chaque puits
• création automatique des tables référençant la localisation des limites
de couches pour tous les puits
• création automatique des tables qui possèdent les valeurs extrêmes
d’altitude (min et max) pour chaque puits, puis pour chaque limite de
couche
• création automatique de la table des valeurs de diagraphie pour
chaque puits
• trouver le centre du bloc diagramme

Pour pouvoir construire les différents objets de notre projet, nous utilisons les bases
de données que nous avons construites. Nous avons procédé comme suit :

1. Concepts

a) Construction de la surface au sol

Cette surface doit encadrer tous les puits. Pour ce faire, il nous faut comparer toutes
les valeurs d’ordonnées et d’abscisses des puits. Les coordonnées maximales et
minimales pour l’ensemble des puits seront gardées. Un nombre leur est ajouté ou
retranché pour qu’aucun puits ne se trouve sur un bord. Les coordonnées extrêmes
obtenues seront utilisées pour définir les sommets de la surface au sol. La figure 6
illustre ce propos.

13
Figure 6 : Méthode de construction de la surface au sol

b) Trouver le milieu du terrain

Pour trouver le milieu du terrain, un algorithme simple a été construit. Il est basé sur
un principe simple de comparaison de valeurs pour toutes les coordonnées des
puits. Les valeurs extrêmes obtenues en abscisses, ordonnées et profondeur sont
manipulées de telles sortes qu’on obtienne la position au milieu du bloc diagramme.
Toute la procédure est illustrée sur le schéma qui suit.

14
Figure 7: Méthode de détermination des coordonnées de milieu de terrain : trouver le centre du
bloc diagramme

c) Position des puits et triangulation: généralités et


construction de la base de données

Lors de la phase d’écriture des algorithmes, un module de construction des tables


SIF et GD (respectivement sommets initiaux/sommets finaux et gauche/droite) a été
créé. Il pourra être utilisé par un autre module pour déterminer le sens de parcours
des sommets des triangles pour qu’ils soient directs.

Le raisonnement a été le suivant pour construire la table GD:


• soit T1 le premier triangle dont les trois sommets sont enregistrés dans la
table TRIAN. Ces informations seront situées dans la 1ère ligne du tableau, sur
les 3 colonnes.
• soit SI le sommet initial du triangle (1er sommet dans la 1ère colonne du
tableau). Il nous faut comparer SI avec les 2 autres sommets référencés dans
la table des triangles.
• Selon le sens du vecteur résultat du produit vectoriel entre le vecteur a (allant
de SI à SF) et le vecteur vect1 (allant de SI au 3ème sommet du triangle), le
domaine (triangle) se situera à droite ou à gauche du vecteur a.
• La figure 8 illustre la méthode employée.

15
Figure 8: Utilité des tables SIF pour la construction de la table GD. L’arc a est à droite du
domaine 1 : le sens du vecteur Z bleu est négatif selon l’axe Zp. Il est à gauche du domaine 2 :
le sens du vecteur Z vert est positif.

Le sens de rotation du triangle sera déterminé en utilisant la même méthode. En


effet, soit un triangle donné (une ligne donnée du tableau TRIAN), et deux vecteurs :
a (allant du 1er au 2ème sommet, soit de S1 à S2 dans TRIAN) et vect1 (allant du 1er
au 3ème sommet, soit de S1 à S3). Si le produit vectoriel des vecteurs a et vect1
donne un vecteur résultant négatif selon l’axe vertical, le sens de rotation direct sera
S1-> S2-> S3. Dans le cas contraire, il sera S1S3S2.

Cependant, parce que nous avons pris le parti de construire une base de données
fixe pour la durée du projet, nous n’avons pas utilisé les algorithmes précédents. En
effet, nous avons directement créé les domaines de telle sorte que le sens
d’apparition des sommets soit direct pour chaque ligne du tableau. Ainsi, nous avons
préparé l’éventuelle utilisation de fonctions d’éclairage qui nécessiteraient de
connaître la norme de chaque domaine. Dans ce cas, tous les domaines du terrain
doivent avoir une norme qui doit globalement avoir le même sens. Par la suite, le
produit vectoriel entre le vecteur lumière et la norme des domaines déterminera la
zone du domaine à couvrir d’ombre des limites de couches si besoin est.

16
Figure 9: Localisation des puits de diagraphie sur le terrain. Chaque nombre correspond à un
puits. Chaque T suivi d’un nombre correspond à un numéro de triangle (considéré comme
domaine ici).

d) Les courbes de Béziers

Les valeurs de diagraphie sont enregistrées pour chaque puits. La courbe qui doit les
représenter doit donc courir le long du puits qu’elle caractérise. Pour ce faire, nous
choisissons d’ajouter la valeur de diagraphie aux abscisses du puits concerné. Les
coordonnées selon la verticale seront données par le pas DZ d’enregistrement des
valeurs ainsi que le rang de la valeur. Ainsi la 6ème valeur enregistrée se trouvera à la
profondeur de : Z ici= Z Altitude en surface - 6*DZ.
Une fois que les coordonnées de tous les points sont déterminées, ils seront reliés
de telle sorte que la courbe obtenue passe le plus près possible de chaque point.
Dans la réalité, la courbe ne passe exactement sur aucun point, à l’exception des
deux extrémités. La figure 10 représente la méthode employée pour tracer les
courbes.

Finalement, lors de la phase de codage, nous avons été confrontés à des étapes de
programmation sous Fortran 95 non maitrisées. N’ayant pu coder la représentation
3D des valeurs par la méthode des courbes de Béziers, nous avons donc
simplement reliés un ensemble de points dont les coordonnées étaient enregistrées
dans un tableau CDB (courbe de Béziers).

17
Figure 10: Méthode de construction des courbes de valeurs de diagraphie: utilisation des
courbes de Béziers

e) Diagramme de récapitulation

18
19
2. Graphe d’appel

20
3. Réalisation des algorithmes

a) Algorithme de création d’un vecteur de nombres quasi


aléatoires compris entre 0 et 1 :

ALGORITHME censuré

b) Obtention des valeurs extrémales des coordonnées


terrain, ainsi que de la position du centre et de l’échelle

ALGORITHME censuré

c) Algorithme de l’IHM

Les commandes de la boîte de dialogue qui seront employables par l’utilisateur


seront de quatre types :
- ‘push button’ ou bouton pressoir : ce type servira à commander des actions
simples qui peuvent répondre à l’état d’un booléen comme le mode de vision
(normal ou anaglyphique) ou l’initialisation (réaffichage de l’objet tel qu’il était
à l’origine).
- ‘check-boxe’ : 2 états sont disponibles pour cette commande : vrai ou faux. Il
s’agit donc encore de booléens cachés derrière ce type. Nous avons choisi de
les utiliser pour gérer l’affichage des objets selon la volonté de l’utilisateur.
- Scrollbar : le curseur positionné sur cette barre prend des valeurs entières
comprises entre une valeur minimale et une valeur maximale. La position du
curseur peut donc servir à faire évoluer une variable. Nous avons choisi de les
appliquer aux mouvements verticaux et horizontaux de l’objet, tout comme
aux rotations selon les 3 axes de l’espace.
- Slider : seule l’apparence diffère de la scrollbar. Les principes de
fonctionnement sont les mêmes. Il aura donc la même utilité que cette
dernière. Sa fonction sera ici de régler l’écart entre l’objet rouge et l’objet vert
lorsque le mode anaglyphique est choisi

Le premier algorithme a pour fonction de créer la boîte de dialogue et d’y associer


les divers boutons de commandes :

ALGORITHME censuré

21
d) Gestion des évènements de la souris

Les algorithmes qui suivent, permettent à l’utilisateur de modifier l’affichage de l’objet


grâce à la souris. Ainsi, lorsqu’il active la souris, il peut faire tourner l’objet selon le
mouvement de la souris.

La souris est un outil qui possède 3 boutons (droite, milieu, gauche) et 2 états (actif,
inactif).

Nous voulons attribuer un mouvement de rotation à l’objet lorsque le bouton de


gauche est activé et que la souris se déplace. Le bouton droit permettra quant à lui
de zoomer.

ALGORITHME censuré
Parce que l’amplitude des transformations (rotations ou translations) est liée au
déplacement de la souris, il est nécessaire de connaître la position de celle-ci même
lorsqu’ aucun de ses boutons n’est actif. En effet, si la dernière position enregistrée
correspond à l’arrêt du clic de la souris, lorsque l’utilisateur cliquera sur l’image, la
différence se fera entre l’ancienne valeur à l’arrêt du clic et les nouvelles
coordonnées écran du clic. Il en résultera un saut d’objet à l’écran.

ALGORITHME censuré

22
D. Utilisation des bibliothèques OpenGL avec
Fortran95 :
Les outils qu’OpenGL proposent sont intéressants. Il a été nécessaire d’utiliser des
livres tels qu’OpenGL 1.2, guide officiel par M.Woo, J.Neider, T.Davis, et D.Shreiner
(Editions CampusPress Référence). Malgré tout, nous avons réaliser que tous les
exemples de ce livre sont écrits en C.

Voici la liste des principales fonctions OpenGL utilisées :

Table de nombres aléatoires :


- random_number() donne un nombre réel compris entre 0 et 1. Il est tiré d’une
table conséquente de réels enregistrés dans le compilateur.
- date_and_time() fournit les données de temps et de date au moment de
l’exécution du programme. Elle donne dans l’ordre : l’année, le mois, le rang du
jour dans le mois, l’heure, la minute, la seconde et la milliseconde d’exécution du
programme.

Gestion de fichiers texte :


- open() ouvre le fichier demandé.
- write() permet d’écrire dans le fichier demandé. Elle efface entièrement le
fichier texte avant de réécrire dessus.
- read() permet de lire dans le fichier déterminé.

Gestion des Buffers :


- glClear(GL_COLOR_BUFFER_BIT) permet d’effacer le buffer stockant les
couleurs et ainsi définit le fond de la scène.
- glClear(GL_DEPTH_BUFFER_BIT) permet d’effacer le contenu du Z-Buffer.
- glDepthFunc(GL_LESS) dessine le point si la valeur est plus petite que celle
enregistrée dans le Z-Buffer.
- glEnable(GL_DEPTH_TEST) active le Z-Buffer. Ainsi, si deux objets sont l’un
en dessus de l’autre, alors seul l’objet situé le plus près de l’observateur est
affiché.

Gestion des matrices de rotation :


- glMatrixMode() détermine le type de la matrice de rotation.
- glLoadIdentity() réinitialise la matrice de rotation.
- glpushMatrix() enregistre la matrice de rotation.
- glpopmatrix() récupère la dernière sauvegarde de la matrice de rotation.

Modification des coordonnées objets :


- glScalef() modifie l’échelle de l’espace objet suivant les 3 axes.
- glrotatef() effectue une rotation sur les coordonnées objet, suivant un axe et
un angle déterminés.
- gltranslatef() effectue une translation des coordonnées objet, selon un axe et
une distance.
- gluperspective() détermine le volume de vue dans lequel sera affiché l’objet.

23
Gestion du tracé des objets :
- glLineWidth() détermine la largeur des lignes tracées
- glPointSize() détermine la taille des sommets
- glColor4f() détermine la couleur des objets
- glBegin(GL_LINES) permet de tracer des lignes reliant les sommets 2 à 2.
- glBegin(GL_LINE_STRIP) permet de tracer des lignes reliant les sommets
suivant une liste donnée.
- glBegin(GL_LINE_LOOP) est identique à GL_LINE_LOOP, mais avec la
propriété supplémentaire de relier les 2 extrémités entre elles.
- glBegin(GL_POLYGON) permet de tracer des polygones convexes.
- glBegin(GL_TRIANGLES) permet de tracer des triangles en tenant compte
des points 3 à 3.
- glVertex3f() place un point dans l’espace objet.

Gestion de l’IHM :
- dlginit(): initialise la boîte de dialogue
- dlgset(): associe les boutons à la boîte de dialogue
- dlgsetsub(): associe les boutons à l’activation d’une subroutine
- dlgmodeless(): définit le type de boîte de dialogue
- dlgget(): permet d’obtenir la valeur correspondant à la position du curseur sur
une scrollbar ou sur un slider.

Gestion des évènements clavier et souris :


- glutKeyboardFunc() permet de spécifier au programme le nom de la
subroutine qui gère les évènements clavier. Ainsi, elle prend en paramètre
d’entrée le nom de la subroutine considérée.
- glutmotionfunc() gère les évènements engendrés par le déplacement de la
souris, lorsque qu’au moins un bouton de celle-ci est appuyé.
- glutpassivemotionfunc() gère les évènements engendrés par le déplacement
de la souris, lorsque qu’aucun bouton de celle-ci n’est appuyée.

Gestion de la fenêtre d’affichage :


- glutInit() initialise la bibliothèque GLUT.
- glutInitDisplayMode() spécifie le mode d'affichage de la fenêtre. Par exemple,
permet de définir le jeu de couleur utilisé (RVB, CMJN, soit les 3 valeurs allant de
0 à 255, ou sinon les valeurs allant de 0 à 1).
- glutInitWindowSize(), détermine la taille de la fenêtre d’affichage
- glutInitWindowPosition(), détermine la position de la fenêtre d’affichage au
niveau de l’écran de l’ordinateur
- glClearColor(), détermine la couleur de fond de la fenêtre d’affichage
- glutCreateWindow(), crée la fenêtre d’affichage

Fonctions d’affichage des données :


- glutSwapBuffers(), force l’affichage du résultat.
- glutDisplayFunc(), est la fonction de rappel d’affichage pour la fenêtre
courante.
- glutMainLoop() permet d'entrer dans la boucle de GLUT de traitement des
événements. Dans cette boucle, les fonctions de rappel qui ont été enregistrées
sont appelées à tour de rôle.

24
Autres fonctions :
- gluLookAt() détermine le point de vue de l’observateur.
- glShadeModel(GL_SMOOTH) permet de lisser les objets, pour éviter
l’apparition non voulue de face. On peut citer comme exemple celui des sphères,
dont on veut éviter de voir qu’elles sont constituées de facettes.
- glEnable(GL_BLEND) permet de mieux combiner les couleurs au niveau d’un
pixel.
- glutPostRedisplay() permet le rafraîchissement de l’affichage de l’objet.

25
E. Création de la boîte de dialogue

L’IHM a été divisée en deux


parties :
• Une pour la commande
d’affichage
• Une pour la commande
d’animation
Dans la partie AFFICHAGE,
l’utilisateur commande le mode
d’affichage, en vision
anaglyphique ou normale, par un
bouton pression ‘Anaglyphique’.
Pour ajuster l’affichage à la vue de
l’utilisateur, nous avons choisi de
lui donner la possibilité de régler
l’écart entre l’objet rouge et l’objet
vert en utilisant un slider.
De même, l’utilisateur pourra
choisir le type d’objet qu’il affiche
(puits, valeurs, limites de
couches…) grâce à des check-
boxes.
La partie ANIMATION lui permet
d’avoir le contrôle des objets
affichés. L’utilisateur peut régler la
position de l’objet à l’écran,
effectuer des translations
verticales et horizontales,
procéder à des rotations selon les
3 axes de l’espace ou choisir de
réinitialiser l’affichage. De plus, il
pourra choisir de réduire ou
agrandir l’objet grâce au slider du
zoom.
Les fonctions ci-dessus sont
attachées à des scroll-bar et un
bouton pression pour l’initialisation
qui commande le retour à
l’affichage initial de l’objet.

Figure 11 : capture d'écran de l'interface


homme/machine ou IHM

26
Les différents modes de commande de l’IHM choisis sont relativement simples à
utiliser. De manière générale, chaque bouton active un moteur composé de cases.
Lorsque le bouton est activé, il commande par le biais de ce moteur une partie du
code qui régit l’opération de transformation (translation, rotations, initialisation).

IV. RESULTATS
Les outils qu’OpenGL proposent sont intéressants pour la création des objets que
nous avons choisis. La liste des objets affichés est associée à une capture d’écran
de notre affichage pour chaque type d’objet.
Notre programme est fait de telle sorte qu’à chaque nouvelle exécution les couleurs
des couches soient différentes. Ceci explique pourquoi les couches du bloc
diagramme apparaissent sur les captures d’écran suivantes avec des couleurs
différentes.

A. L’affichage

1. Mode d‘affichage
Nous avons choisi de pouvoir afficher le terrain selon 2 modes : l’un normal qui fait
apparaître l’objet en perspective. L’autre anaglyphique qui fait apparaît l’objet en 3
dimensions à condition que l’observateur utilise des lunettes appropriées.

- Normal :

L’affichage normal aura l’avantage de montrer les épaisseurs de couches. C’est celui
qui donnera le mieux une estimation des volumes qui composent le bloc diagramme.

Figure 12: Affichage normal du bloc diagramme. Tous les objets apparaissent en volumes
pleins plus ou moins transparents.

- Anaglyphique :

Le mode d’affichage anaglyphique montrera bien plus précisément les reliefs qui
composent l’objet. Pour cela, l’objet doit être filaire. Il doit être affiché deux fois à
l’écran. Une fois à gauche et en rouge, une autre fois à droite et en vert. Un

27
observateur muni de lunette avec un filtre rouge pour un œil et un filtre vert pour
l’autre œil verra l’objet apparaître en 3 dimensions pour peu que l’écart soit ajusté à
son regard. C’est pourquoi nous avons choisi de mettre une commande sur l’IHM
pour que l’utilisateur puisse régler l’écartement entre les deux objets à son gré.

Figure 13: Bloc diagramme affiché en vision anaglyphique. Deux images sont superposées :
une rouge à gauche et une verte à droite.

2. Le sol

Il est représenté par un rectangle. Pour réaliser cette surface, la fonction d’OpenGL
qui permet l’affichage des rectangles est utilisée. Les quatre points utilisés sont ceux
de qui encadrent les extrema des coordonnées de puits renseignées par le fichier
champ.txt

Figure 14: Surface du bloc diagramme

3. Les puits

28
Ils sont représentés par des lignes épaisses verticales. Ils possèdent la même
longueur et sont positionnés grâce aux coordonnées enregistrées dans le fichier
champ.txt.

Figure 15: Puits

4. Les valeurs

Les valeurs doivent s’agencer au côté du puits qu’elles caractérisent. Pour les
positionner au bon endroit, les valeurs sont considérées comme étant une ligne. Les
différents points qui la composent possèdent la même ordonnée que le puits, mais
leur abscisse correspondra à celle du puits à laquelle une valeur val est ajoutée.
Celle-ci est donnée par le fichier val.txt. La profondeur décroit proportionnellement en
fonction du numéro de la valeur dans le puits et du coefficient de profondeur DZ.

Figure 16: Valeurs de diagraphie: courbes courant près des puits qu'elles caractérisent

5. Les limites de couches

Vues de dessus, les limites de couches ressemblent à une superposition de surfaces


planes composées de triangles. Ceci est dû au fait que l’abscisse et l’ordonnée des
sommets qui la composent ne varient pas d’une couche à l’autre. En réalité, la
profondeur varie ce qui confère aux surfaces un relief.
Nous considérons chaque triangle comme étant un domaine. L’un des sommets du
triangle sera le sommet initial et le sommet final de l’arc (périphérie du triangle). Les
2 autres sommets du triangle seront considérés comme étant des points annexes.

29
Chaque sommet de triangle correspond à l’emplacement d’un puits à une certaine
profondeur.

Figure 17: Vue de dessus des limites de couches en vision anaglyphique. Chaque sommet des
triangles correspond à la position d'un puits

La seule restriction imposée est que pour un puits donné, le sommet d’une couche
ne doit pas être à une altitude supérieure de celui qui le précède. De même, son
altitude ne doit pas être inférieure à celle du sommet qui le suit.

Figure 18: Vision anaglyphique des limites de couches, vue de côté

Chaque limite de couche correspond à un raccordement entre les différents puits au


niveau de changement brusque de même sens et de même ordre dans les valeurs
de diagraphies. Les figures suivantes montrent le résultat en vision normale.
L’utilisateur peut choisir entre un affichage complet de toutes les couches et un
affichage ciblé des couches qui l’intéressent (figures 19 et 20).

30
Figure 19: en affichage normal, les limites de couches apparaissent de façon nette aux
changements brusques de valeurs de diagraphie

Figure 20: Il est possible de choisir les limites de couches affichées. Ici, une limite de couche
sur deux a été gardée

6. Les couches

Elles sont représentées par un volume compris entre 2 limites de couches.

En utilisant la boîte de dialogue, l’utilisateur peut choisir les couches qu’il veut
afficher. La transparence plus ou moins prononcé des volumes permettent d’identifier
la position des puits ou de suivre les variations de valeurs des limites de diagraphie.

31
Figure 21: Représentation des couches existant sur tout le terrain

Figure 22: Certaines couches du bloc diagramme précédent ont été masquées

B. L’animation

L’affichage d’un objet 3D ne serait pas très utile si l’utilisateur n’avait pas la
possibilité de manipuler cet objet. En effet, c’est grâce à cette manipulation que
l’observateur pourra se rendre pleinement compte des dimensions et reliefs du
terrain. Nous avons choisi 3 grands types de transformations : la rotation, la
translation et la modification d’échelle.

1. Les rotations

Les rotations selon les 3 axes de l’espace ont été assurées. L’axe des abscisses est
considéré comme étant l’axe horizontal par rapport à l’observateur. L’axe des
ordonnées sera l’axe vertical pour l’utilisateur. Le dernier axe, celui de la profondeur,
sera celui qui court de l’objet vers l’utilisateur.

Pour pouvoir comparer ces trois commandes, nous comparerons chaque


transformation à la position initiale de l’objet (figure 23).

32
Figure 23: position initiale de l'objet

- Rotation selon l’horizontale : rotation autour de l’axe x.

Les coordonnées des tous les éléments qui composent l’objet subissent une
multiplication matricielle avec une matrice de rotation selon x. il en résulte un
basculement de l’avant de l’objet soit vers le bas, soit vers le haut selon l’angle de
rotation choisi.

Figure 24: position après rotation selon les abscisses (axe horizontal par rapport à
l’observateur)

- Rotation selon la verticale : rotation autour de l’axe y.

33
Cette transformation résulte en un mouvement de l’avant de l’objet vers la droite ou
vers la gauche. Il s’agit ici aussi d’une multiplication matricielle qui est mise en
œuvre.

Figure 25: position finale après rotation selon les ordonnées (axe vertical par rapport à
l'observateur)

- rotation selon la profondeur : rotation autour de l’axe z.

Comme toute rotation, il s’agit ici aussi d’une multiplication matricielle.

Figure 26: position finale de l'objet après rotation selon l'axe de la profondeur (axe allant de
l'objet à l'observateur)

2. Les translations

Toute translation utilisera encore une fois le principe des multiplications de matrices
pour des raisons d’homogénéité avec les autres transformations. En réalité, il s’agit
d’utiliser un vecteur de dimension 3 qui ajoutera à chaque coordonnée de tous les

34
points un pas. Ce pas correspond à la valeur des coordonnées du vecteur
translation.
- Position initiale de l’objet : image qui sert de référence pour identifier la
transformation après translation.

Figure 27: position initiale de l'objet avant toute translation


- Translation selon l’axe vertical :

Pour obtenir ce résultat, toutes les ordonnées de tous les points de l’objet se sont
vues ajouter un pas transY.

Figure 28: position finale de l'objet après une translation verticale

35
- Translation selon l’horizontale :

Toutes les abscisses des points se sont vues ajouter un pas de translation transX.

Figure 29: position finale de l'objet après une translation horizontale

3. Réduction/ agrandissement

De même que pour les rotations et translations, la modification d’échelle est donnée
par une multiplication matricielle d’une matrice carrée à 4 dimensions.

Figure 30: Objet tel qu'il apparaît après un agrandissement de l'échelle

36
V. DISCUSSION

A. Définition des limites du projet


Notre première étape a été de définir les limites de notre projet. L’essentiel des
difficultés a résidé dans le fait que notre projet porte essentiellement sur l’affichage et
beaucoup moins sur le traitement de données. Il nous a donc été nécessaire de
définir quel était le niveau de détail requis pour que l’application puisse être
intéressante d’un point de vue interprétatif.
Pour cela, nous avons ciblé notre recherche sur des algorithmes de calculs qui ne
reprennent pas des fonctions existantes d’OpenGL.
Aujourd’hui que le projet est fini, nous réalisons que nous avons utilisé peu de nos
algorithmes. Tel est le cas pour l’algorithme de construction des tables SIF et GD,
tout comme ceux qui permettent d’obtenir les coordonnées écran depuis les
coordonnées 3D dans l’espace objet.

A cette phase de définition des limites s’ajoute la définition des fonctionnalités


auxquelles un utilisateur pourrait faire appel. Pour cela, il nous a fallu nous mettre
dans la peau d’un utilisateur pour penser au mieux la gestion de l’affichage et de
l’animation.

B. Phase de réalisation
Cette étape passe obligatoirement par une période de prise en main de l’outil
Fortran95 avant de réussir à manipuler des objets 3D grâce à OpenGL. Malgré les
difficultés rencontrées initialement, nous avons réussi à obtenir un résultat en
affichage normal d’un objet en perspective tout comme un affichage en vision
anaglyphique.
Malgré tout, il reste quelques difficultés que nous n’avons pas su résoudre.

En premier lieu, l’affichage en vision anaglyphique reste problématique. En effet,


nous avons évidemment réalisé qu’une simple translation de l’objet et son affichage
dans une autre couleur ne suffit pas à donner un résultat suffisant. Si cette seule
opération est réalisée, alors lors de la rotation, les objets rouge et vert subissent tout
deux la transformation. Il en résulte une inversion dans l’affichage des couleurs :
l’objet vert, initialement à droite de l’objet rouge passe à sa gauche.

Deux solutions se sont présentées à nous :


- inverser les couleurs lorsque l’objet subit une rotation d’une valeur d’angle
comprise dans l’intervalle d’inversion. Cependant, parce que nous
autorisons les rotations dans les 3 dimensions de l’espace, nous sommes
confrontés à un problème de définition des intervalles d’inversion que nous
n’avons su résoudre.
- Obtenir l’affichage de deux objets identiques cette fois-ci dans deux
procédures. L’idée était de créer un premier objet, d’initialiser les matrices
qui lui sont associées pour l’affichage, d’opérer les transformations voulues
et d’afficher le résultat à l’écran. La même procédure sera appliquée au
deuxième objet, image du premier après translation. Pour ce faire, nous
avons choisi d’implanter ces deux procédures dans une boucle allant de 1

37
à 2. Cette boucle contient un case qui l’objet vert ou rouge selon l’état de la
boucle. Ce procédé s’est montré efficace sur un objet simple tel qu’un
cube. En effet, l’objet rouge restait constamment à la gauche de l’objet
vert. Les transformations qui leur étaient appliquées avaient la même
amplitude, par conséquent les deux objets restaient côte à côte.
Cependant, nous n’avons su implanter cette procédure dans le bloc
diagramme complet.

Une autre difficulté rencontrée a été celle des multiplications matricielles lors d’un
enchaînement de transformations. En effet, dans le cas des rotations, nous avons
réalisé que lors d’une succession de rotation, une multiplication de matrices
s’opérait et les axes résultants devenaient différent des axes initiaux.
Pour éviter un tel écueil, il aurait fallu utiliser un repère différent de celui de l’espace
objet, ou même de celui de l’objet. Ainsi, nous aurions dû utiliser un repère dont l’axe
des profondeurs serait celui allant de l’objet cible vers l’utilisateur, dont l’horizontale
serait donnée par un produit vectoriel entre la verticale et l’axe des profondeurs.
Avec un tel repère, toute transformation appliquée ne paraît pas subir de
multiplication de matrice.

Le même type de difficulté d’implantation s’est présenté lors de la mise en fonction


d’un retour à l’affichage initial. La procédure était opérationnelle sur un objet simple
comme le cube : l’objet retournait à sa place initiale et dans la position initiale. Lors
de l’implantation dans le code du terrain, seule le retour à la position initiale a été
réussi.

De même, nous n’avons pu tracer réellement des courbes de Béziers. Nous avons
donc dû nous résoudre à les remplacer par des segments joignant les points
correspondant aux valeurs des puits.

D’autres difficultés, cette fois inhérentes au fonctionnement du compilateur, nous ont


ralenti dans notre progression. La fabrication d’un système de tirage aléatoire de
nombres réels. La subroutine que nous avons construite, est basée sur la fonction
random_num (qui n’a rien d’aléatoire : les chiffres de sortie sont toujours les mêmes
dans le même ordre) ainsi que sur l’heure d’exécution du programme pour introduire
une donnée variable. En théorie, il ne sera possible d’obtenir le même tableau de
valeurs qu’uniquement dans le cas où le programme est exécuté à la même
milliseconde du même jour de l’année. Mais, malheureusement, l’aléatoire n’existe
pas en informatique.

C. Phase de manipulation
Nous avons été confrontés au problème de la portabilité : les mêmes fonctions
provenant des mêmes bibliothèques ne sont pas toujours fonctionnelles selon la
machines utilisée. Un exemple précis serait l’association de fonctions aux boutons de
la souris. Normalement, si une fonction différente est assignée à chacun des boutons
de la souris, chaque bouton doit activer sa propre fonction. Or, nous avons dû
constater que tous les boutons de notre souris donnent le même résultat même si
des fonctions différentes leur sont affectées. La seule fonction activée sera celle du
bouton gauche.

38
D. En équipe
Les difficultés qui suivent, sont cette fois-ci entièrement liées à nos aptitudes.
En effet, il est plus ou moins difficile selon les individus d’appréhender correctement
les 2 repères utilisés sous OpenGL : le repère de l’objet (ou repère terrain) et le
repère de la zone d’affichage. La confusion entre les deux reste parfois un écueil à
éviter.
De plus, s’agissant de notre premier projet de programmation de près de 2000
lignes, il nous est apparu bien clairement les raisons pour lesquelles il faut apporter
du soin à la façon dont le programme est fait. Le code doit être clairement commenté
et structuré de telle sorte qu’il puisse être repris par n’importe qui. L’organisation sera
le reflet de la structure de l’algorithme. Les variables doivent être déclarées en en-
tête et commentées de telles qu’elles soient compréhensibles par tous. En effet,
nous avons vite compris l’intérêt des règles qui viennent d’être énoncées surtout
lorsqu’il s’agit d’implanter des morceaux de programme d’un membre du projet dans
le travail de l’autre membre. De même nous aurions dû convenir de noms de
variables pour éviter tout conflit à résoudre lors de cette implantation.
L’implantation des subroutines gérant l’anaglyphe et le retour à la position initiale
sont deux exemples flagrants du problème énoncé ci-dessus.

VI. CONCLUSION
Notre sujet est essentiellement axé sur l’affichage d’un objet 3D et s’est montré
intéressant pour plusieurs raisons. Tout d’abord, s’agissant de notre première
expérience de programmation d’un objet en 3D, il a consisté en de nouvelles
connaissances à acquérir et à maîtriser. De plus, ayant été traité peu de fois dans
les promotions antérieures, nous n’avons pu nous baser sur les travaux d’anciens
pour penser notre projet. Tout a été donc à penser et à construire.
De plus, toutes les difficultés rencontrées inhérentes à nos aptitudes ou à notre façon
de procéder ont été très formatrices. Elles constituent des écueils à éviter pour les
projets suivants dont nous sommes entièrement conscients. Un exemple parlant est
celui des noms d’identificateurs à convenir pour faciliter la mise en commun des
codes de chacun des membres de l’équipe. Un autre exemple est celui de la
transcription d’un concept algorithmique qui parait pourtant évident dans la réalité à
un code en Fortran. Ainsi, la traduction en Fortran du concept algorithmique Ale(0),
donnant un réel compris entre 0 et 1, qui n’est pas si aisée.

Même si l’utilisation des champs de diagraphies appartient à un domaine très


spécialisé, il n’en est pas moins que les connaissances acquises sont transférables :
- Dans le cas de la gestion de bases de données, il nous aura fallu les
construire avant de pouvoir les utiliser et éventuellement les modifier.
- Parce que nous avons construit la base de données nous avons dû gérer :
o le positionnement des éléments qui composent notre objet
o la visualisation 3D sur papier avant de pouvoir afficher le résultat à
l’écran. Ceci a consisté en la construction d’une BD non aléatoire
entièrement sur papier avant même de l’afficher sur l’écran. Il a
donc fallu s’assurer de la bonne coordination des tables qui
composent cette BD ce qui fut relativement difficile.

39
- L’étape de construction d’une boîte de dialogue nous a permis de nous
mettre dans la peau d’un utilisateur lambda. Nous avons considéré que
celui-ci a pour seul but de pouvoir effectuer les modifications qu’il souhaite
sans pour autant modifier le code de l’application.

Ce projet constitue notre première vraie expérience de programmation. Nous en


retirons donc beaucoup de bénéfices. Ainsi, nous sommes entièrement convaincus
que la structuration et le commentaire d’un programme sont des qualités
impérativement requises pour tout projet. En effet, la récupération de tout
programme qui ne répondra pas aux impératifs précédemment énoncés se verra très
difficile voire quasi impossible.

VII. REFERENCES
Les images trouvées :
Bore hole : http://geothermal61.learnz.org.nz/pan/big/b-drill-rig.jpg
Geological survey of Canada: http://gsc.nrcan.gc.ca/borehole/index_e.php
Layne water: www.laynewater.com/borehole_geophysics.html.
Burnside: http://www.rjburnside.com/GIS.aspx
Ardara: www.ardara-me.com/borehole.html.
Musée du pétrole, Schlumberger : http://www.musee-du-
petrole.com/schlumberger.htm

40

Vous aimerez peut-être aussi