Cours 9 : Introduction à la 3D
Vincent Guigue
UPMC - LIP6
Stratégies complexes : plusieurs solutions
1
Composite : Liste de Selector/Strategy
- Composite dans Composite = Arbre de strategy
- Partage d’informations entre Selector et Strategy : 1 objet implémente les 2 interfaces (attributs communs)
2
Héritage : une stratégie fille plus fine que la stratégie parente - getCommande() = parent.getCommande() + spécificités
classe fille
3
Decorator/Délégation : une Strategy attribut d’une autre - Comportement partiel (ex : donner une accélération franche
lorsque la vitesse de la voiture est à 0) - Surcouche sur n’importe quelle stratégie - Fonctionnement :
·
Possède une stratégie en attribut
·
Renvoie tous les ordres vers l’attribut (Délégation)
·
Fait quelques modifications dans certains cas particuliers
Intérêt et Usage de la décoration
◦ Une stratégie décorée EST UNE stratégie
◦ Pouvoir étendre/spécialiser n’importe quelle stratégie (plus général que l’héritage)
Forme générale :
1 p u b l i c c l a s s S t r a t e g y P r u d e n t e imp leme nts S t r a t e g y {
2 p r i v a t e S t r a t e g y s B a s e ;
3
4 p u b l i c S t r a t e g y P r u d e n t e ( S t r a t e g y s B a s e ) {
5 s u p e r( ) ;
6 t h i s. s B a s e = s B a s e ;
7 }
8
9 p u b l i c Commande getCommande ( ) {
10 Commande c = s B a s e . getCommande ( ) ; // d é l é g a t i o n
11 // m o d i f i c a t i o n de c
12 // [ . . . ]
13
14 r e t u r n c ;
15 }
16 }
Rappel sur les filtres
◦ Filtre = cahier des charges = interface
1 p u b l i c v o i d f i l t r e ( T e r r a i n [ ] [ ] mat )
◦ Les filtres parcourent et modifient la matrice Terrain[][]
◦ La CircuitFactory change (ou il en faut une nouvelle) - Aucune méthode static (l’appel depuis le main change aussi) - La classe a un attribut ArrayList<Filtre> instancié dans le
constructeur
- La classe contient une méthode void add(Filtre f) - Avant de construire le CircuitImpl, la classe applique les
filtres sur la matrice Terrain[][]
1 f o r( F i l t r e f : l i s t e )
2 f . f i l t r e ( mat ) ;
Filtre simple
Dans la version simple, un filtre est rapide à développer :
◦ Pas d’attribut
◦ Pas de constructeur (Implicite)
1 p u b l i c c l a s s F i l t r e D i a g impleme nts F i l t r e {
2
3 p u b l i c v o i d f i l t r e ( T e r r a i n [ ] [ ] mat ) {
4 f o r(i n t i =0; i <mat . l e n g t h-1; i ++)
5 f o r(i n t j =0; i <mat [ 0 ] . l e n g t h-1; j ++){
6 i f( [ QUADRUPLE CLAUSE ] ) {
7 mat [ i ] [ j ] = T e r r a i n . H e r b e ;
8 mat [ i + 1 ] [ j +1] = T e r r a i n . H e r b e ;
9 }
10 e l s e i f( [ QUADRUPLE CLAUSE ] ) {
11 mat [ i + 1 ] [ j ] = T e r r a i n . H e r b e ;
12 mat [ i ] [ j +1] = T e r r a i n . H e r b e ;
13 }
14 }
15 }
16 }
Filtre générique
◦ Détection d’un pattern (Utiliser isRunnable, ⇒ filtre booléen)
◦ Remplacement
...
...
...
Proposition de codage
1 p u b l i c c l a s s F i l t r e G e n e r i q u e imp leme nts F i l t r e {
2 p r i v a t e b o o l e a n[ ] [ ] window ;
3 p u b l i c F i l t r e G e n e r i q u e (b o o l e a n[ ] [ ] window ) {t h i s. window = window ; }
4
5 p u b l i c v o i d f i l t r e ( T e r r a i n [ ] [ ] mat ) {
6 f o r(i n t i =0; i <mat . l e n g t h−window . l e n g t h−1; i ++)
7 f o r(i n t j =0; i <mat [ 0 ] . l e n g t h−window [ i ] . l e n g t h−1; j ++){
8 i f( m a t c h i n g ( mat , i , j ) ) { // t e s t
9 f o r(i n t m=0; m<window . l e n g t h ; m++)
10 f o r(i n t n =0; n<window [ 0 ] . l e n g t h ; n++)
11 mat [ i +m ] [ j+n ] = T e r r a i n . H e r b e ; // r e m p l a c e m e n t
12 }
13 }
14 }
15
16 p r i v a t e b o o l e a n m a t c h i n g ( T e r r a i n [ ] [ ] mat , i n t i , i n t j ) {
17 f o r(i n t m=0; m<window . l e n g t h ; m++)
18 f o r(i n t n =0; n<window [ 0 ] . l e n g t h ; n++)
19 i f( T o o l s T e r r a i n . i s R u n n a b l e ( mat [ i +m ] [ j+n ] ) != window [m ] [ n ] )
20 r e t u r n f a l s e;
21 r e t u r n t r u e;
22 }
23 }
Rappels sur l’évaluation
◦ CC : 70%
- Partiel (0.25) : Annales en ligne + cours 9 1er avril 10h45-12h30 (et ce n’est pas une blague)
·
Sur feuille, vérification de la maitrise du projet
·
Développement propre de nouvelles fonctions/strategy - Rapport et performance de votre code (binôme) (0.6)
·
Nombre de fonctionnalités développées (Strategy, Optimisation, IHM)
·
Propreté du code
·
Performance des stratégies (bonus/malus dans la compétition) - Participation (0.15) : retard/présence, jalons manqués
◦ Exam : 30%
- Soutenances orale et modification de code individuel
Exam le 15/04, Soutenances le 17/04
Quelques explications sur le fonctionnement
◦ Slides en partie tirés du cours de A. Meyer, Lyon 1
◦ Beaucoup de calcul matriciel (d’où les nouveaux usages des
cartes graphiques)
Cours de synthèse d’images 4
2 approches duales en SI
Impossible d'a!cher l'image. Votre ordinateur manque peut-être de mémoire pour ouvrir l'image ou l'image est endommagée.
Redémarrez l'ordinateur, puis ouvrez à nouveau le fichier. Si le x rouge est Impossible d'a!cher l'image. Votre ordinateur
Oeil Image
(pixels)
Impossible d'a!cher l'image. Votre ordinateur manque peut-être de mémoire pour ouvrir l'image ou l'image est endommagée.
Redémarrez l'ordinateur, puis ouvrez à nouveau le fichier. Si le x rouge est Impossible d'a!cher l'image. Votre ordinateur
Oeil Image
(pixels)
Des rayons sont lancés depuis l’œil vers la scène
en passant par un pixel
Les objets sont projetés sur l’écran dans la direction de l’œil.
Ray-tracing
•!Image réaliste
•!Lent
Rendu projectif
(cablé sur les cartes graphiques modernes -> temps réel)Cours de synthèse d’images 6
Pipeline
1. Clipping des polygones en 3D suivant la pyramide de vue 2. Projection des points sur le plan image
3.! Remplissage des triangles (Rasterizing) dans l’image a.! Suppression des parties cachées : Z-Buffer b.! Calcul de la couleur : illumination
Ap
oeil
Plan image
A
Rendu projectif : PIPELINE
Cours de synthèse d’images 19
Projection perspective
!! Besoin de perspective
!! Configuration simple :
CDP
Q
P(x,y,z)
O A
Plan image -Z Y
d
Si et
C
d=distance focale
Cours de synthèse d’images 20
Matrice de projection : M I!C
!!
Soit un point dans l’espace de la camera
!!
Résultat : un point dans l’espace Image
Cours de synthèse d’images 42
1. Projection des points sur le plan image 2. Clipping
3.! Remplissage des triangles (rasterisation) dans l’image 5.! Suppression des parties cachées
6.! Calcul de la couleur : illumination Ap
CDP
Plan image (viewport)
d
hl
A
Rendu projectif
Cours de synthèse d’images 49
1ere idée : algo du peintre
Ambiguïtés
Cours de synthèse d’images 56
12 13 14 11 12 12 13 10 12 12 13 10 10 11 12
5 4
Z-Buffer
+inf +inf +inf +inf +inf +inf +inf +inf +inf +inf +inf +inf +inf +inf 4 4 4 +inf +inf +inf +inf +inf +inf +inf +inf +inf 4 4 5 5 5 +inf +inf +inf +inf +inf +inf 4 4 5 5 5 +inf +inf +inf +inf
+inf +inf +inf 3 3 4 4 +inf +inf
+inf +inf +inf 3 3 3 +inf +inf
+inf +inf +inf +inf 3 +inf +inf +inf +inf +inf +inf +inf +inf +inf +inf +inf
4 5
z=11>5 donc caché
Cours de synthèse d’images 64
OpenGL : par exemple
!!
Effacer le buffer et le zbuffer entre chaque image
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
!!
Active le test des Z avec le Z-buffer
glEnable(GL_DEPTH_TEST) ;
activé
non
activé
JAVA et 3D
◦ On propose d’utiliser lwjGL - http://lwjgl.org/
◦ La puissance de l’architecture vient du fait qu’il n’y a pas grand chose à modifier pour faire de la 3D...
◦ Le modèle ne change pas, seule la manière de l’afficher est modifiée.
◦ IHMSwing devient
- public class IHM3D extends AWTGLCanvas
- void paint(Graphics g) devient public void paintGL()
Coté main...
... pas de modification ! (logique on a prévu ce cas figure dans le MVC)
1 S i m u l a t i o n s i m u = new S i m u l a t i o n ( t r a c k , v , s t r a t e g y ) ;
2
3 JFrame f e n = new JFrame ( ) ;
4 f e n . s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT_ON_CLOSE ) ;
5 IHM3D ihm = new IHM3D ( ) ;
6
7 s i m u . add ( ihm ) ;
Qu’est ce qu’une IHM3D ?
◦ Proposition : utiliser le AWTGLCanvas qui ouvre un panel OpenGL dans l’univers SWING
1 p u b l i c c l a s s IHM3D e x t e n d s AWTGLCanvas
2 implements K e y L i s t e n e r , U p d a t e E v e n t L i s t e n e r {
3 p r i v a t e A r r a y L i s t <O b s e r v e u r 3 D > toDraw ;
4
5 p u b l i c IHM3D ( ) t h r o w s LWJGLException {
6 toDraw = new A r r a y L i s t <O b s e r v e u r 3 D > ( ) ;
7 t h i s. a d d K e y L i s t e n e r (t h i s) ; // j e m ’ a u t o−e c o u t e p o u r l e s t o u c h e s
8 }
9 p u b l i c v o i d p a i n t G L ( ) {
10 // s u r c h a r g e
11 }
12 p u b l i c v o i d add ( O b s e r v e u r 3 D d ) { toDraw . add ( d ) ; }
13 p u b l i c v o i d k e y P r e s s e d ( K e y E v e n t e ) {}
14 p u b l i c v o i d k e y R e l e a s e d ( K e y E v e n t e ) {}
15 p u b l i c v o i d k e y T y p e d ( K e y E v e n t e ) { }
16
17 p u b l i c v o i d manageUpdate ( ) {}
18 }
Spécificités de la 3D
◦ Pas de mise à jour explicite : la 3D se refraichît en boucle
◦ Nouveaux observeurs :
1 p u b l i c i n t e r f a c e O b s e r v e u r 3 D {
2 p u b l i c v o i d drawGL ( ) ;
3 }
◦ Beaucoup de paramètres à régler pour l’affichage : - Surcharge de l’initialisation (AWTGLCanvas ) :
1 p r o t e c t e d v o i d i n i t G L ( ) {
2 g l E n a b l e (GL_TEXTURE_2D ) ; // a c t i v a t i o n d e s t e x t u r e s
3 g l E n a b l e (GL_DEPTH_TEST ) ; // g e s t i o n de l a p r o f o n d e u r
4 }
- Dans paintGL() ... On appelle glsettings()
PaintGL
◦ RAZ du buffer
◦ Définition d’une scène
1 p r i v a t e v o i d g l s e t t i n g s ( ) {
2 g l C l e a r (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
3 g l V i e w p o r t ( 0 , 0 , g e t W i d t h ( ) , g e t H e i g h t ( ) ) ;// 100% de l a f e n ê t r e
4 g l C l e a r C o l o r ( 0 . f , 0 . f , 0 . f , 1 . 0 f ) ;
5 g l M a t r i x M o d e (GL_PROJECTION ) ;
6
7 g l L o a d I d e n t i t y ( ) ; // RAZ t r a n s f o r m a t i o n s
8
9 // d e f i n i t i o n de l a t a i l l e de l a f e n e t r e 3D où l ’ on r e g a r d e
10
11 g l O r t h o ( (f l o a t) −g e t W i d t h ( )∗zoom , (f l o a t) g e t W i d t h ( )∗zoom ,
12 (f l o a t) −g e t H e i g h t ( )∗zoom∗0 . 5 , (f l o a t) g e t H e i g h t ( )∗zoom∗1 . 5 , −2000 , 2 0 0 0 ) ;
13
14 g l M a t r i x M o d e (GL_MODELVIEW ) ;
15 . . .
Définition de la fenêtre
PaintGL
◦ Définition des lumières/matériaux
1 p r i v a t e v o i d g l s e t t i n g s ( ) {
2 [ . . . ]
3 i n i t L i g h t A r r a y s ( ) ; // c o d e f o u r n i s u r l e s i t e web
4
5 g l S h a d e M o d e l (GL_SMOOTH ) ; // mode de r e n d u
6
7 g l M a t e r i a l (GL_FRONT, GL_SPECULAR , m a t S p e c u l a r ) ;
8 g l M a t e r i a l f (GL_FRONT, GL_SHININESS , 5 0 . 0 f ) ;
9
10 g l L i g h t ( GL_LIGHT0 , GL_POSITION , l i g h t P o s i t i o n ) ;
11 g l L i g h t ( GL_LIGHT0 , GL_SPECULAR , w h i t e L i g h t ) ;
12 g l L i g h t ( GL_LIGHT0 , GL_DIFFUSE , w h i t e L i g h t ) ;
13 g l L i g h t M o d e l (GL_LIGHT_MODEL_AMBIENT, l M o d e l A m b i e n t ) ;
14
15 g l E n a b l e ( GL_LIGHTING ) ; // a c t i v a t i o n
16 g l E n a b l e ( GL_LIGHT0 ) ;
17 g l E n a b l e (GL_COLOR_MATERIAL ) ;
18 g l C o l o r M a t e r i a l (GL_FRONT, GL_AMBIENT_AND_DIFFUSE ) ;
19
20 g l L o a d I d e n t i t y ( ) ;
Modes de rendu
Synthè!"#$%&'()"! 6 Texture
Fil de fer Faces cachées (objet) Rendu Gouraud
Rendu Phong
Historique
PaintGL
◦ Et enfin... On peut dessiner !
1 p u b l i c v o i d p a i n t G L ( ) {
2 t r y {
3 g l s e t t i n g s ( ) ;
4 // d é f i n i t i o n de l a c a m e r a
5 GLU . g l u L o o k A t ( x , y , z , 5 0 0 , 5 0 0 , −500 , 0 , 0 , 1 ) ;
6 // MVC c l a s s i q u e
7 f o r( O b s e r v e u r 3 D d : toDraw ) {
8 g l P u s h M a t r i x ( ) ;
9 d . drawGL ( ) ;
10 g l P o p M a t r i x ( ) ;
11 }
12 s w a p B u f f e r s ( ) ;
13
14 r e p a i n t ( ) ;
15 } c a t c h ( LWJGLException e ) {throw new R u n t i m e E x c e p t i o n ( e ) ; }
16 }
Fonctionnement de la caméra :
1 G L v o i d g l u L o o k A t ( G L d o u b l e e y e x , G L d o u b l e e y e y ,
2 G L d o u b l e e y e z , G L d o u b l e c e n t e r x , G L d o u b l e
3 c e n t e r y , G L d o u b l e c e n t e r z , G L d o u b l e upx ,
4 G L d o u b l e upy , G L d o u b l e upz )
Rendre un objet en 3D
Dans l’idée, c’est simple : on multiplie les dessins de formes basiques (triangle/carré) dans l’espace :
Sur un exemple dans :
1
2 p u b l i c c l a s s C i r c u i t O b s e r v e u r 3 D im pleme nts O b s e r v e u r 3 D {
3 [ . . . ]
4
5 p u b l i c v o i d drawGL ( ) {
6
7 GL11 . g l B e g i n ( GL11 . GL_QUADS ) ;
8 {
9 GL11 . g l V e r t e x 3 f ( 0 , 0 , 0 ) ;
10 GL11 . g l V e r t e x 3 f ( 0 , h e i g h t R , 0 ) ;
11 GL11 . g l V e r t e x 3 f ( widthR , h e i g h t R , 0 ) ;
12 GL11 . g l V e r t e x 3 f ( widthR , 0 , 0 ) ;
13 }
14 GL11 . g l E n d ( ) ;
15 }
Utilisation de volumes préfédinis
Dessiner la voiture sous forme de sphère est assez simple :
1 p u b l i c c l a s s V o i t u r e O b s e r v e u r 3 D im pleme nts O b s e r v e u r 3 D {
2 p r i v a t e o r g . l w j g l . u t i l . g l u . S p h e r e s p h e r e = new S p h e r e ( ) ;
3 p r i v a t e V o i t u r e v o i t u r e ;
4
5 p u b l i c V o i t u r e O b s e r v e u r 3 D ( V o i t u r e v o i t u r e ) {
6 t h i s. v o i t u r e = v o i t u r e ;
7 }
8
9 p u b l i c f l o a t g e t X ( ) {r e t u r n (f l o a t) v o i t u r e . g e t P o s i t i o n ( ) . g e t X ( ) ; }
10 p u b l i c f l o a t g e t Y ( ) {r e t u r n (f l o a t) v o i t u r e . g e t P o s i t i o n ( ) . g e t Y ( ) ; }
11
12 p u b l i c v o i d drawGL ( ) {
13 g l C o l o r 3 f ( 1 , 0 , 1 ) ; // c o d e RGB e n t r e 0 e t 1
14 g l T r a n s l a t e f ( ge t X ( ) , g e t Y ( ) , 0 ) ;
15 s p h e r e . draw ( 2 0 , 1 0 , 1 0 ) ; // r a y o n + r é s o l u t i o n
16 g l T r a n s l a t e f (−g e t X ( ) , −g e t Y ( ) , 0 ) ;
17 g l C o l o r 3 f ( 1 , 1 , 1 ) ;
18 }
19 }
Textures
Pour des rendus plus agréables et pour le terrain, il faut gérer les images en plus de la 3D :
5
Plaquage de la texture
!
A chaque sommet de la face
! Coordonnées textures (u,v)
! *+,-.#/011"!203$#4#+3"#20!&5&03#$(3!#6%&'()"#*$(3!#6(#5"75+1".
!"#$%"&'
()*%'+,'-,./'
0-
12$
123
1450.
126
14
0-
72$
723
7450.
726
74
(0,0)
(1,1) (0,1)
(1,0)
Vincent Guigue 2i013 - Course de Voiture 23/45
Texture : application sur le circuit
◦ La classe possède un attribut Texture
◦ Une texture est stockée dans la mémoire graphique et possède un identifiant
◦ Texture = contrainte : souvent des images carrées, toujours en puissance de 2
1 p u b l i c v o i d drawGL ( ) {
2 // c h a r g e m e n t l o r s du p r e m i e r a p p e l
3 i f( t e x t u r e == n u l l) {
4 B u f f e r e d I m a g e im = T o o l s T e r r a i n . i m a g e F r o m C i r c u i t ( t r a c k ) ; // c r e a t i o n
5 t r y {
6 I m a g e I O . w r i t e ( im , "PNG", new F i l e (" t e r r a i n . png ") ) ;
7 t e x t u r e = T e x t u r e L o a d e r . g e t T e x t u r e ("PNG", R e s o u r c e L o a d e r . g e t R e s o u r c e A s S t r e a m (" t e r r a i n . png ") ) ;
8 } c a t c h ( I O E x c e p t i o n e ) {
9 e . p r i n t S t a c k T r a c e ( ) ;
10 }
11 w i d t h = t e x t u r e . g e t T e x t u r e W i d t h ( ) ;
12 h e i g h t = t e x t u r e . g e t T e x t u r e H e i g h t ( ) ;
13 }
14 . . .
Texture : application sur le circuit (suite)
1 . . .
2 GL11 . g l B i n d T e x t u r e ( GL11 . GL_TEXTURE_2D, t e x t u r e . g e t T e x t u r e I D ( ) ) ;
3 GL11 . g l P i x e l S t o r e i ( GL11 . GL_UNPACK_ALIGNMENT, 1 ) ;
4
5 // draw a quad t e x t u r e d t o match t h e s p r i t e
6 GL11 . g l B e g i n ( GL11 . GL_QUADS ) ;
7 {
8 GL11 . g l T e x C o o r d 2 f ( 0 , 0 ) ; GL11 . g l V e r t e x 3 f ( 0 , 0 , 0 ) ;
9 GL11 . g l T e x C o o r d 2 f ( 0 , 1 ) ; GL11 . g l V e r t e x 3 f ( 0 , h e i g h t , 0 ) ;
10 GL11 . g l T e x C o o r d 2 f ( 1 , 1 ) ; GL11 . g l V e r t e x 3 f ( w i d t h , h e i g h t , 0 ) ;
11 GL11 . g l T e x C o o r d 2 f ( 1 , 0 ) ; GL11 . g l V e r t e x 3 f ( w i d t h , 0 , 0 ) ;
12 }
13 GL11 . g l E n d ( ) ;
14 GL11 . g l B i n d T e x t u r e ( GL11 . GL_TEXTURE_2D, 0 ) ;
15 16 }
Exemple de résultat
Exemples de circuit d’examen
Gestion d’un labyrinthe :
Exemples de circuit d’examen
Gestion d’un nouveau type de terrain :
Exemples de circuit d’examen
Jouer un circuit de 2 manières
Circuit mystère
◦ Construire un circuit mystère à partir d’un algorithme, par exemple :
- 500x500 pixels, bordure d’herbe de 10 pixels - Départ en ... Arrivée en ...
- ...
Questions
◦ Dans quel objet le développer ?
◦ Implémenter l’algorithme
Strategy 3D Implem. Observeurs Examen Partiel Personnalisations Exercice 3 – Circuit analytique myst`ere (6 pts)
Nous proposons dans cet exercice de construire un circuit de mani`ere analytique, en respectant `a la lettre l’algorithme fourni ci-dessous. Vous cr´eerez la classeCircuitFactoryFromAlgo, sans argument.
Attributs/Constructeur :
Dans le constructeur, vous initialiserez les attributsint sizeX=600 ; int sizeY=600 ; int bordure=20 ;La classe poss`ede ´egalement les attributs :
private Vecteur depart;
private Vecteur dirDepart = new Vecteur(0,1); // comme d’habitude private Vecteur dirArrivee = new Vecteur(0,1); // comme d’habitude M´ethode build :
Dans la m´ethodepublic Circuit build()de cette classe, on commencera par instancier un tableautrackde Terrain de 600x600 cases.
Goudron partout sauf sur les bords :
En parcourant toutes les cases `a l’aide d’une double boucle for, vous mettrez toutes les cases enRoute, sauf les cases dont l’une des coordonn´ees est inf´erieure `a bordure ou sup´erieure `a sizeX/Y-bordure.
D´epart :
Le point de d´epart se situe en (bordure+10, bordure+10). Mettez `a jour la matrice de Terrain ainsi que l’attribut departde la classe.
Arriv´ee :
La ligne d’arriv´ee est d´efinie par le code suivant : for(int i= 0; i<20; i++){
track[300-i][300] = Terrain.EndLine;
}
Coeur du circuit : D´efinition de double : a=0, b=1 D´efinition de int : nbPas = 10000 Pour i allant de 1 `a nbPas faire : –✓=nbP asi⇡10
NB :⇡est d´efini dans Math.PI. Suivant votre impl´ementation du calcul, il faut mieux convertir nbPas en double pour ´eviter les probl`emes de division.
–⇢=a✓+b;
–x=⇢cos(✓)8 + 300
NB : x doit ˆetre un entier, il faut donc convertir le r´esultat ci-dessus `a l’aide de (int).
–y=⇢⇤sin(✓)8 + 300 (mˆeme conversion en int)
– Ajouter le code suivant pour convertir les cases autour de (x,y) en herbe : track[x][y] = Terrain.Herbe;
for(int j=0; j<2; j++){
track[x+j][y] = Terrain.Herbe;
track[x][y+j] = Terrain.Herbe;
} Retour :
return new CircuitImpl(track, depart, dirDepart, dirArrivee) ;
Q 3.1Cr´eer ce circuit, jouer le et sauver le r´esultat dans les fichiersVincent Guigue 2i013 - Course de Voituremystere.com/mystere.png 29/45
Départ manuel
Héritage vs Décoration
1 p u b l i c i n t e r f a c e C i r c u i t {
2 p u b l i c d o u b l e g e t D i s t (i n t i , i n t j ) ; // Pour i n t e r r o g e r d i j k s t r a
3 p u b l i c T e r r a i n g e t T e r r a i n (i n t i , i n t j ) ;
4 p u b l i c T e r r a i n g e t T e r r a i n ( V e c t e u r v ) ;
5 p u b l i c V e c t e u r g e t P o i n t D e p a r t ( ) ;
6 p u b l i c V e c t e u r g e t D i r e c t i o n D e p a r t ( ) ;
7 p u b l i c V e c t e u r g e t D i r e c t i o n A r r i v e e ( ) ;
8 p u b l i c i n t g e t W i d t h ( ) ;
9 p u b l i c i n t g e t H e i g h t ( ) ;
10 p u b l i c A r r a y L i s t <V e c t e u r > g e t A r r i v e e s ( ) ;
11 }
◦ On veut créer un système générique pour ajouter des obstacles dans le circuit (possibilité d’ajouter des obstacles rectangles, ronds...).
◦ Un obstacle permettra donc de coder la définition d’un zone de l’espace (pour une coordonnée il est nécessaire de savoir si on est sur l’obstacle ou pas).
◦ On construira ensuite une nouvelle implémentation de circuit gérant
les obstacles.
Obstacle
1
Cahier des charges
Qu’est qu’un obstacle du point de vue du cahier des charges ? (expliquer en une ou deux phrases) Utiliseriez vous une interface ou une classe abstraite pour l’implémenter ? (expliquer en une ou deux phrases) Donner le code de la classe/interface Obstacle.
2
Concrétisation
Donner le code d’un obstacle rectangle et d’un obstacle rond
(en accord avec la question précédente).
Prise en compte des obstacles dans le Circuit
L’idée de base est simple : on veut prendre en compte les obstacles sans changer le code de la classe circuit On souhaite pouvoir ajouter plusieurs obstacles (nombre indéterminé) de n’importe quel type (rectangle, rond ou autres définis dans le futur).
1
Par héritage
Donner le code de la classe CircuitAvecObstacleHeritage qui implémente l’idée ci-dessus en utilisant l’héritage.
2
Par décoration
Donner le code de la classe CircuitAvecObstacleDecoration qui réalise exactement les mêmes opérations que dans la question précédente mais en prenant un attribut Circuit à décorer.
3
Exemples d’usage
Approfondissement
1
Réflexions sur les deux solutions
Quels sont les avantages et inconvénient des deux solutions ? Pistes de réponse : - comparer le type de l’objet qui est étendu par héritage avec le type de l’attribut qui est décoré dans la seconde solution. - comparer comment sont instanciés les deux objets. - comparer le nombre d’indirection (c’est à dire le nombre d’appels de fonctions pour effectuer une même opération dans les deux
architectures).
2
Pérénisation : sauvegarde/chargement
Quels sont les enjeux et les choix à faire au niveau de la
sauvegarde des circuits avec obstacles ? Proposer une ou
plusieurs architecture de sauvegarde chargement des circuits
avec obstacles.
Algorithmique : radar parabolique
Prédiction Réglage de l’avance
Mesure de la force du virage à venir (x_max,y_max)
35 30 25 20 15 10 5 0 40
−20 −10 0 10 20
0 5 10 15 20 25 30 35 40
-25 -20 -15 -10 -5 0
Les faisceaux ont pour équation y = ax
2+ bx + c . Le paramétrage du radar se fait en donnant :
◦ y
max: la hauteur du maximum (y
max= 40)
◦ x
max: la déviation en x du point max de la parabole (x
maxprend les valeurs :
[ − 12.5, − 10, − 7.5, − 5, 5, 7.5, 10, 12.5]).
Les équations des faisceaux correspondent à :
b = 2y
max/x
max, a = − b/(2x
max), c = 0.
Algorithme d’analyse sur un faisceau : A partir de la position et de la direction de la voiture, nous voulons extraire les coordonnées de 100 points répartis le long d’un faisceau.
On calcule 100 valeurs de x entre 0 et 2x
max. Pour chaque valeur, on calcule la valeur y associée. Il faut ensuite faire un changement de repère pour obtenir des coordonnées dans l’espace du circuit.
◦ Calculer l’angle α entre la direction de la voiture et la direction (0, 1). Vous supposerez que vous disposez de la fonction adéquat, soit dans la classe Vecteur, soit dans une classe Tools.
◦ Appliquer une rotation α sur les coordonnées (x , y).
◦ Appliquer la translation suivante : x ← x + voiture.x, y ← y + voiture.y
Une fois les points dans le bon espace, l’algorithme est très proche
du radar Dijkstra : on parcours les points tant que l’on n’est pas
dans l’herbe et on note le score le plus intéressant.
Implémentation
1
Quels sont les attributs du radar parabolique ?
2
Donner la signature du constructeur ainsi qu’un exemple de construction d’un tel radar depuis le main.
3
Donner le code de la méthode double
scoreFaisceau(double xmax) qui prend en argument xmax et qui retourne le meilleur score dijkstra rencontré.
NB1 :ymaxdevra évidemment être accessible, ainsi que les données de la voiture.
NB2 : question (un peu) difficile qui nécessite sans doute un peu de réflexion au brouillon.
NB3 : on partira de x=0 pour aller vers xmax. Si on rencontre de l’herbe, on s’arrête.
NB4 : il peut être utile de coder le changement de repère dans une méthode privée à part pour faciliter la lecture du code.
4
Donner le reste du code de la classe RadarParabolique.
NB1 : vous pourrez choisir de faire de l’héritage par rapport au radar classique ou pas.
NB2 : vous mettrez quelques commentaires pour que je m’y retrouve si vous faites appel à des méthodes/attributs issus de la classe mère
1 p u b l i c i n t e r f a c e R a d a r {
2 p u b l i c d o u b l e[ ] s c o r e s ( ) ; // s c o r e de c h a q u e b r a n c h e
3 p u b l i c d o u b l e[ ] d i s t a n c e s I n P i x e l s ( ) ; // p o u r l ’ o b s e r v e r
4 p u b l i c i n t g e t B e s t I n d e x ( ) ; // m e i l l e u r i n d i c e
5 p u b l i c d o u b l e[ ] t h e t a s ( ) ; // a n g l e s de c h a q u e f a i s c e a u
6 }
Approfondissement
1
Observation
Proposer une technique d’observation du radar parabolique.
Expliquer votre approche en quelques phrases. S’il vous reste du temps à la fin, proposez un code réalisant l’opération.
2
Stratégie
Proposer une stratégie à partir du radar parabolique (en quelques phrases, pas de code).
NB : vous pouvez évidemment ajouter d’autres radars.
3