Univers de murs et arbre BSP



Documents pareils
Petite initiation au langage C et au graphisme SDL

Les arbres binaires de recherche

Les structures de données. Rajae El Ouazzani

Deux disques dans un carré

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

V- Manipulations de nombres en binaire

Séquence 2. Repérage dans le plan Équations de droites. Sommaire

Nombres complexes. cours, exercices corrigés, programmation

III- Raisonnement par récurrence

Fonctions de deux variables. Mai 2011

Les algorithmes de base du graphisme

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

I. Introduction aux fonctions : les fonctions standards

chapitre 4 Nombres de Catalan

1 radian. De même, la longueur d un arc de cercle de rayon R et dont l angle au centre a pour mesure α radians est α R. R AB =R.

Activités numériques [13 Points]

Chapitre 2 : Caractéristiques du mouvement d un solide

Réalisation de cartes vectorielles avec Word

Découverte du logiciel ordinateur TI-n spire / TI-n spire CAS

Les Angles. I) Angles complémentaires, angles supplémentaires. 1) Angles complémentaires. 2 Angles supplémentaires. a) Définition.

1S Modèles de rédaction Enoncés

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Compression de Données - Algorithme de Huffman Document de Conception

I00 Éléments d architecture

Algorithmique et Programmation, IMA

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

STAGE IREM 0- Premiers pas en Python

Les droites (d 1 ) et (d 2 ) sont sécantes en A Le point A est le point d intersection des 2 droites

Correction du Baccalauréat S Amérique du Nord mai 2007

Formats d images. 1 Introduction

Arbres binaires de recherche

Enoncé et corrigé du brevet des collèges dans les académies d Aix- Marseille, Montpellier, Nice Corse et Toulouse en Énoncé.

point On obtient ainsi le ou les points d inter- entre deux objets».

Initiation à l algorithmique

Algorithmique I. Algorithmique I p.1/??

Algorithmique, Structures de données et langage C

Items étudiés dans le CHAPITRE N5. 7 et 9 p 129 D14 Déterminer par le calcul l'antécédent d'un nombre par une fonction linéaire

Quelques Algorithmes simples

Exo7. Calculs de déterminants. Fiche corrigée par Arnaud Bodin. Exercice 1 Calculer les déterminants des matrices suivantes : Exercice 2.

Programmation Classique en langage C

#include <stdio.h> #include <stdlib.h> struct cell { int clef; struct cell *suiv; };

Durée de L épreuve : 2 heures. Barème : Exercice n 4 : 1 ) 1 point 2 ) 2 points 3 ) 1 point

Représentation d un entier en base b


AC AB. A B C x 1. x + 1. d où. Avec un calcul vu au lycée, on démontre que cette solution admet deux solutions dont une seule nous intéresse : x =

Introduction au maillage pour le calcul scientifique


Exercices - Nombres complexes : corrigé. Formes algébriques et trigonométriques, module et argument

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Bases de programmation. Cours 5. Structurer les données

Cours 7 : Utilisation de modules sous python

MINIMUM. connaissances nécessaires à la programmation des microcontrôleurs PIC18 en langage C (une introduction au langage c A.N.S.

Vision industrielle et télédétection - Détection d ellipses. Guillaume Martinez 17 décembre 2007

Sujet proposé par Yves M. LEROY. Cet examen se compose d un exercice et de deux problèmes. Ces trois parties sont indépendantes.

Simulation de variables aléatoires

ARBRES BINAIRES DE RECHERCHE

Exprimer ce coefficient de proportionnalité sous forme de pourcentage : 3,5 %

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

5 ème Chapitre 4 Triangles

Note de cours. Introduction à Excel 2007

Quelques contrôle de Première S

CONJUGUÉ D'UN POINT PAR RAPPORT À UN TRIANGLE

Cours d initiation à la programmation en C++ Johann Cuenin

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

Reconstruction de bâtiments en 3D à partir de nuages de points LIDAR

Mon premier rpm. 7 juin Avant de commencer RPM URPMI RPMBUILD... 2

«Aucune investigation humaine ne peut être qualifiée de science véritable si elle ne peut être démontrée mathématiquement.

1 Définition. 2 Systèmes matériels et solides. 3 Les actions mécaniques. Le système matériel : Il peut être un ensemble.un sous-ensemble..

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

1) Information sur le logiciel et la notice 2) Le tableau de bord 3) Les devis 4) Les factures 5) Les factures d acompte 6) Les avoirs sur facture

La fonction exponentielle

Leçon N 4 : Statistiques à deux variables

1.6- Génération de nombres aléatoires

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

PROGRAMME D HABILETÉS EN FAUTEUIL ROULANT (WSP-F)

Angles orientés et fonctions circulaires ( En première S )

Problèmes de dénombrement.

Corrigé du baccalauréat S Pondichéry 12 avril 2007

Seconde Généralités sur les fonctions Exercices. Notion de fonction.

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

COMPTE-RENDU «MATHS EN JEANS» LYCEE OZENNE Groupe 1 : Comment faire une carte juste de la Terre?

Cours 1 : Qu est-ce que la programmation?

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Chapitre 4 : Guide de Mouvement et Masque

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

L ALGORITHMIQUE. Algorithme

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Cours Programmation Système

DURÉE DU JOUR EN FONCTION DE LA DATE ET DE LA LATITUDE

Synthèse d'images I. Venceslas BIRI IGM Université de Marne La

Le théorème de Thalès et sa réciproque

AGASC / BUREAU INFORMATION JEUNESSE Saint Laurent du Var Tel : bij@agasc.fr Word: Les tableaux.

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Les chaînes de caractères

Le prototype de la fonction main()

Recherche dans un tableau

Solutions du chapitre 4

Présentation du langage et premières fonctions

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Transcription:

1 Univers de murs et arbre BSP Le contexte Plaçons-nous nous dans le cas simple où le paysage est constitué de plusieurs murs rectilignes posés sur le sol et que l on regarde en leur faisant face. Il s agit principalement d un problème en deux dimensions. L objectif est de dessiner les parties de murs visibles par l œil de l observateur. Arbre BSP (binary search partitioning) Les données initiales sont les N murs, numérotés de 0 à N-1, et considérés comme des segments orientés avec une extrémité origine (xe1[], ye1[]) et une extrémité finale (xe2[],ye2[]). 2[]). On connaît aussi la position de l œil (xoeil, yoeil) ) et sa direction de vision grâce au vecteur Voeil. Notre univers de murs va être enregistré dans une structure de données en forme d arbre binaire, et l on verra ensuite pourquoi cela facilite son dessin. La méthode consiste prendre chaque mur l un après l autre et à construire un arbre binaire dont les nœuds contiennent chaque numéro des murs. Après avoir mis dans la racine de l arbre le mur 0, on fait descendre chacun des autres murs dans le sous-arbre gauche ou le sous-arbre droit selon qu il est à gauche ou à droite des murs enregistrés dans les nœuds déjà construits, jusqu à la première place vide. Ce procédé est identique à celui du tri par arbre binaire (cf. Algorithmique chapitre 6, à revoir au préalable avant de se lancer dans l arbre BSP). Mais cela suppose une situation où chaque mur est soit à gauche soit à droite, et non pas de part et d autre. Nous allons d abord traiter ce contexte le plus simple, avant de passer au cas général. Gauche ou droite, exclusivement On met le mur 0 dans la racine de l arbre. Puis le mur numéro 1 est placé à gauche ou à droite sous la racine selon qu il est à gauche ou à droite du mur 0. Puis on fait descendre le mur 2 à gauche ou à droite des nœuds déjà placés, selon sa position, etc. Cela donne un arbre qui concentre l information sur la position relative des murs. Notons que cet arbre est complètement indépendant de la position de l œil. Voici un exemple de murs avec l arbre associé : Dans le programme correspondant, on commence par entrer la structure des nœuds : struct cell {int n; struct cell * droite; struct cell * gauche;;

2 Puis on construit l arbre : racine=(struct cell *) malloc(sizeof(struct cell)); racine->n=0; racine->gauche=null; racine->droite=null; for(i=1;i<n;i++) { crochety=null;crochetx=racine; newcell=(struct cell *) malloc(sizeof(struct cell)); newcell->n=i; newcell->droite=null; newcell->gauche=null; while(crochetx!=null) { crochety=crochetx; numero=crochetx->n; xa=xe1[crochetx->n];ya=ye1[crochetx->n]; xxa=xe2[crochetx->n];yya=ye2[crochetx->n]; gauchedroite=dequelcote(xe1[i],ye1[i],xe2[i],ye2[i],xa,ya,xxa,yya); if (gauchedroite==1) crochetx=crochetx->gauche; else crochetx=crochetx->droite; if (gauchedroite==1) crochety->gauche=newcell; else crochety->droite=newcell; parcoursarbre(racine); A noter la présence de la fonction dequelcote() qui teste de quel côté se trouve le segment en cours de descente xe1[i],ye1[i],xe2[i],ye2[i] par rapport au segment xa, ya, xxa, yya correspondant au nœud de l arbre. Cette fonction ramène 1 ou -1 selon qu on est à gauche ou à droite. Enfin il y a la fonction parcoursarbre() qui va nous permettre de comprendre l intérêt de l arbre BSP. Parcours de l arbre Faisons maintenant intervenir la position de l œil. Si l œil est à droite du mur numéro i, on doit d abord dessiner les murs qui sont à gauche de ce mur i ( et qui sont derrière par rapport à l œil) avant de dessiner ce mur, et dessiner ce mur avant ceux qui sont situés à sa droite, cela afin de préserver les parties visibles des murs. Cela correspond à un parcours infixé du sous-arbre dont le mur i est la racine. Par contre si l œil est à gauche du mur i, on doit commencer par tracer les murs à droite, aussi va-t-on échanger le sous-arbre gauche et le sous-arbre droit de l arbre de racine i, de façon à faire ensuite comme auparavant un parcours infixé. Autrement dit, la position de l œil ne fait que provoquer quelques interversions dans l arbre, ce qui est facile à opérer, tout comme le parcours infixé. void parcoursarbre(struct cell * r) { if (r!=null) { if (oeilgauche(r)==non) /* fonction oeilgauche() à faire */ { parcoursarbre (r->gauche); dessiner le mur parcoursarbre(r->droite); else { parcoursarbre (r->droite); dessiner le mur parcoursarbre(r->gauche); Voici comment marche ce parcours dans l exemple choisi :

3 Les murs sont affichés dans l ordre 4 1 5 0 2 3. Ayant obtenu l ordre dans lequel on va prendre les murs, il reste à la dessiner sur l écran. Traçons pour cela un arc de cercle de centre l œil, cet arc étant coupé en O par le vecteur Voeil donnant la direction de la vision. C est cet arc qui va jouer le rôle d écran. Pour chaque mur, on détermine les deux angles (positifs ou négatifs) que font ses deux extrémités avec la direction de l œil, ce qui donne leur distance (la longueur de l arc) au point O sur l écran. On ajoute enfin un effet de perspective en diminuant la hauteur du mur entre ses deux extrémités selon qu elles sont plus ou moins loin de l œil. Remarquons que notre écran est courbe, ce qui n est pas le cas de l écran d ordinateur, mais la déformation est faible. On pourrait d ailleurs la rectifier en prenant le sinus des angles.

4 Cas général Nous allons maintenant nous placer dans le cas général où un mur n est pas forcément à gauche ou à droite d un autre mur, mais se trouve de part et d autre. Il convient alors de découper le mur suivant sa partie à gauche, qui conserve le numéro du mur complet initial, et sa partie à droite, qui devient un nouveau mur, avec un nouveau numéro (qui suit celui du mur de gauche), et qui s insère dans la liste des murs. On appellera NN le nombre de ces murs après découpage, étant entendu que NN est égal à N au début, mais qu il augmente de un à chaque découpage d un mur en deux. Les numéros des murs en cours d évolution sont placés dans un tableau a[]. Si le mur découpé a sa partie gauche dans a[i], sa partie droite sera placée dans a[i+1]. La fonction dequelcote(), qui jusqu ici ramenait 1 ou -1 selon que le mur était à gauche ou à droite d un autre mur, va maintenant ramener aussi 2 o -2, selon que le mur passe de gauche à droite ou de droite à gauche. Le problème de l intersection Pour permettre le découpage éventuel d un mur, il s agit de chercher le point où se fait la coupure. Prenons C (X, Y) et D (XX, YY) de part et d autre du vecteur AB avec A (x, y) et B (xx, yy), et déterminons le point d intersection K de (AB) avec [CD]. Considérons d abord le cas où C est à gauche et D à droite de AB : det(ab, AC)>0 et det(ab, AD)<0. Le point B est le barycentre des points A, C et D, avec comme masses respectives les aires des triangles CBD, ADB et ABC, ou leur double, qui sont les déterminants des vecteurs correspondants. Le point K est le barycentre de C et D avec les coefficients d1 = det(ab, AC) et d2= - det(ab, AD). Cela se traduit par : CK= (d1/(d1 d2)) CD, d où xk = (d1/(d1 d2))(xx-x)+x, et même pour yk. On fera de même lorsque C est à droite et D à gauche de AB. Il y a maintenant un problème subtil. Imaginons que l on ait pris les coordonnées des extrémités des murs en entiers. Jusque là tout va bien. Mais en cas de problème d intersection, si l on prend aussi les coordonnées du point K en entiers, il se produit une légère erreur d arrondi, et ensuite le test pour savoir si la partie de mur est à gauche ou à droite risque de rater : la partie gauche peut être testée comme empiétant sur la droite. Il est donc obligatoire de tout prendre en flottants, et de laisser une petite marge d erreur, du style determinant<=0.00001 au lieu de determinant<=0. On aboutit ainsi au programme final. #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <SDL/SDL.h> #define OUI 1 #define NON 0 #define N 6 #define z 100. /* zoom */

5 void ligne(int x0,int y0, int x1,int y1, Uint32 c); void pause(void); void cercle( int xo, int yo, int RR, Uint32 couleur); int dequelcote(float X, float Y, float XX, float YY,float x,float y, float xx, float yy); void parcoursarbre(struct cell * r); int oeilgauche(struct cell * rr); void dessinmurs(void); void floodfill( int x,int y, Uint32 cr,uint32 cb); Uint32 blanc,noir,rouge,vert,color[100],couleur,c[100];sdl_surface *ecran; float xe1[1000],ye1[1000],xe2[1000],ye2[1000]; int a[1000],nn,q; float oeilx,oeily,vectoeilx,vectoeily; float det1,det2; float longoeile,longoeilo, longvectoeil;int X1,Y1,X2,Y2; float oeilxe,oeilye,oeilxo,oeilyo,xg,yg; float angle1,angle2; struct cell {int n; struct cell * droite;struct cell * gauche;; struct cell * racine; int main ( int argc,char *argv[]) { int i,j,resultat,xg,yg,xd,yd,gauchedroite,numero; float xint,yint, xc,yc,xxc,yyc,xa,ya,xxa,yya; struct cell * crochetx, * crochety,*newcell; SDL_Init( SDL_INIT_VIDEO );srand(time(null)); ecran= SDL_SetVideoMode(800, 600, 32,SDL_HWSURFACE SDL_DOUBLEBUF); blanc=sdl_maprgb(ecran->format,255,255,255); noir=sdl_maprgb(ecran->format,0,0,0); rouge=sdl_maprgb(ecran -> format, 255, 0, 0); vert=sdl_maprgb(ecran -> format, 0,255, 0); for(j=0;j<100;j++) color[j]=sdl_maprgb(ecran -> format, rand()%200, rand()%256, rand()%256); SDL_FillRect(ecran,NULL,blanc); xe1[0]=0.20;ye1[0]=0.50; xe2[0]=1.30;ye2[0]=1.00; /* un exemple avec six murs */ xe1[1]=1.20;ye1[1]=1.80; xe2[1]=0.90;ye2[1]=1.20; xe1[2]=2.20;ye1[2]=0.20; xe2[2]=1.05;ye2[2]=0.55; xe1[3]=2.30 ;ye1[3]=0.40; xe2[3]=2.20;ye2[3]=0.70; xe1[4]=0.50;ye1[4]=0.90; xe2[4]=0.10;ye2[4]=1.60; xe1[5]=1.30;ye1[5]=1.20; xe2[5]=2.13 ;ye2[5]=1.20; for(i=0;i<n;i++) { ligne(z*xe1[i],450-z*ye1[i],z*xe2[i],450-z*ye2[i],rouge); cercle(z*xe1[i],450-z*ye1[i],2,rouge);sdl_flip(ecran); oeilx=3.50;oeily=0.70;cercle(z*oeilx,450-z*oeily,3,rouge); vectoeilx=-1.00;vectoeily=0; ligne(z*oeilx,450-z*oeily,z*oeilx+z*vectoeilx,450-(z*oeily+z*vectoeily),vert); SDL_Flip(ecran);pause(); for(i=0;i<n;i++) a[i]=i; NN=N; racine=(struct cell *) malloc(sizeof(struct cell)); racine->n=a[0]; racine->gauche=null; racine->droite=null; c[a[0]]=color[0]; for(i=1;i<nn;i++) { crochety=null;crochetx=racine; newcell=(struct cell *) malloc(sizeof(struct cell)); newcell->n=a[i]; newcell->droite=null; newcell->gauche=null; xc=xe1[a[i]];yc=ye1[a[i]];xxc=xe2[a[i]];yyc=ye2[a[i]];

6 if (c[a[i]]==0) c[a[i]]=color[i]; /* couleur finale des murs */ while(crochetx!=null) { crochety=crochetx; numero=crochetx->n; xa=xe1[crochetx->n];ya=ye1[crochetx->n]; xxa=xe2[crochetx->n];yya=ye2[crochetx->n]; xc=xe1[a[i]];yc=ye1[a[i]];xxc=xe2[a[i]];yyc=ye2[a[i]]; gauchedroite=dequelcote(xc,yc,xxc,yyc,xa,ya,xxa,yya); if (gauchedroite==1) crochetx=crochetx->gauche; else if (gauchedroite==-1) crochetx=crochetx->droite; else if (gauchedroite==2) { xint=det1*(float)(xxc-xc)/(det1-det2) +xc; yint=det1*(float)(yyc-yc)/(det1-det2)+yc; cercle(z*xint,450-z*yint,5,rouge); xe2[a[i]]=xint; ye2[a[i]]=yint; for(q=nn-1;q>i;q--) { a[q+1]=a[q]; xe1[a[q+1]]=xe1[a[q]] ; ye1[a[q+1]]=ye1[a[q]] ; xe2[a[q+1]]=xe2[a[q]] ; ye2[a[q+1]]=ye2[a[q]] ; a[i+1]=nn; xe1[a[i+1]]=xint; ye1[a[i+1]]=yint; xe2[a[i+1]]=xxc; ye2[a[i+1]]=yyc; c[a[i+1]]=c[a[i]]; /* on garde la même couleur pour chaque partie du même mur */ NN++; else if (gauchedroite==-2) { xint=det2*(float)(xxc-xc)/(det2-det1)+xc; yint=det2*(float)(yyc-yc)/(det2-det1) +yc; xe2[a[i]]=xint; ye2[a[i]]=yint; cercle(xint,450-yint,3,vert ); for(q=nn-1;q>i;q--) { a[q+1]=a[q]; xe1[a[q+1]]=xe1[a[q]] ; ye1[a[q+1]]=ye1[a[q]] ; xe2[a[q+1]]=xe2[a[q]] ; ye2[a[q+1]]=ye2[a[q]] ; a[i+1]=nn; xe1[a[i+1]]=xint; ye1[a[i+1]]=yint; xe2[a[i+1]]=xxc; ye2[a[i+1]]=yyc; c[a[i+1]]=c[a[i]]; NN++; if (gauchedroite==1) crochety->gauche=newcell; else crochety->droite=newcell; parcoursarbre(racine); SDL_Flip(ecran);pause(); return 0; int dequelcote(float X, float Y, float XX, float YY,float x,float y, float xx, float yy) { float vx,vy,vx,vy,vxx,vyy; vx=xx-x;vy=yy-y; vx=x-x;vy=y-y; vxx=xx-x;vyy=yy-y; det1=vx*vy-vy*vx; det2=vx*vyy-vy*vxx; if (det1>=-0.00001 && det2>=-0.00001) return 1; if (det1<=0.00001 && det2<=0.00001) return -1; if (det1>=-0.00001 && det2<=0.00001 ) return 2; if (det1<=0.00001 && det2>=-0.00001) return -2; else return 0;

7 void parcoursarbre(struct cell * r) { if (r!=null) { if (oeilgauche(r)==0) { parcoursarbre (r->gauche); oeilxo=xe1[r->n] -oeilx; oeilyo=ye1[r->n]-oeily; oeilxe=xe2[r->n]-oeilx; oeilye=ye2[r->n]-oeily; longvectoeil=sqrt(vectoeilx*vectoeilx+vectoeily*vectoeily); longoeilo=sqrt(oeilxo*oeilxo+oeilyo*oeilyo); longoeile=sqrt(oeilxe*oeilxe+oeilye*oeilye); ligne(z*oeilx,450-z*oeily,z*xe1[r->n],450-z*ye1[r->n],rouge); ligne(z*oeilx,450-z*oeily,z*xe2[r->n],450-z*ye2[r->n],rouge); couleur=c[r->n];dessinmurs(); parcoursarbre(r->droite); else { parcoursarbre (r->droite); oeilxo=xe1[r->n] -oeilx; oeilyo=ye1[r->n]-oeily; oeilxe=xe2[r->n]-oeilx; oeilye=ye2[r->n]-oeily; longvectoeil=sqrt(vectoeilx*vectoeilx+vectoeily*vectoeily); longoeilo=sqrt(oeilxo*oeilxo+oeilyo*oeilyo); longoeile=sqrt(oeilxe*oeilxe+oeilye*oeilye); ligne(z*oeilx,450-z*oeily,z*xe1[r->n],450-z*ye1[r->n],rouge); ligne(z*oeilx,450-z*oeily,z*xe2[r->n],450-z*ye2[r->n],rouge); couleur=c[r->n];dessinmurs(); parcoursarbre(r->gauche); int oeilgauche(struct cell * rr) { float vx,vy,vvx,vvy,det; vx=xe2[rr->n]-xe1[rr->n]; vvx=oeilx-xe1[rr->n] ;vvy=oeily-ye1[rr->n]; det=vx*vvy-vy*vvx; if ( det>0) return 1; else return 0; vy= ye2[rr->n]- ye1[rr->n]; void dessinmurs(void) { angle1=(oeilxo*vectoeily-oeilyo*vectoeilx) /(longvectoeil*longoeilo); angle2=(oeilxe*vectoeily-oeilye*vectoeilx) /(longvectoeil*longoeile); X1=(int) (700.*angle1);Y1=150-z*longoeilo/4; X2=(int) (700.*angle2);Y2=150-z*longoeile/4; cercle(300,200,5,rouge); ligne(300+x1,200,300+x1,200-y1,couleur);ligne(300+x2,200,300+x2,200-y2,couleur); ligne(300+x1,200,300+x2,200,couleur);ligne(300+x1,200-y1,300+x2,200-y2,couleur); xg=(300+x1+300+x2)/2; yg=(200+200-y2)/2; floodfill(xg,yg,couleur,couleur); if (longoeilo<longoeile) { ligne(300+x1,200,300+x1,200-y1,noir); ligne(301+x1,200,301+x1,200-y1,noir); ligne(302+x1,200,302+x1,200-y1,noir); else { ligne(300+x2,200,300+x2,200-y2,noir); ligne(301+x2,200,301+x2,200-y2,noir); ligne(302+x2,200,302+x2,200-y2,noir);

8 (ici un des murs, celui qui est en rouge, a été coupé en trois)