approximation volumique et octrees - Infoterre

publicité
BRGM
L'ENTREPRISE A U SERVICE DE LA TERRE
APPROXIMATION VOLUMIQUE
ET
OCTREES
R 31333 ISA-SGN 90
Août 1990
LACOUR Ph. - SGN/ISA
BRGM
établissement public à caractère industriel et commercial
Sidge : Tour Mirabeau, 39-43, quai André-Citroën - 75739 Paris cedex 15, France
Tél.: (33) 1 40.58.89.00 - Télex : B R G M 780258 F - Télécopieur : (33) 1 40.58.89.33
R.C. 58 B 5614 Paris - SIRET : 58205614900419
Centre scientifique et technique :
Avenue de Concyr, Orléans-La Source (Loiret) - B.P. 6009 - 45060 Orléans cedex 2, France
Tél.: (33) 38.64.34.34 - Télex : B R G M 780258 F - Télécopieur : (33) 38.64.35.18
Reme
M*~
M1"
Le?
H1-
rciements A s
Yve»
Martinez
J e a n F*±er-ï-e V e y r i e r
service
SGN/ISA
R é g i s Bacl i er-
SOMMAIRE
INTRODUCTION
1
PRESENTATION GENERALE
3
Orientation Objet
3
Problème posé
3
Structure de données
3
ALGORITHMES
5
1 - Repérage et Codage
5
la - Repérage des octants fils d'un cube
5
1b - Repérage des direction de recherche des adjacents
6
S - Définitions, Propositions
7
Définition 1 <Frère)
7
Proposition S
(Adjacent Frère)
7
Proposition 3
(adjacent)
/
9
Définition 4 (cube frontière d'un octree 1)
10
Définition 5 (cube frontière d'un octree S)
10
3 - Algorithmes
10
3a - Algorithme de subdivision
10
3b - Algorithme d'Intersection et de réunion
11
3c - Algorithme de recherche d'adjacent
13
3d - Algorithme de recherche de la filiation
15
3e - Algorithme de recherche de la parenté
16
3f - Algorithme de création de 1'Octree frontière
17
CONCLUSION
18
BIBLIOGRAPHIE
19
ANNEXE la Structure "pointeurs"
i
Descriptif des objets HyperCube et Octree.
i
1 - Organisation de l'objet HyperCube
i
la - Descriptif des champs de l'objet HyperCube
ii
lb - Descriptif des méthodes de l'objet HyperCube
ii i
2 - Organisation de l'objet Octree
iv
Sa - Descriptif des champs de l'objet Octree
vi
Sb - Descriptif des méthodes de l'objet Octree
vii
Annexe lb Structure "tableau"
ix
Descriptif des objets Octree et OctreeSurf.
ix
1 - Organisation de l'objet Octree
ix
la - Descriptif des champs de l'objet Octree
xii
lb - Descriptif des méthodes de l'objet Octree
xiii
S - Organisation de l'objet OctreeSurf
xv
Sa - Descriptif des champs de l'objet OctreeSurf
xvi
Sb - Descriptif des méthodes de l'objet OctreeSurf
xvi i
Annexe S Résultat des fonctions
xvii i
1 - Tableau de résultat de la fonction NouvDir
xviii
S - Tableau de résultat de la fonction EstFrere
xix
3 - Tableau de résultat de la fonction OpposeSurAxe
xx
-
1 -
INTRODUCTION
En informatique, le volume d'un solide peut être décrit de
deux manières :
- Un arbre C.S.G ("Constructive Solid Geometry")
- Un arbre Octal (ou Octree)
La première méthode consiste à approcher le volume par des
primitives volumiques le composant, le problème étant la
détermination desdites primitives. En effet celles-ci sont
à priori inconnues dans un volume quelconque (cas qui nous
intéresse i c i ) , il en est autrement si le volume est luimême défini par des primitives volumiques connues.
<Cf Annexe la)
•
La seconde méthode 1CMEA 81D(celle choisie dans cette
étude) consiste à englober le volume dans un cube appelé
"Univers", puis a subdiviser celui-ci en huit cubes égaux,
les "Octants fils", chacun reçoit alors un attribut de
couleur :
- Blanc s'il n'appartient pas au volume
- Noir s'il appartient au volume
- Gris s'il intersecte le volume
La subdivision est opérée récursivement sur chacun des
fils. Ce pose alors le problème de l'arrêt de la
subdivision. On se donne une taille minimale de
subdivision en fonction de la finesse de définition du
volume. Les octants noirs et blancs sont considérés comme
terminaux (ils ne seront pas subdivisés), alors que les
octants gris seront eux subdivisés jusqu'à obtention
d'octants noirs blancs ou de taille minimale. (Cf Annexe
lb)
Il existe toutefois deux types d'Octree :
- Les Octrees dits "complets"
- Les Octrees dits "polygonaux" ou "exacts"
Pour les Octrees "complets" on réalise la subdivision
spatiale telle que décrite précédemment.
Pour les Octrees "polygonaux" on introduit des attributs
supplémentaires pour les octants gris :
- Face si l'octant est traversé uniquement par une
facette du solide.
- Arête si l'octant est traversé par une arête et par
les deux facettes qui s'y rattache.
- Sommet si l'octant contient un seul sommet et si les
facettes qui le traversent se rencontrent en ce point.
- aLes Octrees "polygonaux" ne peuvent être utilisés que
lorsqu'il s'agit, de décrire un volume polygonal, ou
pouvant être considéré comme tel. Aussi ne traiterons nous
ici que de l'utilisation des octrees "complets".
La description du volume d'un solide a pour but la
réalisation d'opérations sur des solides, opérations
telles que intersection ou réunion entre deux solides,
représentation de solide, coupe dans un solide. Toutes ces
opérations nécessitent des notions d'adjacence entre les
octants composant l'arbre, des notions de frontière de
1'octree. Ces notions seront abordées ultérieurement.
Figura 1 x Objet et 1'Octree correspondant
PRESENTATION GENERALE
Orientation Objet
Pour développer les algorithmes nous avons utilisé un
langage de programmation orienté objet le C++
glockenspiel. L'avantage de ce concept de programmation
réside dans la structure de nos données qui ne sont plus
tributaires des procédures qui les utilisent mais qui
possèdent leurs procédures à travers lesquelles nous
accédons aux données. 2CWILE 883
En fait le C++ est un langage de classes, c'est à dire que
chaque objet est structuré en ses données et ses
procédures, tout cela formant un type évolué appelé
classe. Cela réalise une encapsulation 3CWILE 883donnéesprocédures qui fait qu'une modification de l'organisation
des données en interne influe le moins possible sur
l'utilisation de ses données.
Un autre concept de la programmation en C++ est la notion
d'héritage^CWILE 883, en effet si une classe doit posséder
la même structure de données qu'une autre classe, dite
classe mère, on ne récrit que les données supplémentaires
de la nouvelle classe et on la fait hériter de la classe
mère. Ainsi toute modification de la classe mère se
répercutera automatiquement sur les classes filles qui ont
héritées d'elle.
Problème posé
Le problème posé par le BRGM est d'analyser un volume pour
en tirer le maximum de renseignements et pouvoir réaliser
les opérations décrites en introduction.
Tout cela bien sûr le plus rapidement possible et sur des
modèles relativement importants <le mai liage moyen est de
l'ordre de 80000 points). Les volumes sont donnés sous
forme de mai liages tridimensionnels, chaque point
possédant un attribut, nous nous limiterons à un attribut
noir (1) ou blanc (0). Avec ces volumes nous devons créer
l'octree correspondant, être capable de le stocker sur
disque et enfin de pouvoir réaliser des opérations sur ces
octrees.
Structure de données
La première approche envisagée fut celle d'une structure
pointeur avec deux objets, l'hypercube et l'octree. Cette
structure est relativement naturelle et simple a
appréhender. En effet l'objet élémentaire qu'est
l'hypercube est la base de l'octree, chaque hypercube
devant posséder le nom de son père et celui de ses fils
s'il en a <Cf Annexe S ) . Mais cette structure est trop
gourmande en mémoire, la seule chose intéressante à
- 4 conserver étant la couleur (on ne peut pas la retrouver
par calcul) le reste est donc stocké inutilement.
Cette solution fût donc abandonnée.
La seconde structure dérive de la structure d'arbre
binaire sous forme tableau (Cf cours L0*f ) . Mais cette
structure oblige à réserver la place pour la filiation des
octants noirs et blancs, ce qui est très coûteux en
mémoire, donc incompatible avec les exigences du BRGM. La
structure définitive est donc une structure tableau où
l'on ne conserve que la filiation des octants gris. Pour
cela on sépare en deux tableaux les octants gris et les
octants noirs et blancs. C'est à dire que dans chaque
tableau un octant est représenté par un bit. Dans le
tableau codant les gris le bit est à 1 si l'octant est
gris et à 0 dans le cas contraire. De mfme dans le tableau
codant les noirs, le bit est à 1 si l'octant est noir et à
0 autrement. Ainsi il est possible de retrouver rapidement
la couleur d'un octant et de reconnaître les octants gris
dans un niveau de subdivision.
Cette dernière possibilité est primordiale car il faut
être capable de déterminer le nombre de gris avant une
position précise pour connaître la filiation d'un octant
gris. De même il faut pouvoir déterminer le n * ^ m e gris
dans un niveau pour connaître la parenté.
- 5 ALGORITHMES
Les Algorithmes mis en oeuvre sont valables dans la mesure
où l'on définit le repère associé à l'univers.
1 - Repérage et Codage
Tout d'abord, le repère est un repère direct, l'axe des
côtes étant dirigé vers le haut. L'origine du repère se
trouve en bas à gauche et au fond du cube univers.
1* - Repérage des octants fils d'un cube
Les vecteurs d'origine le centre de l'univers et
d'extrémités le centre d'un des octants fils, ont pour
coordonnées respectivement et dans l'ordre croissant des
côtes, ordonnées, abscisses :
(-1, - 1 , -1 )
(-1 »-l> + 1 )
(-1, + 1» -1 )
(-1 > + l >+1)
(+1, - 1 , -1 )
( + 1,-!> + 1 )
( + 1,+1» -1 )
( + 1, + l» +1)
Remplaçons les -1 par des 0. Cela devient :
-
< 0, 0, 0)
( 0, 0,+l)
< 0,+l, 0)
( 0,+l,+l)
(+1, 0, 0)
<+l, 0,+l)
(+1,+1, 0)
(+1,+1,+1>
Si l'on considère que ce sont les trois premiers bits
d'un octet, le codage des octants fils devient :
0
1
2
3
h
5
é>
7
pour
pour
pour
pour
pour
pour
pour
pour
1 'octant
1 'octant
1 'octant
1 'octant
1 'octant
1 'octant
1 'octant
1 'octant
Nord-Ouest-Nadir
Nord-Ouest-Zéni th
Nord-Est-Nadir
Nord-Est-Zénith
Sud-Ouest-Nad i r
Sud-Ouest-Zéni th
Sud-Est-Nadir
Sud-Est-Zénith
Les octants fils ne seront désormais désigné que par
leur code ainsi l'octant fils ¿f désignera l'octant
Sud-Ouest-Nad ir.
- 6
lb - Repérage des direction de recherche des adjacents
Les directions utilisées seront les directions
cardinales composées simples des directions élémentaires
Nord-Sud,Ouest-Est et Zénith-Nadir. Cela nous amène à
considérer vingt six directions possibles. Ces
directions sont repérées par les vecteurs suivants :
(-1 ,-1 >-l> pour
(-1 »-!) 0) pour
(-1 ,-1 ,+1 ) pour
(-1 > 0 9 -1 ) pour
<-l > 0 , 0) pour
(-1 > 0 ; + 1 ) pour
(-1 » + l »-D pour
(-1 . + !> 0) pour
(-1 j + 1 , + 1) pour
<
, - 1 , -1 ) pour
<
,-1 , 0) pour
» - l 5 + 1) pour
( , 0> - l > pour
( > 0 ,+ 1 ) pour
<
»+l .-1 > pour
( . + 1» 0) pour
(
.+1 , + D pour
( + 1f - 1 J -1 ) pour
( + 1,-1 i 0 ) pour
( + 1, - 1 , + 1 ) pour
( + 1; 0 f - D pour
( + 1> 0» 0) pour
( + 1, 0 , + 1 )pour
(+1 » + l > -1) pour
( + 1»+l , 0) pour
< + l j + l J + 1) pour
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
la
direction
direction
d irect ion
direction
direction
direction
direction
direct ion
direction
direction
direction
direction
direction
direction
direction
direction
direction
direction
direction
direction
direction
direction
direction
direct ion
direction
direction
Nord-Ouest-Nadir
Nord-Ouest
Nord-Ouest-Zéni th
Nord-Nadir
Nord
Nord-Zénith
Nord-Est-Nad ir
Nord-Est
Nord-Est-Zénith
Ouest-Nadir
Ouest
Ouest-Zénith
Nadir
Zénith
Est-Nadir
Est
Est-Zénith
Sud-Ouest-Nadir
Sud-Ouest
Sud-Ouest-Zéni th
Sud-Nadir
Sud
Sud-Zénith
Sud-Est-Nadir
Sud-Est
Sud-Est-Zénith
Séparons ce vecteur en deux composantes. Une première
composante appelée direction spécidiée qui contiendra 1
si le nombre correspondant est un 1 et 0 dans la cas
contraire. Une seconde composante appellee direction
indéterminée qui contiendra 1 si le nombre correspondant
est un 0 et 0 dans le cas contraire. Par exemple la
direction Sud-Nadir sera codée de la façon suivante :
- direction spécifiée
- direction indéterminée
<+l, 0, 0)
< 0,+l, 0)
De plus l'utilisateur devant passer la direction en
paramètre, pour que cela soit plus explicite, nous
utiliserons une variable contenant l'octet représentant
la direction spécifiée accolé à l'octet représentant la
direction indéterminée.
- 7 Les formules de changement de représentation sont :
- Passage de représentation vectorielle à
représentation cardinale :
- DirCard = DirSp * 8 + Dirlnd
- Passage de représentation cardinale à représentation
vectorielle :
- DirSp
= (DirCard &. 00111000) / 8
- Dirlnd = (DirCard & 00000111)
S - Définitions, Proposition
Définition 1 (Frère)
Dans un octree, un octant est dit frère d'un autre si
il appartient au même octant père que celui-ci.
Proposition S (Adjacent Frère)
Dans un octree, un octant O g ( 0ai»^22»^23^ adjacent
d'un octant O j (0 j j,0 ig,013) dans la direction d
(d¿,dg,d3), est Frère de celui-ci si et seulement si :
i)
ii )
iii)
O
0
0
1 1
S i
e i
* d 1 + O l s * d g + O
= O u si d j s
0
= - 0 - ü si dj <> 0
1 3
* d 3 < = 0
Démonstration 5Cqaco 90D
Soient CO J J les coordonnées du centre de 0 1 , C P O ^ les
coordonnées du centre du père de 0|, a la longueur de
l'artte de Oj . La portion d'espace englobée par le
père de 0^ est définie par :
( C P 0 H - 2a <= x i <= C P 0 U + 2a) i - 0,1,2
Ol
est
la
portion d'espace définie par
( C 0 i i + 0 i
i
* a ~ a < = X i < = C 0
1
:
j + 0 i i * a + a >
Le voisin de O j dans la direction d est le translaté
de O j par la translation de vecteur 2a * d, soit la
portion d'espace définie par :
( C O ^ + Oí i * a + 2a * d^ - a <= x^ <= COj ¿ + 0^ ¿ * a
+ 2a * di + a ) ( 1 )
- sLe
fils de type OQ dut père de Qj
(CPOjj
+ Cgj
*
a -
vérifie
a <= x¿ <= CPOj j
:
+ Ogj *
a + a)
(2)
Identifions (1) et <2) :
alors quel que soit i = 1,2,3 Ojj + 2 * dj = 0ai.(3>
l°cas : dj = 0, alors 0j¿ = Cgj (d'après (3)) et
°li * dl i <= 02°cas : dj = - 1 , alors 0 ^ = Ogj + 2 (d'après (3)>
donc Ojj = +1 (car Ojj = -1,0,1) et 0 t i * dj¿ <* 0.
3°cas : dj = +1, alors 0 ¿ i = Ogj - 2 (d'après (3>)
donc Oij = -1 (car Oji = -1,0,1) et 0,^ * d 1 4 <= 0.
d'où le résultat.
- 9 Proposition 3 (adjacent)
On dit qu'un octant O j est adjacent à un autre octant
Og dans une direction d, si l'une des conditions est
vérifiée :
i)
O j est le frère de O g dans la direction d
ii> 0 j est l'adjacent de l'octant père de O g dans
une direction d' et 0 ^ n'a pas de filiation.
iii) O j est un fils de l'adjacent A de l'octant père
de O g dans une direction d'. Soit OA le fils de A
qui est de même type que Og. O j est alors l'adjacent
Frère de OA.
Avec d' vérifiant :
- d'i « 0 si dj = 0 ou si dj = - Ogi .
- d ' j - d j si dj *= Ogj .
Démonstration 6Cqaco 903
i) a déjà été traité dans la proposition S, ii) est
similaire à iii) et peut être traité comme lui, à
condition de raisonner comme si on subdivisait tous
les octants. On considère simplement les octants non
subdivisés comme étant leurs propres fils.
Soient a la longueur de l*ar?te de Og , COgj les
coordonnées du centre de Og, CPOgj les coordonnées du
centre du père POg de Og , CAPOgj les coordonnées du
centre de l'adjacent de POg dans la direction d',
COjJ les coordonnées du centre de O j , CPOjj les
coordonnées du centre du père de 0\ . Il faut et il
suffit que les coordonnées de CAPOg et de CPOj
coïncident, soit les expressions de ces coordonnées :
CAPO g i = C P O e i
+ 4 * di'
# a
CPO ! j, = CPOgj + 0 S i * a + 3 * d ¿ # a - Oji * a
D'où la relation suivante :
¿ t * d j ' +OJJ = 0 g i
+2*dj
Trois cas se présentent alors :
i)
d ¿ = - 1 , la relation devient ^ d ^ ' + O i j = Ogj-2
a- 0 e i = -1 alors 0 ^ = 1, d i' = 1
b - 0 2 i = +1 alors O J Î = - 1 , d j ' = 0
ii)
d ¿ = 0 , la relation devient A d ^ ' + O j i = O g j
a - O g ! = -1 alors 0 ^ = - 1 , d j ' = 0
b - 0 2 i = 0 alors 0 ^ = 0 , d f = 0
c - 0 e i = +1 alors On = + 1 , d ¿' = 0
iii) d ¿ = + 1 , la relation devient 4dj'+0j¿ = ®Eï + 2
a- 0 2 i = -1 alors 0 ^ = 1, d j ' = 0
b - 0 2 i = +1 alors O - ^ = - 1 , d ^ = 1
-
10 -
En regroupant les résultats, on obtient :
- d ' j = 0 si d j = 0 ou si d i = - O p j .
- d ' i = d j si d j = Ogisoit là condition sur d ' . De plus on obtient
- Q^i = O U si d¿ = 0
:
- Cfei = -Ojj si di O 0
soit la relation qui donne l'opposé sur l'axe de
direction, obtenue dans la proposition S.
Définition h (cube frontière d'un octree 1)
On dira qu'un cube est frontière d'un octree si parmi
ses adjacents, il en existe au moins un qui soit
blanc.
Définition 5 (cube frontière d'un octree 2 )
On dira qu'un cube est frontière d'un octree s'il
existe un chemin d'adjacents blancs qui conduise au
frontière de l'univers.
3 - Algorithmes
3a - Algorithme de subdivision
Subdivise (Niveau,
NbGrisPere)
/* niveau du géniteur
*/
/* Nb de groupes a creer */
tantque (i < NbGrisPere)
<
QuidAdresse (j,NGroupe,Nom>
Coul <- QuidCouleur (Niveau,j)
Si (Coul = GRIS)
C
QuidPosition (Abscisse,Ordonnée,Cote,Niveau,j)
NbFilsGris <- NbFilsGris +
CreerFils (Abscisse,
Ordonnée,
Cote,
Niveau + 1)
i <- i + 1
>;
j <- j + i
>
NbGFils CNiveau + 1] <- NbGrisPere
Si (NbFilsGris <> 0) Subdivise (Niveau +• 1 ,NbFi lsGr is )
-
11 -
3b - Algorithms d'Intersection et de réunion
Intersecte (Octl,
Octe,
Niveau,
Posl,
Pose,
Pos)
/*
/#
/*
/*
/*
octree a intersecter
"
"
niveau d'intersection
position des peres du
feuillage a intersecter
*/
*/
#/
*/
*/
**#*•****•**#***#*#**#•**#*#*
* * * * # * # * * # # * * * # * * * * * # * * * * * *
* Table
*
*
*
Cubel Cubée Résultat *
*
*
*
* 0 NOIR BLANC NOIR
#
# 1 NOIR GRIS NOIR
#
* S NOIR NOIR NOIR
*
* 3 BLANC BLANC BLANC
#
* ^ BLANC GRIS GRIS
*
* 5 GRIS GRIS Indt
*##**#*#**##**#*#*#•***#*#*
d'intersection
*
*
#
*
#
*
*
*
*
*
* Table
*
Cubel CubeS
0
1
2
3
¿v
5
NOIR
NOIR
NOIR
BLANC
BLANC
GRIS
BLANC
GRIS
NOIR
BLANC
GRIS
GRIS
Résultat #
#
BLANC
*
GRIS
*
NOIR
•
BLANC
*
BLANC
*
Indt
*
*#***#***#***##**#•#***#*#*#
<
QuidAdresse
de réunion
*
(Pos,NGroupe,Nom)
Coull <- Octl -> QuidCouleur
CoulH <- OctS -> QuidCouleur
Coul <- (Coull OR CoulS) //
Coul <- (Coull AND CoulH) //
(Niveau,Posl)
(Niveau,PosH)
pour la réunion
pour l'intersection
Si (Coul = GRIS)
UniversGris CNiveauD CNGroupeD
UniversGris [Niveau] CNGroupeD OR PB CNom]
Si (Coull = CoulS)
<
NbGFils CNiveau + 13 <- NbGFils CNiveau + 1 3 + 1
Octl -> QuidFils (Niveau,Posl,0,NivFilsl,PosFilsl)
Octe -> QuidFils (Niveau,Pose,0,NivFilse,PosFilse)
Qu i dF i 1s (N i veau,Pos,0,N i vF i 1s,PosF ils)
//pour l'intersection
pour j allant de 0 à 7
Intersecte (Oct 1,Octe,NivFils,PosFilsl + j ,
PosFilse + j,
PosFils + j ) ;
>
QuidAdresse (PosFils,NGroupeFils,NomFils);
-IS
-
—
Si ((Uni versGris [Niveau + 13CNGroupeFils3 = 0)
et (UniversNoir CNiveau + 13CNGroupeFils3 = 0>)
<
NbGFils CNiveau + 13 <- NbGFils CNiveau + 1 3 - 1
UniversGris CNiveau3CNGroupe3 <UniversGris CNiveau3CNGroupe3 AND (NOT P2 CNom3)
UniversNoir CNiveau3CNGroupe3 <UniversNoir CNiveau3CNGroupe3 OR (PS CNom3)
>
>
//pour la réunion
pour j allant de 0 à 7
i
Réuni (Octl,OctS,NivFils,PosFilsl + j ,
PosFilsS + j ,
PosFils + j ) ;
>
QuidAdresse (PosFils,NGroupeFils,NomFils);
Si ((UniversGris CNiveau + 13CNGroupeFils3 = 0)
et (UniversNoir CNiveau + 13CNGroupeFils3 = S55))
C
NbGFils CNiveau + 13 <- NbGFils CNiveau + 1 3 - 1
UniversGris CNiveau3CNGroupe3 <UniversGris CNiveau3CNGroupe3 AND (NOT PE CNom3)
>
>
Sinon Si (Coull = GRIS)
{
Rattache (Posl,Pos,Oct 1,Niveau)
>
Sinon
C
Rattache (PosS,Pos,0ct2,Niveau)
}
>
Sinon
i
Si (Coul = NOIR)
UniversNoir CNiveau3 CNGroupe3 <UniversNoir CNiveau3 CNGroupe3 OR
>
P2 CNom3
- 13 3c - Algorithme de recherche d'adjacent
Adjacent
(DirCard,
NiveauCube,
Pos i t ionCube,
NiveauAdjacent,
PositionAdjacent)
/*
/*
/*
/*
/*
direction de recherche
niveau du cube
position du cube
niveau de l'adjacent
position de l'adjacent
*/
*/
*/
*/
*/
-
lit
-
—
i
Si ((NiveauCube = 0) et <PositionCube = 0))
C
NiveauAdjacent
<- 255
PositionAdjacent
<- 0
>
Sinon
<
Dir <- QuidDir (DirCard)
QuidAdresse (Posit ionCube,NGroupe, Nom)
FilsAPrendre <- OpposeSurAxe (Nom,Dir)
Si (Frère (Nom,Dir))
<
QuidPere (NiveauCube,
PositionCube,
NiveauPere,
PositionPere)
QuidFils (NiveauPere,
PositionPere,
FiIsAPrendre,
NiveauAdjacent,
PositionAdjacent)
>
Sinon
<
NDir <- NouvDir (Nom,Dir);
DirVoisin <- QuidDirCard (NDir)
QuidPere (NiveauCube,
Posi tionCube,
NiveauPere,
PositionPere)
Adjacent (DirVoisin,
NiveauPere,
Posi tionPere,
N i veauVo i s i nDuPere,
Posit ionVoisinDuPere)
Si (NiveauVoisinDuPere <> 255)
QuidFils (NiveauVoisinDuPere,
Posi tionVoisinDuPere,
FiIsAPrendre,
NiveauAd jacent,
Posi t ionAd jacent)
Sinon
Í
NiveauAdjacent <- 255
PositionAdjacent <- 0
>
- 15 -
_
3d - Algorithme de recherche de la filiation
Qu idFi Is (NiveauPere,
Posi t ionPere >
NomFils,
NiveauFils,
PositionFils )
Í
Si (EstFeuille
(NiveauPere,Positio nPere) = FAUX)
CompteGris (PositionFils,Posit i onPere,N iveauPer e)
PositionFils <- PositionFils * 8
PositionFils <- PositionFils + NomFils
NiveauFils
<- NiveauPere + 1
•
>
S i nij n
<
PositionFils <- Posi tionPere
NiveauFils
<- NiveauPere
}
>
CompteGris
(PositionFi ls,
PositionPere,
NiveauPere)
<.
pour i allant de 0 à NGroupe - 1
PositionGrise < - PositionGrise +
NGris CUniversG ris CNiveau3 C i33
y
Pos itionGrise <- Pos itionGrise +
NG ris C(UniversGris CNiveauD
AND Masque CNom3>3
y
CNGroupe3
- 16 -
—
3e - Algorithme de recherche de la parenté
Qu idPere (NiveauFils,
Posit ionFils,
NiveauPere,
Posi t ionPere)
C
Si (NiveauFils = 0)
<
NiveauPere
PositionPere
<- 0
<- 0
}
Sinon
<
QuidAdresse (Posi tionFils,N6roupe,Nom)
NiveauPere
<- NiveauFils - 1
PositionPere
<- RechGris (NiveauPere,NGroupe)
>
>
RechGris (NiveauPere,
Posi tionPere)
<
NFils = NbGFils [NiveauPere3 * 8
tantque (NbGrisTrouve <= PositionPere)
C
NbGrisTrouve = NbGrisTrouve +
NGris CUniversGr is CNiveauPere3
LUI
i = i + 1
>
i = i - 1
NbGrisTrouve -= NbGrisTrouve NGris CUniversGris [NiveauPere] CiD3
i = i * 8
tantque ((NbGrisTrouve <= PositionPere) et (i < NFils))
{
Si (QuidCouleur (NiveauPere,i) = GRIS)
NbGrisTrouve = NbGrisTrouve + 1
i = i + 1
}
i = i - 1
return (i)
>
NGris est un tableau contenant le nombre de bits à un
dans un octet en fonction de sa valeur. Cela permet de
traiter huit fils à la fois.
-
17 -
3f - Algorithme de création de 1'Octree frontière
La création d'un Octree frontière avait pour but de
diminuer la taille occupée en mémoire par la structure
de données, en éliminant l'intérieur du volume. Cela
nous donnait une surface codée dans un octree. Cette
structure tenant moins de place elle permettait de
rajouter le stockage de la filiation et de la parenté.
L'accès aux données en étant alors accéléré, problème
crucial de la représentation graphique. Mais la
première notion d'octree frontière (définition A)
n'élimine pas l'intérieur de 1'octree, en effet tous
les gris restent gris, seuls quelques noirs deviennent
blancs. Quant à la seconde notion d'octree frontière,
elle n'a pas été implémentée car l'algorithme est trop
gourmand en niveau de récursivité.
-
18 -
CONCLUSION
Cette étude a permis de démontrer que les algorithmes
applicables aux Octrees sont parfaitement adaptables aux
besoins du BRGM en matière d'approximation volumique. La
structure de données proposée est compacte et rapide, les
tests effectués sur un BULL BM60 <640K,BMhz) ont permis de
creer deux Octrees et de les intersecter (resp. réunir) en
moins de 5 minutes pour des volumes de l'ordre de 80000
points. Il s'agit tout de m?me d'une ébauche qui demande à
être approfondie, tout particulièrement dans le domaine de
la visualisation, de la coupe des volumes et de la
modification des volumes après création de 1'octree. De
plus la structure de données du BRGM étant en FORTRAN, il
est nécessaire de réaliser 1'interfaçage FORTRAN-C++, car
pour l'instant les routines fonctionnent tout à fait en
dehors de tout environnement. Il est donc nécessaire
d'envisager, a plus ou moins long terme, la création d'une
interface utilisateurs, aussi bien pour l'utilisation des
routines dans un programme FORTRAN, que pour l'utilisateur
du logiciel ainsi créé.
1
-
19 -
BIBLIOGRAPHIE
1CMEA 813 D. fEASHER Geometric Modeling Using Octree Encoding
COMPUTER GRAPHICS AND IMAGE PROCESSING 19, 1S9-147
P.134-135. Date de publication 198S, date d'écriture 1981,
ECWILE 883 R. W IEflER et J.F. LEHIS An Introduction to ObjectOriented Programming and C++ Chpt 1 et 2.
3CWILE 883 R. WIENER et J.F. LEHIS An Introduction to ObjectOriented Programming and C++ Chpt 4
4CWILE 883 R. WIENER et J.F. LEHIS An Introduction to ObjectOriented Programming and C++ Chpt 5
5Cgaco 903G. GARCIA et J.F. LEC0RRE Recherche d'adjacents dans un
espace multidimensionnel représenté par un arbre AFCET Vo1.
9,N°1 1990 P.38-39.
6Cgaco 903G. GARCIA et J.F. LECORRE Recherche d'adjacents dans un
espace multidimensionnel représenté par un arbre AFCET Vo1.
9,N«1 1990 P.39-40.
Erratum GARCIA et J.F. LECORRE Recherche d'adjacent» dans un
espace multidimensionnel représenté par un arbre AFCET Vo1.
9,N°1 1990 P.41, paragraphe 4.2, Il faut lire s
(d XOR r.specif) OR r.Indif « 11.. 1 pour le mot «indif»
(d AND r.specif) pour le mot «specif».
On constate que le mot «indif» est donné par la même formule
que «tous-les-produits-négatifs», ce qui permet de ne faire li
calcul qu'une fois.
1
-
ANNEXE la Structure "pointeurs"
Cette structure inclue deux objets :
+ L'hypercube
+ L'octree
L'octree étant en fait un arbre d'HyperCubes situé dans
1'espace.
Descriptif des objets HyperCube et Octree.
1 - Organisation de l'objet HyperCube
private :
HyperCube
*
HyperCubePere;
HyperCube
* * HyperCubesFils;
unsigned char
Taille;
short
*
Coord;
unsigned char
Couleur;
unsigned char
TypeFils;
HyperCube
unsigned char
HyperCube
*
HyperCube
*
long
unsigned char
short
*
unsigned char
QuidNom
QuidPere
QuidFils
QuidTaille
QuidCouleur
QuidPosition
""HyperCube
EstFeuille
(short,
unsigned char,
unsigned char,
unsigned char,
short *,
HyperCube * = 0,
unsigned char = 0 ) ;
();
<);
(unsigned c h a r ) ;
();
();
();
( ) ;
<);
- i l -
la - Descriptif des champs de l'objet HyperCube
- HyperCubePere ;
Pointeur sur l'adresse du père de 1'HyperCube
considéré. Ce champ sert à remonter dans
l'arborescence, il est fort utile pour la recherche
d'adjacents.
- HyperCubesFils :
Pointeur sur la structure des fils de 1'HyperCube. Ce
pointeur est en fait un tableau de pointeurs sur chacun
des fils de 1'HyperCube.
- Taille i
Contient la taille de 1'HyperCube considéré. Cette
taille est en fait stockée sous la forme du niveau de
subdivision auquel appartient 1'HyperCube. La taille de
1'HyperCube est la taille de l'univers divisée par la
puissance de deux du niveau.
- Coord ;
Contient les coordonnées du centre de 1'HyperCube dans
le repère de l'univers. Ces coordonnées sont exprimées
en demi-maille.
- Couleur :
Contient la couleur de 1'HyperCube
Gris = 1, Blanc = 0.
: Noir = 3,
- TypeFils ;
Contient le nom de 1'HyperCube parmi ses frères.
- I l l
-
lb - Descriptif des méthodes de l'objet HyperCube
- HyperCube :
Constructeur de l'objet HyperCube. Cette procédure
permet l'initialisation des champs de l'objet.
- QuidNom :
Retourne le nom de 1'HyperCube parmi ses frères. Par
défaut, le nom de la racine est zéro. 11 s'agit de lire
le champ TypeFils.
— QuidPere :
Retourne l'adresse du père de l'HyperCube. Par défaut,
le père de la racine est la racine elle-mîme. Il s'agit
de lire le champ HyperCubePere.
- QuidFils :
Retourne l'adresse du fils de l'HyperCube. Le fils d'un
noeud terminal est le noeud lui-même. Il s'agit de lire
le champ HyperCubeFils.
- QuidTaille :
Retourne la taille de l'HyperCube. Par défaut, la
taille de la racine est la taille de l'univers. Il
s'agit de lire le champ Taille.
- QuidCouleur ;
Retourne la couleur de l'HyperCube. Il s'agit de lire
le champ Couleur.
- QuidPosition :
Retourne la position de l'HyperCube dans l'univers. Il
s'agit de lire le champ Coord.
- ""HyperCube ;
Destructeur de l'objet HyperCube. Cette procédure
désalloue les pointeurs affectés par le constructeur.
- EstFeui1 le :
Détermine si un HyperCube est noeud terminal ou non.
IV
2 - Organisation de l'objet Octree
private :
HyperCube
short
long
float
float
unsigned ch ar
*
#
#
*
Direction
short
short
Directioni
unsigned ch ar
unsigned ch ar
unsigned ch ar
void
#
short
vo id
void
vo id
vo id
void
Racine;
VolumeV;
NbrePts;
MinAxe;
LMaille;
Minimal ;
QuidDir
QuidDirCard
Frere
(short);
(Direction);
(unsigned char,
Direction);
(unsigned char,
NouvDir
Direction);
(unsigned char,
OpposeSurAxe
Direction);
(short,
CVol
short,
short);
ValCouleur
(ParamCube);
Subdivise
(HyperCube * ) ;
Posi t ionFiIs (unsigned char,
ParamCube);
(HyperCube
*);
Li tOctree
EffaceBranche (HyperCube *>;
(HyperCube *,
Rattache
HyperCube * ) ;
(HyperCube *,
Intersecte
HyperCube *,
HyperCube * ) ;
(HyperCube
*,
Réuni
HyperCube *,
HyperCube * ) ;
pub lie
Octree
Octree
(unsigned char,
short *,
float *,
float *>;
(short,
short *,
float *,
float *,
short * ) ;
— v
HyperCube
vo id
void
vo id
HyperCube
Octree
Octree
void
*
*
#
*
Ad jacent
Translat ion
Homothetie
Rotation
QuidRacine
Intersection
Reunion
^Octree
Affiche
(short,
HyperCube * ) ;
<float * ) ;
(float * ) ;
(float * ) ;
<>;
(Octree *) ;
(Octree * ) ;
<>;
<>;
- v i -
Sa — Descriptif des champs de l'objet Octree
- Racine :
contient l'adresse de l'HyperCube racine de 1'Octree.
- VolumeV :
Indicatrice définissant le volume.
- NbrePts :
Nombre de points définissant le volume.
- MinAxe :
Position de l'univers dans le repère absolu.
- LMaille :
Largeur des mailles sur chaque axe.
- Minimal :
Taille minimum de subdivision de l'espace.
-
vi i -
Sb - Descriptif des méthodes de l'objet Octree
- QuidDir :
Renvoie la direction vectorielle correspondant à la
direction cardinale passée en paramètre.
- QuidDirCard :
Réalise l'opération
inverse de la fonction ci-dessus.
-Frère :
Détermine si le cube de nom passé en paramètre possède
un frère comme adjacent dans la direction spécifiée.
- NouvDir :
Détermine la direction dans laquelle il faut rechercher
l'adjacent au père du noeud.
- OpposeSurAxe :
Détermine l'opposé de l'HyperCube sur l'axe de
direction de recherche de l'adjacent.
- CVol :
Retourne la couleur du point du volume.
- ValCouleur :
Détermine la couleur de l'HyperCube.
- Subdivise :
Réalise la subdivision spatiale.
— PositionFils :
Retourne les coordonnées du fils de l'HyperCube.
- LitOctree :
Lit
l'Octree.
- EffaceBranche :
Efface 1'octree récursivement.
- Rattache :
Rattache une branche d'un Octree à un autre Octree.
- Intersecte :
Intersecte deux Octrees.
-
vi 11
-
- Réuni :
Réunit deux Octrees.
- Octree ;
Constructeurs de 1'Octree. L'un des deux est utilisé
pour la construction á partir d'un volume, l'autre pour
l'intersection ou la réunion de deux Octrees.
- Adjacent :
Recherche l'adjacent au cube dans la direction de
recherche spécifiée.
- Translation :
- Homothetie :
- Rotation ;
- QuidRacine i
Retourne la racine de 1'Octree.
- Intersection :
Fonction appelée par l'utilisateur pour intersecter
deux Octrees.
- Reunion :
Fonction appelée par l'utilisateur pour réunir deux
Octrees.
- ^Octree :
Destructeur de 1'Octree.
- Affiche :
Affichage de 1'Octree.
-
ix -
-—
Annexe lb Structure "tableau"
Cette structure inclut deux objets :
+ L'octree volumique
(Octree)
+ L'octree surfacique (OctreeSurf)
Dans cette structure les pointeurs sur la parenté sont
obtenus par un calcul.
La lenteur du parcours de cette structure nécessite la
création d'une structure intermédiaire, l'octree
surfacique, dont les pointeurs sur la parenté sont
contenus dans des variables, mais n'étant plus des
adresses absolues, le stockage est plus économique.
Nous avons donc deux objets : un octree volumique et un
octree surfacique qui hérite du premier. L'Octree
surfacique étant destiné à être utilisé lors de la
représentation graphique.
Descriptif des objets Octree et OctreeSurf.
1 - Organisation de l'objet Octree
fr iend
Octree
*
operator +
(OctreeSc,
OctreeSc) ;
fr iend
Octree
*
operator *
De treeü,,
(Octrees,,
Octree&c) ;
*
VolumeV;
NbrePts;
private:
unsigned char huge
long
protected :
unsigned
unsigned
unsigned
unsigned
float
float
unsigned
unsigned
char
char
long
long
char
char
FILE
Direction
short
unsigned char
* * UniversGris;
* * UniversNoir;
*
ÑbBFils;
*
*
*
*
TUnivers;
MinAxe;
LMaille;
NMaille;
Minimal ;
Fichier ;
QuidDir
QuidDirCard
Frere
(short);
(Direction)
(unsigned char,
Direc t ion);
— x —
Direction
NouvDir
unsigned char
OpposeSurAxe
vo id
LitOctree
vo id
Rattache
vo id
Intersecte
void
Réuni
virtual
void
unsigned char
unsigned char
virtual
vo id
Compactage
QuidGr is
QuidNo ir
QuidPere
virtual
void
QuidFiIs
unsigned long
vo id
QuidTai1 le
QuidPosi tion
unsigned long
RechGris
vo id
QuidAdresse
unsigned char
unsigned char
QuidNom
EstFeuilie
(unsigned char,
Direct ion);
(unsigned char,
Direct ion);
(unsigned char,
long);
(unsigned long,
unsigned long,
Octree *,
unsigned char);
(Octree *,
Octree *,
unsigned char,
unsigned long,
unsigned long,
unsigned long);
(Octree *,
Octree *,
unsigned char,
unsigned long,
unsigned long,
unsigned long);
<);
(unsigned
unsigned
(unsigned
unsigned
char ,
long);
char,
long);
(unsigned
unsigned
unsigned
unsigned
char ,
long,
char&,
long&);
(unsigned
unsigned
unsigned
unsigned
unsigned
(unsigned
( shorts.,
shortSt,
shor t&c,
unsigned
long);
(unsigned
unsigned
(uns igned
unsigned
unsigned
(unsigned
(unsigned
unsigned
char ,
long,
char,
char&,
long&<) ;
char )
char ,
char ,
long);
long ,
long&c,
char&c) ;
long )
char,
long);
-
xi -
private:
unsigned char
CVo1
unsigned char
ValCouleur
void
Subdivise
void
PositionFils
unsigned char
void
CreerFils
CompteGris
(short,
short,
short);
(short,
short,
short,
unsigned
(unsigned
long);
<short&,
short&,
short&c,
unsigned
unsigned
(short,
short,
short,
unsigned
unsigned
(unsigned
unsigned
unsigned
long);
char,
long,
char);
long,
char);
long&,
long,
char);
public:
Octree
Octree
Octree
unsigned char
QuidCou leur
unsigned
unsigned
unsigned
float
float
unsigned
void
NbGris
QuidTUn i ver s
QuidMinimal
QuidMinAxe
QuidLMaille
QuidNMaille
Adjacent
void
void
void
vo id
long
long
char
char
Translation
Homothetie
Rotation
^Octree
Affiche
(Octree *)
(Octree *,
Octree *) ;
(short,
short*,
float*,
float*,
unsigned char huge *) ;
(unsigned char,
unsigned long);
(unsigned char )
<>S
•
<);
(unsigned char);
(unsigned c h a r ) ;
(unsigned char)
(unsigned char,
unsigned char,
unsigned long,
unsigned chari,
unsigned long&);
(float *>;
(float * ) ;
(float * ) ;
();
<);
-
x 11
-
la - Descriptif des champs de l'objet Octree
Nous ne décrirons que les champs qui diffèrent de la
version "pointeurs".
- UniversGris :
Tableau codant les cubes gris, chaque élément du tableau
est un octet qui correspond à un groupe de huit fils.
Chaque bit correspond à un fils, si le bit est à un
alors le fils est gris, sinon il est soit noir soit
blanc.
- UniversNoir ;
Ce tableau est de même structure que J.e précédent, seule
différence il code la couleur noire. Si le bit est à un
alors le fils est noir sinon il est soit blanc soit
gris.
- NbGFils :
Contient le nombre de groupes de huit fils de chaque
niveau.
- NMaille :
Contient le nombre de mailles sur chaque axe.
- Fichier :
Sert à sortir les résultats sur fichier. Cela évite des
déclarations "extern" au sein du programme puisque le
fichier fait partie intégrante de l'objet.
-
x i11
-
lb - Descriptif des méthodes de l'objet Octree
- Compactage ;
Sert à compacter 1'octree résultant d'une intersection
ou d'une réunion, en effet la place réservée par le
constructeur est plus importante que nécessaire.
- QuidGris :
Retourne le masque des gris du groupe de fils considéré.
- QuidNoir ;
Retourne le masque des noirs du groupe de fils
considéré.
- RechGri s :
Recherche le rang du cube parmi les gris du niveau.
Utilisée par QuidPère.
- Quidftdresse :
Retourne le numéro de groupe et le nom du cube de
position passée en paramètre.
- CreerFils ;
Crée les huits fils d'un HyperCube.
- CompteGris :
Compte les gris d'un niveau qui sont placés avant la
position spécifiée. Utilisée par QuidFils.
- Octree :
Constructeurs de 1'Octree. Un des trois sert à la
réalisation de la subdivision spatiale, un autre réserve
la place pour Intersection et Reunion, le dernier
réserve la place pour la création de 1'Octree
surfac ique.
- NbGris :
Retourne le nombre de gris du niveau. Il s'agit en fait
du nombre de groupe de fils du niveau suivant.
- QuidTUnivers :
Retourne la taille de la racine.
- QuidMinAxe :
Retourne le minimum sur chaque axe, c'est à dire la
position de 1'Octree dans le repère absolu.
-
x i v -
- QuidLMaille :
Retourne la largeur des mailles sur chaque axes.
- QuidNMailie :
Retourne le nombre de maille sur chaque axes.
- Les opérateurs surchargés + et * servent à l'utilisateur
en tant qu'opérateurs de réunion et d'intersection.
- xv -
S - Organisation de l'objet OctreeSurf
private:
unsigned long
unsigned long
* huge * PtrPere;
* huge * PtrFils;
void
QuidFiIs
vo id
QuidPere
vo id
Direct ion
unsigned char
Compactage
DirOpp
EstFrontiert
unsigned char
FrereBlanc
vo id
Evider
(unsigned
unsigned
unsigned
unsigned
unsigned
(unsigned
unsigned
unsigned
unsigned
char,
long,
char,
char&,
long&);
char,
long,
chari,
long&>;
•O;
(Direction) ;
(Octree*,
unsigned char,
unsigned long);
(Octree *,
Direction,
unsigned char,
unsigned long);
(Octree*,
unsigned char,
unsigned long,
uns i g ned 1o n g ) ;
pub lie:
OctreeSurf
(Octree
LancerDeRayon ( ) ;
~OctreeSurf
();
*);
-
XVI
Sa - Descriptif des champs de l'objet OctreeSurf
- PtrPere :
Contient le déplacement dans le niveau du père, ceci
permet d'accéder à la parenté.
- PtrFils :
Contient le déplacement dans le niveau du fils, ceci
permet d'accéder à la filiation.
—
xvii
—
2b — Descriptif des méthodes de l'objet OctreeSurf
- QuidFils :
Lit le champ correspondant dans le tableau PtrFils.
Diffère en cela de l'objet Octree où ceci était fait par
calcul
- QuidPere :
Lit le champ correspondant dans le tableau PtrPere.
Diffère en cela de l'objet Octree où ceci était fait par
calcul
- Compactage :
Même fonction que dans l'objet Octree.
- DirQpp :
Retourne la direction opposé à la direction paramètre.
- EstFrontiere :
Determine si un cube est frontière.
- FrereBlanc :
Détermine si dans la filiation de l'adjacent gris, il
existe un blanc accolé au cube considéré.
- Evider :
Supprime l'intérieur de 1'Octree volumique.
- OctreeSurf :
Constructeur de 1'octree surfacique, fait appel au
constructeur de 1'octree volumique qui réserve la place
pour 1'octree à partir d'un octree, puis appelle Evider.
- LancerDeRayon :
réalise un lancer de rayon.
- ^OctreeSurf :
Détruit l'objet OctreeSurf, désalloue la place occupée
par les pointeurs.
- xvLii Annexe S Résultat des fonctions
1 - Tableau de résultat de la fonction NouvOir
DCard
000
001
010
011
100
101
110
111
NaNO
NO
NaN
NaNO
NO
NaN
NO
NO
N
NaN
N
NaN
N
N
N
NaO
0
Na
0
0
FRERE
Na
FRERE
Na
FRERE
FRERE
FRERE
N
NaO
0
N
NaO
0
N
0
0
N
Na
FRERE
N
FRERE
FRERE
FRERE
NaO
0
FRERE
0
0
FRERE
Na
FRERE
FRERE
FRERE
FRERE
Na
ZNO
ZN
Na
NO
N
FRERE
ZNO
2N
Na
N
N
FRERE
ZN
ZN
Na
0
FRERE
FRERE
ZO
Z
Na
FRERE
FRERE
FRERE
Z
Z
ZO
Z
NaNE
0
FRERE
NaN
ZO
Z
N
FRERE
FRERE
NaNE
Z
Z
NE
0
FRERE
Na
ZO
FRERE
FRERE
NaE
Z
Z
E
NE
NaE
E
N
Na
FRERE
N
FRERE
FRERE
NE
NaE
E
NE
E
E
FRERE
Na
FRERE
FRERE
FRERE
FRERE
E
NaE
E
E
E
E
ZNE
ZE
NaSO
N
FRERE
NaO
ZN
Z
0
NE
E
Na
ZNE
ZE
FRERE
FRERE
FRERE
NaSO
Z
Z
SO
E
E
NaS
ZE
ZE
S
SO
NaS
S
0
Na
FRERE
0
FRERE
FRERE
FRERE
Na
FRERE
FRERE
FRERE
FRERE
SO
NaS
S
S
NaS
S
S
S
S
ZSO
ZS
NaSE
0
FRERE
Na
ZO
Z
FRERE
FRERE
FRERE
NaE
Z
Z
E
SO
S
NaS
S
S
NaSE
ZS
SE
ZSE
FRERE
FRERE
FRERE
Z
E
E
E
ZE
S
S
SE
SE
SE
ZSE
z
FRERE
so
s
s
zso
zs
s
s
zs
.. .
zs
SE
- XÏ*X
-
2 — Tableau de résultat de la fonction EstFrere
DCard
000
001
010
011
100
101
110
111
NaNO
NO
NaN
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
V
FAUX
V
FAUX
V
V
N
NaO
0
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
V
FAUX
V
V
V
FAUX
FAUX
V
FAUX
FAUX
V
FAUX
V
V
V
V
Na
ZNO
ZN
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
V
FAUX
FAUX
FAUX
FAUX
V
V
FAUX
FAUX
FAUX
V
V
FAUX
FAUX
ZO
Z
NaNE
FAUX
V
FAUX
FAUX
FAUX
FAUX
V
V
FAUX
FAUX
FAUX
FAUX
FAUX
V
FAUX
FAUX
FAUX
V
FAUX
FAUX
FAUX
FAUX
NE
NaE
E
FAUX
FAUX
V
FAUX
V
V
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
V
FAUX
V
V
V
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
ZNE
ZE
NaSO
FAUX
V
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
V
V
V
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
SO
NaS
S
FAUX
FAUX
V
FAUX
V
V
V
FAUX
V
V
V
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
ZSO
ZS
NaSE
FAUX
V
FAUX
FAUX
FAUX
V
V
V
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
SE
ZSE
V
V
V
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
FAUX
- XTT -
3 — Tableau de résultat de la fonction OpposeSurAxe
DCard
000
001
010
011
100
101
110
111
NaNO
NO
NaN
111
110
101
110
111
100
101
100
111
100
101
110
011
010
001
010
011
000
001
000
011
000
001
010
N
NaO
0
100
011
010
101
010
011
110
001
000
111
000
001
000
111
110
001
110
111
010
101
100
011
100
101
Na
ZNO
ZN
001
111
101
000
110
100
011
101
111
010
100
110
101
011
001
100
010
000
111
001
011
110
000
010
ZO
Z
NaNE
011
001
111
010
000
110
001
011
101
000
010
100
111
101
011
110
100
010
101
111
001
100
110
000
NE
NaE
E
110
011
010
111
010
011
100
001
000
101
000
001
010
111
110
011
110
111
000
101
100
001
100
101
ZNE
ZE
NaSO
111
011
111
1 10
010
110
101
001
101
100
000
100
011
111
011
010
110
010
001
101
001
000
100
000
SO
NaS
S
110
101
100
111
100
101
100
111
110
101
110
111
010
001
000
011
000
001
000
011
010
001
010
011
ZSO
ZS
NaSE
111
101
111
110
100
110
101
111
101
100
110
100
011
001
011
010
000
010
001
011
001
000
010
000
SE
ZSE
110
111
111
1 10
100
101
101
100
010
011
011
010
000
001
001
000
Téléchargement