From 54fecc3c759b4bc1f32188b9fb60eeace8cce685 Mon Sep 17 00:00:00 2001 From: Yoann Date: Wed, 19 Oct 2011 19:30:24 +0200 Subject: [PATCH 01/18] =?UTF-8?q?Fin=20de=20la=20fonciton=20d'initialisati?= =?UTF-8?q?on=20de=20la=20grille=20de=20stockage=20de=20n=C5=93ds=20de=20r?= =?UTF-8?q?outes.=20Et=20adaptation=20des=20autres=20fonctions.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 77 +++++++++++++++++++++++++++++++++++++++++++-------------- roads.h | 10 +++++--- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/roads.c b/roads.c index b020dc9..d70c2ee 100644 --- a/roads.c +++ b/roads.c @@ -30,23 +30,43 @@ void roads(Polygon* quartier) { // TODO Fusionner les deux fonctions et retourner une paire de valeurs. // Transforme des coordonnées du plan en coordonées du tableau sur x. int toX(Vertex *v) { - return v->x*(maxSubDivision-1)/quarterSize; + fprintf(stderr,"%d\n",nbXSubDivision); + int x = v->x*(nbYSubDivision-1)/quarterWidth; + if(x >= nbXSubDivision) + fprintf(stderr,"depassement du tableau sur x\n"); + return x; } // Transforme des coordonnées du plan en coordonées du tableau sur y. int toY(Vertex *v) { - return v->x*(maxSubDivision-1)/quarterSize; + int y = v->x*(nbYSubDivision-1)/quarterHeight; + if(y >= nbYSubDivision) + fprintf(stderr,"Depassement du tableau sur y\n"); + return y; } -void grid_initNodesGrid(int size) { - nodesGrid = (roadNodeY****) malloc(sizeof(roadNodeY***)*size); +/* Initialise la grille de nœds. + * @param int width : Largeur du quartier à remplir. + * @param int height : Hauteur du quartier à remplir. + * @param int maxSegmentSize : Taille maximale d'un segment de route. + */ +void grid_initNodesGrid(int width, int height, int segmentSize) { + int xSize, ySize; + xSize = (int)(width/segmentSize); + ySize = (int)(height/segmentSize); + + nodesGrid = (roadNodeY****) malloc(sizeof(roadNodeY***)*xSize); int i,j,k; - maxSubDivision = size; + maxSegmentSize = segmentSize; + nbXSubDivision = xSize; + nbYSubDivision = ySize; + quarterWidth = width; + quarterHeight = height; - for(i=0;iv == NULL) return 0; @@ -87,12 +121,12 @@ void addRoadNode(roadPointY *rp, roadNodeY *rn) { roadNodeY* grid_getNearestRoadNode(Vertex *v) { roadNodeY **nr = grid_getNearNodes(v); roadNodeY *nearestNode = NULL; + if(nr[0] == NULL) + return NULL; + roadNodeY *tmp = nr[0]; int distance = distBetween(v,tmp->v); - if(tmp == NULL) - return NULL; - nearestNode = tmp; int i = 0; @@ -120,7 +154,7 @@ roadNodeY** grid_getNearNodes(Vertex *v) { void carreY() { int size = 500; - grid_initNodesGrid(6); + grid_initNodesGrid(800,600,10); roadPointY *roada = (roadPointY*) malloc(sizeof(roadPointY)); roadPointY *roadb = (roadPointY*) malloc(sizeof(roadPointY)); roadNodeY *rn; @@ -128,7 +162,7 @@ void carreY() { roadNodeY *common = NULL; int i; - for(i=0;i<40;i++) { + for(i=0;i<36;i++) { rn = (roadNodeY*)malloc(sizeof(roadNodeY)); v = (Vertex*) malloc(sizeof(Vertex)); @@ -140,17 +174,19 @@ void carreY() { addRoadNode(roada,rn); } - for(i=0;i<30;i++) { + for(i=0;i<20;i++) { rn = (roadNodeY*)malloc(sizeof(roadNodeY)); v = (Vertex*) malloc(sizeof(Vertex)); v->x = (i+1)*22; - v->y = ((i+1)%5)*(61%(i+2))+160; + v->y = ((i+1)%5)*(61%(i+2))+150; rn->v = v; - if(i%5) if(grid_getNearestRoadNode(v) != NULL) - rn = grid_getNearestRoadNode(v); - //rn = common; - addRoadNode(roadb,rn); + if(v->x < 800 && v->y < 600) { + if(i%5 == 0) if(grid_getNearestRoadNode(v) != NULL) + rn = grid_getNearestRoadNode(v); + //rn = common; + addRoadNode(roadb,rn); + } } roadPointY *rd = roada; @@ -185,6 +221,9 @@ int main() { //for (i = 0; i < n; i++) { // svg_line(&(points[i]), &(points[(i+1)%n])); // } + + grid_drawGrid(); + n=n; //roads(points); points[0] = points[0]; diff --git a/roads.h b/roads.h index 3ff55f9..3470c82 100644 --- a/roads.h +++ b/roads.h @@ -35,15 +35,19 @@ typedef struct roadPointY { } roadPointY; roadNodeY ****nodesGrid; -short maxSubDivision; +short nbXSubDivision; +short nbYSubDivision; +short maxSegmentSize; short maxNodesInGrid = 10; -int quarterSize = 600; +int quarterWidth; +int quarterHeight; int toX(Vertex*); int toY(Vertex*); -void grid_initNodesGrid(int size); +void grid_initNodesGrid(int w, int h, int maxSegmentSize); short grid_insertRoadNode(roadNodeY *rn); void addRoadNode(roadPointY *rp, roadNodeY *rn); int distBetween(Vertex *v, Vertex *u); roadNodeY** grid_getNearNodes(Vertex *v); roadNodeY* grid_getNearestRoadNode(Vertex *v); +void grid_drawGrid(); From 93389a75fd96dfd245ab376c2519c892148e4b6c Mon Sep 17 00:00:00 2001 From: Yoann Date: Wed, 19 Oct 2011 19:37:11 +0200 Subject: [PATCH 02/18] =?UTF-8?q?Affichage=20de=20la=20grille=20pour=20d?= =?UTF-8?q?=C3=A9bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/roads.c b/roads.c index d70c2ee..d1283e6 100644 --- a/roads.c +++ b/roads.c @@ -13,6 +13,10 @@ void svg_line(Vertex* a, Vertex* b) { printf("", a->x, a->y, b->x, b->y); } +void svg_grey_line(Vertex* a, Vertex* b) { + printf("", a->x, a->y, b->x, b->y); +} + void roads(Polygon* quartier) { quartier = quartier; Vertex center = { .x=400, .y=300 }; @@ -81,10 +85,10 @@ void grid_drawGrid() { for(j=0;j Date: Wed, 19 Oct 2011 20:16:52 +0200 Subject: [PATCH 03/18] Correction d'un bug. --- roads.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/roads.c b/roads.c index d1283e6..d14580a 100644 --- a/roads.c +++ b/roads.c @@ -34,8 +34,7 @@ void roads(Polygon* quartier) { // TODO Fusionner les deux fonctions et retourner une paire de valeurs. // Transforme des coordonnées du plan en coordonées du tableau sur x. int toX(Vertex *v) { - fprintf(stderr,"%d\n",nbXSubDivision); - int x = v->x*(nbYSubDivision-1)/quarterWidth; + int x = v->x*(nbXSubDivision)/quarterWidth; if(x >= nbXSubDivision) fprintf(stderr,"depassement du tableau sur x\n"); return x; @@ -43,7 +42,7 @@ int toX(Vertex *v) { // Transforme des coordonnées du plan en coordonées du tableau sur y. int toY(Vertex *v) { - int y = v->x*(nbYSubDivision-1)/quarterHeight; + int y = v->y*(nbYSubDivision)/quarterHeight; if(y >= nbYSubDivision) fprintf(stderr,"Depassement du tableau sur y\n"); return y; @@ -157,13 +156,12 @@ roadNodeY** grid_getNearNodes(Vertex *v) { } void carreY() { - int size = 500; grid_initNodesGrid(800,600,10); roadPointY *roada = (roadPointY*) malloc(sizeof(roadPointY)); roadPointY *roadb = (roadPointY*) malloc(sizeof(roadPointY)); roadNodeY *rn; Vertex *v; - roadNodeY *common = NULL; + //roadNodeY *common = NULL; int i; for(i=0;i<36;i++) { @@ -173,7 +171,8 @@ void carreY() { v->x = (i+1)*16; v->y = ((i+1)%3)*(61%(i+1))+100; rn->v = v; - if(i == 18) common = rn; + fprintf(stderr,"x : %d y : %d\n",toX(v),toY(v)); + grid_insertRoadNode(rn); addRoadNode(roada,rn); } @@ -183,12 +182,13 @@ void carreY() { v = (Vertex*) malloc(sizeof(Vertex)); v->x = (i+1)*22; - v->y = ((i+1)%5)*(61%(i+2))+150; + v->y = ((i+1)%5)*(61%(i+2))+112; rn->v = v; + if(i==4) {fprintf(stderr,"x : %d y : %d\n",toX(v),toY(v));} if(v->x < 800 && v->y < 600) { - if(i%5 == 0) if(grid_getNearestRoadNode(v) != NULL) + if(i != 0) if(grid_getNearestRoadNode(v) != NULL) rn = grid_getNearestRoadNode(v); - //rn = common; + //rn = rn; addRoadNode(roadb,rn); } } @@ -206,8 +206,6 @@ void carreY() { rd = rd->next; } - - size=size; } int main() { From 84799155ba3d0ed5582b3c63226df0ba983248c9 Mon Sep 17 00:00:00 2001 From: Yoann Date: Thu, 20 Oct 2011 14:02:55 +0200 Subject: [PATCH 04/18] Modification de la fonction de detection du sommet le plus proche, mais erreur de segmentation pour le moement. --- roads.c | 50 ++++++++++++++++++++++++++++++-------------------- roads.h | 1 + 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/roads.c b/roads.c index d14580a..11e6c32 100644 --- a/roads.c +++ b/roads.c @@ -122,27 +122,34 @@ void addRoadNode(roadPointY *rp, roadNodeY *rn) { } roadNodeY* grid_getNearestRoadNode(Vertex *v) { - roadNodeY **nr = grid_getNearNodes(v); + roadNodeY **nr; roadNodeY *nearestNode = NULL; - if(nr[0] == NULL) - return NULL; - - roadNodeY *tmp = nr[0]; - int distance = distBetween(v,tmp->v); - - nearestNode = tmp; - int i = 0; - - do { - int dist = distBetween(v,tmp->v); - if(dist < distance) { - distance = dist; - nearestNode = tmp; + int i,j; + int x = toX(v); + int y = toY(v); + int distance = maxSegmentSize*2; + roadNodeY *tmp = NULL; + int count = 0; + fprintf(stderr,"colones : %d\n",nbXSubDivision); + fprintf(stderr,"lignes : %d\n",nbYSubDivision); + for(i=x-1; i= 0 && i < nbXSubDivision && y >= 0 && y < nbYSubDivision) { + nr = grid_getNearNodes2(i,j); + tmp = nr[0]; + fprintf(stderr,"passage %d\t\t %d %d\n",count,i,j); + while(tmp != NULL) { + int dist = distBetween(v,tmp->v); + if(dist < distance) { + distance = dist; + nearestNode = tmp; + } + + tmp = nr[i]; + } + } } - - i++; - tmp = nr[i]; - } while(tmp != NULL); + } return nearestNode; } @@ -155,6 +162,10 @@ roadNodeY** grid_getNearNodes(Vertex *v) { return nodesGrid[toX(v)][toY(v)]; } +roadNodeY** grid_getNearNodes2(int x, int y) { + return nodesGrid[x][y]; +} + void carreY() { grid_initNodesGrid(800,600,10); roadPointY *roada = (roadPointY*) malloc(sizeof(roadPointY)); @@ -171,7 +182,6 @@ void carreY() { v->x = (i+1)*16; v->y = ((i+1)%3)*(61%(i+1))+100; rn->v = v; - fprintf(stderr,"x : %d y : %d\n",toX(v),toY(v)); grid_insertRoadNode(rn); addRoadNode(roada,rn); diff --git a/roads.h b/roads.h index 3470c82..678eed2 100644 --- a/roads.h +++ b/roads.h @@ -49,5 +49,6 @@ short grid_insertRoadNode(roadNodeY *rn); void addRoadNode(roadPointY *rp, roadNodeY *rn); int distBetween(Vertex *v, Vertex *u); roadNodeY** grid_getNearNodes(Vertex *v); +roadNodeY** grid_getNearNodes2(int x, int y); roadNodeY* grid_getNearestRoadNode(Vertex *v); void grid_drawGrid(); From 12d74c410cb7d61ec3f80b53d39f47a8c7ca6ad2 Mon Sep 17 00:00:00 2001 From: Yoann Date: Fri, 21 Oct 2011 09:38:35 +0200 Subject: [PATCH 05/18] La fonction de recherche du noed le plus proche fonctionne correctement. --- roads.c | 21 +++++++++++++++------ roads.h | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/roads.c b/roads.c index 11e6c32..f27042f 100644 --- a/roads.c +++ b/roads.c @@ -13,6 +13,10 @@ void svg_line(Vertex* a, Vertex* b) { printf("", a->x, a->y, b->x, b->y); } +void svg_circle(int x, int y, int r) { + printf("",x,y,r); +} + void svg_grey_line(Vertex* a, Vertex* b) { printf("", a->x, a->y, b->x, b->y); } @@ -135,10 +139,14 @@ roadNodeY* grid_getNearestRoadNode(Vertex *v) { for(i=x-1; i= 0 && i < nbXSubDivision && y >= 0 && y < nbYSubDivision) { + nr = grid_getNearNodes2(i,j); - tmp = nr[0]; + + int ind; + //tmp = nr[0]; fprintf(stderr,"passage %d\t\t %d %d\n",count,i,j); - while(tmp != NULL) { + for(tmp = nr[0], ind = 0; tmp != NULL && ind < maxNodesInGrid; tmp = nr[ind++]) { + fprintf(stderr,"noed\n"); int dist = distBetween(v,tmp->v); if(dist < distance) { distance = dist; @@ -187,15 +195,16 @@ void carreY() { addRoadNode(roada,rn); } - for(i=0;i<20;i++) { + for(i=0;i<30;i++) { rn = (roadNodeY*)malloc(sizeof(roadNodeY)); v = (Vertex*) malloc(sizeof(Vertex)); v->x = (i+1)*22; - v->y = ((i+1)%5)*(61%(i+2))+112; + v->y = ((i+1)%5)*(61%(i+2))+120; rn->v = v; if(i==4) {fprintf(stderr,"x : %d y : %d\n",toX(v),toY(v));} if(v->x < 800 && v->y < 600) { + fprintf(stderr,"Noed : %d\n",i); if(i != 0) if(grid_getNearestRoadNode(v) != NULL) rn = grid_getNearestRoadNode(v); //rn = rn; @@ -206,14 +215,14 @@ void carreY() { roadPointY *rd = roada; while(rd->next != NULL) { svg_line(rd->rn->v,rd->next->rn->v); - + svg_circle(rd->rn->v->x,rd->rn->v->y,2); rd = rd->next; } rd = roadb; while(rd->next != NULL) { svg_line(rd->rn->v,rd->next->rn->v); - + svg_circle(rd->rn->v->x,rd->rn->v->y,2); rd = rd->next; } } diff --git a/roads.h b/roads.h index 678eed2..0bff92d 100644 --- a/roads.h +++ b/roads.h @@ -38,7 +38,7 @@ roadNodeY ****nodesGrid; short nbXSubDivision; short nbYSubDivision; short maxSegmentSize; -short maxNodesInGrid = 10; +short maxNodesInGrid = 16; int quarterWidth; int quarterHeight; From eb20bcf0be50ba27b065569a3ac6d8111208ce67 Mon Sep 17 00:00:00 2001 From: Yoann Date: Fri, 21 Oct 2011 11:20:03 +0200 Subject: [PATCH 06/18] =?UTF-8?q?Insertion=20d'un=20segment=20de=20route?= =?UTF-8?q?=20avec.=20Le=20segment=20peut=20s'accrocher=20=C3=A0=20un=20n?= =?UTF-8?q?=C5=93d=20edistant=20ci=20celui-ci=20est=20proche=20du=20point?= =?UTF-8?q?=20d'arriv=C3=A9=20et=20qu'il=20n'implique=20pas=20une=20=C3=A9?= =?UTF-8?q?longation=20du=20segment=20de=20route.=20Pour=20le=20moment=20i?= =?UTF-8?q?l=20n'y=20a=20pas=20de=20cr=C3=A9ation=20de=20n=C5=93ds=20sur?= =?UTF-8?q?=20un=20segment=20ni=20de=20gestion=20des=20intersections=20ent?= =?UTF-8?q?re=20segments.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/roads.c b/roads.c index f27042f..72d2457 100644 --- a/roads.c +++ b/roads.c @@ -162,6 +162,32 @@ roadNodeY* grid_getNearestRoadNode(Vertex *v) { return nearestNode; } +roadNodeY* insertRoadSegment(roadPointY *road, roadNodeY *rnb, roadNodeY *rne, int lag) { + int segLength = distBetween(rnb->v, rne->v); + float coef = ((float)segLength-lag)/(float)segLength; + roadNodeY *nearestNode = NULL; + Vertex tmpEnd; + tmpEnd.x = rnb->v->x+coef*(rne->v->x - rnb->v->x); + tmpEnd.y = rnb->v->y+coef*(rne->v->y - rnb->v->y); + fprintf(stderr,"segLength : %d\n",segLength); + fprintf(stderr," ostart : %d %d\t oend : %d %d\n",rnb->v->x,rnb->v->y,rne->v->x,rne->v->y); + fprintf(stderr," end : %d %d\n",tmpEnd.x,tmpEnd.y); + nearestNode = grid_getNearestRoadNode(&tmpEnd); + + fprintf(stderr,"--11\n"); + + if(nearestNode != NULL && distBetween(nearestNode->v,rne->v) < lag) + rne = nearestNode; + fprintf(stderr,"--AA\n"); + grid_insertRoadNode(rnb); + fprintf(stderr,"--BB\n"); + grid_insertRoadNode(rne); + fprintf(stderr,"--CC\n"); + addRoadNode(road,rne); + fprintf(stderr,"--DD\n"); + return rne; +} + int distBetween(Vertex *v, Vertex *u) { return sqrt((v->x-u->x)*(v->x-u->x)+(v->y-u->y)*(v->y-u->y)); } @@ -180,7 +206,7 @@ void carreY() { roadPointY *roadb = (roadPointY*) malloc(sizeof(roadPointY)); roadNodeY *rn; Vertex *v; - //roadNodeY *common = NULL; + roadNodeY *lastNode = NULL; int i; for(i=0;i<36;i++) { @@ -205,10 +231,14 @@ void carreY() { if(i==4) {fprintf(stderr,"x : %d y : %d\n",toX(v),toY(v));} if(v->x < 800 && v->y < 600) { fprintf(stderr,"Noed : %d\n",i); - if(i != 0) if(grid_getNearestRoadNode(v) != NULL) - rn = grid_getNearestRoadNode(v); - //rn = rn; - addRoadNode(roadb,rn); + if(i==0) { + addRoadNode(roadb,rn); + lastNode = rn; + } + else { + insertRoadSegment(roadb,lastNode,rn,10); + lastNode = rn; + } } } From 0f7cbe176e50991f6dc1d81df5f59662887e5321 Mon Sep 17 00:00:00 2001 From: Yoann Date: Fri, 21 Oct 2011 12:35:14 +0200 Subject: [PATCH 07/18] =?UTF-8?q?Am=C3=A9lioration=20de=20l'affichage=20de?= =?UTF-8?q?s=20routes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/roads.c b/roads.c index 72d2457..7f1c015 100644 --- a/roads.c +++ b/roads.c @@ -9,22 +9,25 @@ void svg_end() { printf(""); } -void svg_line(Vertex* a, Vertex* b) { - printf("", a->x, a->y, b->x, b->y); +void svg_line(Vertex* a, Vertex* b,short color) { + if(color == 0) + printf("", a->x, a->y, b->x, b->y); + else if(color == 1) + printf("", a->x, a->y, b->x, b->y); + else if(color == 2) + printf("", a->x, a->y, b->x, b->y); + else + printf("", a->x, a->y, b->x, b->y); } void svg_circle(int x, int y, int r) { printf("",x,y,r); } -void svg_grey_line(Vertex* a, Vertex* b) { - printf("", a->x, a->y, b->x, b->y); -} - void roads(Polygon* quartier) { quartier = quartier; Vertex center = { .x=400, .y=300 }; - svg_line(¢er, &(quartier[0])); + svg_line(¢er, &(quartier[0]),6); } @@ -88,10 +91,10 @@ void grid_drawGrid() { for(j=0;jv,rne->v) < lag) rne = nearestNode; - fprintf(stderr,"--AA\n"); + grid_insertRoadNode(rnb); - fprintf(stderr,"--BB\n"); grid_insertRoadNode(rne); - fprintf(stderr,"--CC\n"); addRoadNode(road,rne); - fprintf(stderr,"--DD\n"); return rne; } @@ -244,15 +244,15 @@ void carreY() { roadPointY *rd = roada; while(rd->next != NULL) { - svg_line(rd->rn->v,rd->next->rn->v); - svg_circle(rd->rn->v->x,rd->rn->v->y,2); + svg_line(rd->rn->v,rd->next->rn->v,1); + svg_circle(rd->rn->v->x,rd->rn->v->y,1); rd = rd->next; } rd = roadb; while(rd->next != NULL) { - svg_line(rd->rn->v,rd->next->rn->v); - svg_circle(rd->rn->v->x,rd->rn->v->y,2); + svg_line(rd->rn->v,rd->next->rn->v,2); + svg_circle(rd->rn->v->x,rd->rn->v->y,1); rd = rd->next; } } From 994a0ac085ce3720409ab4c474b543048cb3b78e Mon Sep 17 00:00:00 2001 From: Yoann Date: Fri, 21 Oct 2011 19:35:32 +0200 Subject: [PATCH 08/18] =?UTF-8?q?Ajout=20des=20deux=20fonction=20de=20conv?= =?UTF-8?q?ersion=20de=20coordonn=C3=A9es=20polaires=20et=20cart=C3=A9sien?= =?UTF-8?q?nes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 33 +++++++++++++++++++++++++++++---- roads.h | 12 ++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/roads.c b/roads.c index 7f1c015..1e3fbba 100644 --- a/roads.c +++ b/roads.c @@ -42,19 +42,44 @@ void roads(Polygon* quartier) { // Transforme des coordonnées du plan en coordonées du tableau sur x. int toX(Vertex *v) { int x = v->x*(nbXSubDivision)/quarterWidth; - if(x >= nbXSubDivision) - fprintf(stderr,"depassement du tableau sur x\n"); + if(x >= nbXSubDivision) return 0; return x; } // Transforme des coordonnées du plan en coordonées du tableau sur y. int toY(Vertex *v) { int y = v->y*(nbYSubDivision)/quarterHeight; - if(y >= nbYSubDivision) - fprintf(stderr,"Depassement du tableau sur y\n"); + if(y >= nbYSubDivision) return 0; return y; } +/* Convertion de coordonnées polaires en coordonnées cartésiennes. + * @param Vertex* origin : Origine du vecteur. + * @param short angle : Angle. + * @param short length : Taille du vecteur. + * @return struct cartesianCoord* : Les coordonnées cartésiennes du point d'arrivée. + */ +cartesianCoord* ptc(Vertex *origin, short angle, short length) { + cartesianCoord *cc = (cartesianCoord*) malloc(sizeof(cartesianCoord)); + cc->x = origin->x + cos(M_PI*angle/180)*length; + cc->y = origin->y + sin(M_PI*angle/180)*length; + + return cc; +} + +/* Convertion de coordonnées cartésiennes en coordonnées polaires. + * @param Vertex* origin : Origine du vecteur. + * * @param Vertex* end : Fin du vecteur. + * @return struct polarCoord* : Les coordonnées polaires du point d'arrivée. + */ +polarCoord* ctp(Vertex *origin, Vertex *end) { + polarCoord *pc = (polarCoord*) malloc(sizeof(polarCoord)); + pc->length = distBetween(origin,end); + pc->angle = acos((end->x-origin->x)/pc->length); + + return pc; +} + /* Initialise la grille de nœds. * @param int width : Largeur du quartier à remplir. * @param int height : Hauteur du quartier à remplir. diff --git a/roads.h b/roads.h index 0bff92d..fe18c5a 100644 --- a/roads.h +++ b/roads.h @@ -34,6 +34,16 @@ typedef struct roadPointY { roadNodeY *rn; } roadPointY; +typedef struct cartesianCoord { + int x; // Coordonnées sur x. + int y; // Coordonnées sur y. +} cartesianCoord; + +typedef struct polarCoord { + int angle; // Angle en degrès. + int length; // Norme du vecteur. +} polarCoord; + roadNodeY ****nodesGrid; short nbXSubDivision; short nbYSubDivision; @@ -52,3 +62,5 @@ roadNodeY** grid_getNearNodes(Vertex *v); roadNodeY** grid_getNearNodes2(int x, int y); roadNodeY* grid_getNearestRoadNode(Vertex *v); void grid_drawGrid(); +cartesianCoord* ptc(Vertex *origin, short angle, short length); +polarCoord* ctp(Vertex *origin, Vertex *end); From 1a1222b91591f9e9bb6d7126389760008941a612 Mon Sep 17 00:00:00 2001 From: Yoann Date: Fri, 21 Oct 2011 20:03:26 +0200 Subject: [PATCH 09/18] Quelques petites modifications. --- roads.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/roads.c b/roads.c index 1e3fbba..04ddd7a 100644 --- a/roads.c +++ b/roads.c @@ -79,7 +79,7 @@ polarCoord* ctp(Vertex *origin, Vertex *end) { return pc; } - + /* Initialise la grille de nœds. * @param int width : Largeur du quartier à remplir. * @param int height : Hauteur du quartier à remplir. @@ -153,6 +153,11 @@ void addRoadNode(roadPointY *rp, roadNodeY *rn) { rp->next = rpp; } +/* Retourne le nœd le plus proche dans un certain voisinage. Si aucun nœd n'est trouvé alors + * la fonction renvoie NULL. + * @param Vertex *v : Le nœd pour lequel on souhaite trouver un nœd proche. + * @return roadNodeY* : le nœd de route le plus proche. + */ roadNodeY* grid_getNearestRoadNode(Vertex *v) { roadNodeY **nr; roadNodeY *nearestNode = NULL; @@ -190,6 +195,21 @@ roadNodeY* grid_getNearestRoadNode(Vertex *v) { return nearestNode; } +/* Ajoute un segment de route à la fin d'une route. + * Le point d'origine du segment est le dernier de la route actuellement en place. Il est passé en paramètre pour + * éviter le parcour de la route entière pour le trouver. + * Le point d'arrivé peut-etre modifié suivant deux règles principales. + * - Un nœd de route existe proche de l'endroit ou doit ce terminer le segment dans ce cas + * on "fusionne" les deux le point existant devient le point d'arrivé du segment. + * - Un segment se trouve sur le chemin du segment que l'on souhaite placer. Dans ce cas le segment + * que l'on souhaite placer sera sectionné à l'intersection des deux segments et le points d'intersections sera + * le point d'arrivé du segment à placer. + * @param roadPointY *road : La route à laquelle on veut ajouter le segmetn. + * @param roadNodeY *rnb : Le nœd de départ du segment. + * @param roadNodeY *rne : Le nœd d'arrivé du segment. + * @param int lag : le décalage maximal autorisé pour le placement du nœd d'arrivé. + * @return roadNodeY* : Le nœd d'arrivé du vecteur potentiellement modifié. + */ roadNodeY* insertRoadSegment(roadPointY *road, roadNodeY *rnb, roadNodeY *rne, int lag) { int segLength = distBetween(rnb->v, rne->v); float coef = ((float)segLength-lag)/(float)segLength; From d115d482e6b3d4e34cead8e324c8ae48d4a08dba Mon Sep 17 00:00:00 2001 From: Yoann Date: Sat, 22 Oct 2011 14:50:41 +0200 Subject: [PATCH 10/18] =?UTF-8?q?Ajout=20de=20la=20fonction=20de=20calcul?= =?UTF-8?q?=20d'intersection=20entre=20deux=20segments=20(non=20v=C3=A9rif?= =?UTF-8?q?i=C3=A9e).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/roads.c b/roads.c index 04ddd7a..e767e20 100644 --- a/roads.c +++ b/roads.c @@ -92,7 +92,7 @@ void grid_initNodesGrid(int width, int height, int segmentSize) { nodesGrid = (roadNodeY****) malloc(sizeof(roadNodeY***)*xSize); int i,j,k; - + maxSegmentSize = segmentSize; nbXSubDivision = xSize; nbYSubDivision = ySize; @@ -109,6 +109,63 @@ void grid_initNodesGrid(int width, int height, int segmentSize) { } } +/* Détermine si il existe une intersection entre deux segments de droite. Dans le cas + * ou une intersection existe les coordonnées du point d'intersection sont retournées. + * Dans le cas contraire la fonction retourne NULL. + * @param Vertex *va : Point de départ du premier segment. + * @param Vertex *vb : Point d'arrivé du premier segment. + * @param Vertex *ua : Point de départ du second segment. + * @param Vertex *vb : Point d'arrivé du second segment. + * @return Vertex* : Coordonnées du point d'intersection si il existe, sinon NULL. + */ +Vertex* intersectionBetween(Vertex *va, Vertex *vb, Vertex *ua, Vertex *ub) { + Vertex *inter = (Vertex*) malloc(sizeof(Vertex)); + //int ix, iy; // Coordonnées du point d'intersection. + int m, k; // Coordonnées de l'intersection des vecteurs sur les droites. + int Ix, Iy, Jx, Jy; // Vecteur I et J corespondant au segment v et u; + + Ix = vb->x - va->x; + Iy = vb->y - va->y; + Jx = ub->x - ua->x; + Jy = ub->y - ua->y; + + m = -(-Ix*va->y+Ix*ua->y+Iy*va->x-Iy*ua->x)/(Ix*Jy-Iy*Jx); + k = -(va->x*Jy-ua->x*Jy-Jx*va->y+Jx*ua->y)/(Ix*Jy-Iy*Jx); + + if(m < 1 && m > 0 && k < 1 && k > 0) { + inter->x = va->x + k * Ix; + inter->y = va->y + k * Iy; + } + else + return NULL; + + /* Une solution, mais ne fonctionne peut-être pas dans toutes les conditions (si Bx == vb->x) { + if(va->y == vb->y) + return NULL; + else { + ix = va->x; + iy = ((ua->y-ub->y)/(ua->x-ub->x))*(va->x-ua->x) + ua->y; + } + } + else { + if(ua->x == ub->x) { + ix = ua->x; + iy = ((va->y-vb->y)/(va->x-vb->x))*(ua->x-va->x) + va->y; + } + else { + double pCD = (ua->y-ub->y)/(ua->x-ub->x); + double pAB = (va->y-vb->y)/(va->x-vb->x); + double oCD = ua->y-pCD*ya->x; + double oAB = va->y-pAB*va->x; + ix = (oAB-oCD)/(pCD-pAB); + iy = pCD*ix+oCD; + } + }*/ + + return inter; + } + void grid_drawGrid() { int i, j; @@ -313,6 +370,7 @@ int main() { int n = 5; svg_start(800,600); carreY(); + //int i; //for (i = 0; i < n; i++) { // svg_line(&(points[i]), &(points[(i+1)%n])); From 49ae3608f502111f80ff0fb090e5771b5d85aec7 Mon Sep 17 00:00:00 2001 From: Yoann Date: Sat, 22 Oct 2011 15:41:34 +0200 Subject: [PATCH 11/18] =?UTF-8?q?La=20fonction=20de=20calcul=20d'intersect?= =?UTF-8?q?ion=20viens=20de=20passer=20l'=C3=A9preuve=20du=20test=20basiqu?= =?UTF-8?q?e.=20Prochaine=20=C3=A9tape=20int=C3=A9gration=20de=20cette=20f?= =?UTF-8?q?onction=20dans=20la=20fonction=20d'ajout=20de=20segements.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/roads.c b/roads.c index e767e20..e780cb4 100644 --- a/roads.c +++ b/roads.c @@ -121,7 +121,7 @@ void grid_initNodesGrid(int width, int height, int segmentSize) { Vertex* intersectionBetween(Vertex *va, Vertex *vb, Vertex *ua, Vertex *ub) { Vertex *inter = (Vertex*) malloc(sizeof(Vertex)); //int ix, iy; // Coordonnées du point d'intersection. - int m, k; // Coordonnées de l'intersection des vecteurs sur les droites. + float m, k; // Coordonnées de l'intersection des vecteurs sur les droites. int Ix, Iy, Jx, Jy; // Vecteur I et J corespondant au segment v et u; Ix = vb->x - va->x; @@ -129,9 +129,9 @@ Vertex* intersectionBetween(Vertex *va, Vertex *vb, Vertex *ua, Vertex *ub) { Jx = ub->x - ua->x; Jy = ub->y - ua->y; - m = -(-Ix*va->y+Ix*ua->y+Iy*va->x-Iy*ua->x)/(Ix*Jy-Iy*Jx); - k = -(va->x*Jy-ua->x*Jy-Jx*va->y+Jx*ua->y)/(Ix*Jy-Iy*Jx); - + m = (float)(-(-Ix*va->y+Ix*ua->y+Iy*va->x-Iy*ua->x))/(float)(Ix*Jy-Iy*Jx); + k = (float)(-(va->x*Jy-ua->x*Jy-Jx*va->y+Jx*ua->y))/(float)(Ix*Jy-Iy*Jx); + fprintf(stderr,"k , m : %f %f\n",k,m); if(m < 1 && m > 0 && k < 1 && k > 0) { inter->x = va->x + k * Ix; inter->y = va->y + k * Iy; @@ -370,7 +370,17 @@ int main() { int n = 5; svg_start(800,600); carreY(); - + Vertex a = {1,1}; + Vertex b = {4,1}; + Vertex c = {1,2}; + Vertex d = {4,0}; + + Vertex *inter = intersectionBetween(&a,&b,&c,&d); + if(inter == NULL) + fprintf(stderr,"Pas d'intersection\n"); + else + fprintf(stderr,"intersection : %d %d\n",inter->x,inter->y); + //int i; //for (i = 0; i < n; i++) { // svg_line(&(points[i]), &(points[(i+1)%n])); From 99f5b1ae4423e7f2e9f01ef9e5a3e4c9bd28a964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Sat, 22 Oct 2011 10:27:15 +0200 Subject: [PATCH 12/18] =?UTF-8?q?Notes=20sur=20la=20g=C3=A9n=C3=A9ration?= =?UTF-8?q?=20de=20terrain.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terrain.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 terrain.md diff --git a/terrain.md b/terrain.md new file mode 100644 index 0000000..b486b0a --- /dev/null +++ b/terrain.md @@ -0,0 +1,40 @@ +Liens +----- + +* [Différents algos](http://www.sluniverse.com/php/vb/project-development/34994-automatically-generated-terrain-map.html) : Ridged Perlin Noise, Hills Algorithm, Craters, Erosion. +* [Plein d'algos](http://planetgenesis.sourceforge.net/docs15/noise/noise.html#tileworley) dont plusieurs basés sur une sorte de voronoi donc à priori trop lents. + +Perlin noise +------------ + +Ridged Perlin Noise +------------------- + +[Démo de Ridged Perlin Noise)(http://www.inear.se/2010/04/ridged-perlin-noise/) + + // Fait des crêtes de montagnes ou vallées. + abs(perlinNoise()); + +Hills Algorithm +--------------- + +Inverse de craters : on ajoute plein de cercles : + + repeat 1000 times : + r=random(); + cx=random(); + cy=random(); + terrain[x][y] += r**2 + ((x-cx)**2 – (y-cy)**2) + +Craters +------- + +Soustraire des cercles (profondeur = f(distance au centre)) au terrain +existant. +Ou : générer un terrain nu, et soustraire plein de cercles aléatoirs. + +Erosion +------- + +Modélisation correcte : trop lent. À la place, outil "courbes" de gimp. + From 0ed41f928705e3a9923bb4a29644b791aa2c8efd Mon Sep 17 00:00:00 2001 From: Yoann Date: Sat, 22 Oct 2011 16:49:07 +0200 Subject: [PATCH 13/18] =?UTF-8?q?Ajout=20de=20la=20fonciton=20de=20r=C3=A9?= =?UTF-8?q?cup=C3=A9ration=20des=20segments=20potentiellement=20s=C3=A9can?= =?UTF-8?q?t=20avant=20le=20segment=20constitu=C3=A9=20du=20point=20d'entr?= =?UTF-8?q?=C3=A9e=20de=20la=20fonction.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 103 +++++++++++++++++++++++++++++++++++++------------------- roads.h | 10 ++++-- 2 files changed, 76 insertions(+), 37 deletions(-) diff --git a/roads.c b/roads.c index e780cb4..f7fa0a0 100644 --- a/roads.c +++ b/roads.c @@ -120,7 +120,6 @@ void grid_initNodesGrid(int width, int height, int segmentSize) { */ Vertex* intersectionBetween(Vertex *va, Vertex *vb, Vertex *ua, Vertex *ub) { Vertex *inter = (Vertex*) malloc(sizeof(Vertex)); - //int ix, iy; // Coordonnées du point d'intersection. float m, k; // Coordonnées de l'intersection des vecteurs sur les droites. int Ix, Iy, Jx, Jy; // Vecteur I et J corespondant au segment v et u; @@ -131,37 +130,13 @@ Vertex* intersectionBetween(Vertex *va, Vertex *vb, Vertex *ua, Vertex *ub) { m = (float)(-(-Ix*va->y+Ix*ua->y+Iy*va->x-Iy*ua->x))/(float)(Ix*Jy-Iy*Jx); k = (float)(-(va->x*Jy-ua->x*Jy-Jx*va->y+Jx*ua->y))/(float)(Ix*Jy-Iy*Jx); - fprintf(stderr,"k , m : %f %f\n",k,m); + if(m < 1 && m > 0 && k < 1 && k > 0) { inter->x = va->x + k * Ix; inter->y = va->y + k * Iy; } else return NULL; - - /* Une solution, mais ne fonctionne peut-être pas dans toutes les conditions (si Bx == vb->x) { - if(va->y == vb->y) - return NULL; - else { - ix = va->x; - iy = ((ua->y-ub->y)/(ua->x-ub->x))*(va->x-ua->x) + ua->y; - } - } - else { - if(ua->x == ub->x) { - ix = ua->x; - iy = ((va->y-vb->y)/(va->x-vb->x))*(ua->x-va->x) + va->y; - } - else { - double pCD = (ua->y-ub->y)/(ua->x-ub->x); - double pAB = (va->y-vb->y)/(va->x-vb->x); - double oCD = ua->y-pCD*ya->x; - double oAB = va->y-pAB*va->x; - ix = (oAB-oCD)/(pCD-pAB); - iy = pCD*ix+oCD; - } - }*/ return inter; } @@ -272,17 +247,37 @@ roadNodeY* insertRoadSegment(roadPointY *road, roadNodeY *rnb, roadNodeY *rne, i float coef = ((float)segLength-lag)/(float)segLength; roadNodeY *nearestNode = NULL; Vertex tmpEnd; - tmpEnd.x = rnb->v->x+coef*(rne->v->x - rnb->v->x); - tmpEnd.y = rnb->v->y+coef*(rne->v->y - rnb->v->y); - fprintf(stderr,"segLength : %d\n",segLength); - fprintf(stderr," ostart : %d %d\t oend : %d %d\n",rnb->v->x,rnb->v->y,rne->v->x,rne->v->y); - fprintf(stderr," end : %d %d\n",tmpEnd.x,tmpEnd.y); - nearestNode = grid_getNearestRoadNode(&tmpEnd); - fprintf(stderr,"--11\n"); + // ------- TODO à compléter et à vérifier. + Segment **segs = grid_getNearSegments(rnb->v->x,rnb->v->y); + Segment *seg = segs[0]; + int s = 0; + int intersec = 0; // Booléen si intersection = 1 sinon = 0; - if(nearestNode != NULL && distBetween(nearestNode->v,rne->v) < lag) - rne = nearestNode; + while(seg != NULL) { + Vertex *intersection = intersectionBetween(rnb->v,rne->v,seg->u,seg->v); + + if(intersection != NULL) { + // Créer un nœd, l'insérer au segment qui à causé l'intersection. + // Ce nœd deviens le point d'arriver du segment à placer : rne; + intersec = 1; + } + seg = segs[s++]; + } + // ------- + if(intersec == 0) { + tmpEnd.x = rnb->v->x+coef*(rne->v->x - rnb->v->x); + tmpEnd.y = rnb->v->y+coef*(rne->v->y - rnb->v->y); + fprintf(stderr,"segLength : %d\n",segLength); + fprintf(stderr," ostart : %d %d\t oend : %d %d\n",rnb->v->x,rnb->v->y,rne->v->x,rne->v->y); + fprintf(stderr," end : %d %d\n",tmpEnd.x,tmpEnd.y); + nearestNode = grid_getNearestRoadNode(&tmpEnd); + + fprintf(stderr,"--11\n"); + + if(nearestNode != NULL && distBetween(nearestNode->v,rne->v) < lag) + rne = nearestNode; + } grid_insertRoadNode(rnb); grid_insertRoadNode(rne); @@ -302,6 +297,44 @@ roadNodeY** grid_getNearNodes2(int x, int y) { return nodesGrid[x][y]; } +/* Récupère tout les segement potentiellement sécant avec un segment ayant pour arrivée x et y. + */ +Segment** grid_getNearSegments(int x, int y) { + roadNodeY **nr, *tmpnr; + Segment** segs = (Segment**) malloc(sizeof(Segment)*9*maxNodesInGrid); + int i, j, s, k, l; + + s = 0; + + for(i=x-1;i= 0 && x < nbXSubDivision && y >= 0 && y < nbYSubDivision) { + nr = grid_getNearNodes2(i,j); + k = 0; + tmpnr = nr[0]; + + // TODO Tester si le segment existe déjà dans la liste pour ne pas l'insérer en double. + + while(tmpnr != NULL) { + for(l=0;lnbIntersec;l++) { + if(tmpnr->intersec[l]->next != NULL) { + segs[s]->u = tmpnr->v; + segs[s]->v = tmpnr->intersec[l]->next->v; + } + s++; + if(tmpnr->intersec[l]->previous != NULL) { + segs[s]->u = tmpnr->v; + segs[s]->v = tmpnr->intersec[l]->previous->v; + } + } + tmpnr = nr[k++]; + } + } + } + } + return segs; +} + void carreY() { grid_initNodesGrid(800,600,10); roadPointY *roada = (roadPointY*) malloc(sizeof(roadPointY)); diff --git a/roads.h b/roads.h index fe18c5a..48dc7ac 100644 --- a/roads.h +++ b/roads.h @@ -7,6 +7,11 @@ typedef struct Vertex { int y; } Vertex; +typedef struct Segment { + Vertex *u; + Vertex *v; +} Segment; + typedef Vertex Polygon; /* Cette structure définie un nœd de route. Le nœd contient la liste de toute les intersections. @@ -14,14 +19,14 @@ typedef Vertex Polygon; typedef struct roadNodeY { Vertex *v; short nbIntersec; - struct intersectionY *intersec; + struct intersectionY **intersec; } roadNodeY; /* Définition d'une intersection. Permet de savoir quelle route est concernée par cette intersection. * Elle permet également de changer la navigation por parcourir une nouvelle route. * */ typedef struct intersectionY { - roadNodeY roadId; // Premier nœd de la route qui lui sert d'identifiant. + roadNodeY *roadId; // Premier nœd de la route qui lui sert d'identifiant. roadNodeY *next; // Nœd de la route juste après l'intersection. roadNodeY *previous; // Nœd de la route juste avant l'intersection. int zIndex; // Index sur l'axe z de la route. @@ -64,3 +69,4 @@ roadNodeY* grid_getNearestRoadNode(Vertex *v); void grid_drawGrid(); cartesianCoord* ptc(Vertex *origin, short angle, short length); polarCoord* ctp(Vertex *origin, Vertex *end); +Segment** grid_getNearSegments(int x, int y); From 811e425a619209837e82f770cd0824b070753369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Sat, 22 Oct 2011 18:39:46 +0200 Subject: [PATCH 14/18] Algo champs de force dans `roads.md` . --- roads.c | 14 ++++++++++---- roads.h | 20 ++++++++++---------- roads.md | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/roads.c b/roads.c index f7fa0a0..7896168 100644 --- a/roads.c +++ b/roads.c @@ -69,7 +69,7 @@ cartesianCoord* ptc(Vertex *origin, short angle, short length) { /* Convertion de coordonnées cartésiennes en coordonnées polaires. * @param Vertex* origin : Origine du vecteur. - * * @param Vertex* end : Fin du vecteur. + * @param Vertex* end : Fin du vecteur. * @return struct polarCoord* : Les coordonnées polaires du point d'arrivée. */ polarCoord* ctp(Vertex *origin, Vertex *end) { @@ -80,7 +80,7 @@ polarCoord* ctp(Vertex *origin, Vertex *end) { return pc; } -/* Initialise la grille de nœds. +/* Initialise la grille de nœuds. * @param int width : Largeur du quartier à remplir. * @param int height : Hauteur du quartier à remplir. * @param int maxSegmentSize : Taille maximale d'un segment de route. @@ -120,8 +120,8 @@ void grid_initNodesGrid(int width, int height, int segmentSize) { */ Vertex* intersectionBetween(Vertex *va, Vertex *vb, Vertex *ua, Vertex *ub) { Vertex *inter = (Vertex*) malloc(sizeof(Vertex)); - float m, k; // Coordonnées de l'intersection des vecteurs sur les droites. - int Ix, Iy, Jx, Jy; // Vecteur I et J corespondant au segment v et u; + float m, k; // Coordonnées de l'intersection des vecteurs sur les droites. + int Ix, Iy, Jx, Jy; // Vecteur I et J corespondant au segment v et u; Ix = vb->x - va->x; Iy = vb->y - va->y; @@ -183,6 +183,8 @@ void addRoadNode(roadPointY *rp, roadNodeY *rn) { rpp->next = NULL; rpp->rn = rn; rp->next = rpp; + // TODO : previous + // TODO modif les intersections de previous. } /* Retourne le nœd le plus proche dans un certain voisinage. Si aucun nœd n'est trouvé alors @@ -392,6 +394,10 @@ void carreY() { } } +void genroads() { + +} + int main() { Vertex points[] = { { .x=10, .y=10 }, diff --git a/roads.h b/roads.h index 48dc7ac..a4fcd5c 100644 --- a/roads.h +++ b/roads.h @@ -22,16 +22,6 @@ typedef struct roadNodeY { struct intersectionY **intersec; } roadNodeY; -/* Définition d'une intersection. Permet de savoir quelle route est concernée par cette intersection. - * Elle permet également de changer la navigation por parcourir une nouvelle route. - * */ -typedef struct intersectionY { - roadNodeY *roadId; // Premier nœd de la route qui lui sert d'identifiant. - roadNodeY *next; // Nœd de la route juste après l'intersection. - roadNodeY *previous; // Nœd de la route juste avant l'intersection. - int zIndex; // Index sur l'axe z de la route. -} intersectionY; - typedef struct roadPointY { struct roadPointY *first; struct roadPointY *next; @@ -39,6 +29,16 @@ typedef struct roadPointY { roadNodeY *rn; } roadPointY; +/* Définition d'une intersection. Permet de savoir quelle route est concernée par cette intersection. + * Elle permet également de changer la navigation por parcourir une nouvelle route. + * */ +typedef struct intersectionY { + roadPointY *roadId; // Premier point de la route qui lui sert d'identifiant. + roadNodeY *next; // Nœd de la route juste après l'intersection. + roadNodeY *previous; // Nœd de la route juste avant l'intersection. + int zIndex; // Index sur l'axe z de la route. +} intersectionY; + typedef struct cartesianCoord { int x; // Coordonnées sur x. int y; // Coordonnées sur y. diff --git a/roads.md b/roads.md index 5ab81e8..5f31cc9 100644 --- a/roads.md +++ b/roads.md @@ -154,3 +154,19 @@ coordonnées dessus, plus une fonction de densité de points (taille des bâtiments). Dé-transformer la fonction de densité de points, l'utiliser pour générer la grille parfaite avec des densités différentes, puis transformer cette grille. + +Algo champs de force +==================== + +* Choisir des champs de force. `f(x,y,vecteur,n)` renvoie le nième + vecteur de routes qu'on peut faire partir du point `(x,y)`, + lorsqu'on y arrive par la direction vecteur. +* Initialiser `fifo` à vide. +* Choisir un point de départ aléatoire, une direction aléatoire, et + insérer `(x,y,vecteur,0)` dans `fifo`. +* Tant qu'on n'a pas suffisemment créé de routes : + * Prendre le point `(x,y,vecteur,n)` en tête de `fifo`. + * new = f(x,y,vecteur,n). + * Si new != NULL, tracer le segment `(x,y)--(new)`. + * insérer `(x,y,vecteur,n+1)` dans `fifo` si new dit que n+1 existe. + * insérer `(new,(x,y)--(new),0) dans `fifo`. From 81c6c35bfc4c1bd05a3f6ce6eb62108ca0a86252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Sat, 22 Oct 2011 19:13:17 +0200 Subject: [PATCH 15/18] =?UTF-8?q?Premi=C3=A8re=20version=20approximative?= =?UTF-8?q?=20de=20l'algo=20=C2=AB=C2=A0champs=20de=20force=C2=A0=C2=BB.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- roads.md | 6 +++--- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/roads.c b/roads.c index 7896168..91f8c5a 100644 --- a/roads.c +++ b/roads.c @@ -394,8 +394,59 @@ void carreY() { } } -void genroads() { - +// Algo « champs de force » +typedef struct Vector { float x; float y; }; +typedef struct VectorListItem { Vector v; struct VectorNext* next; }; +typedef struct VectorList { VectorListItem* head; VectorListItem* tail; }; +inline VectorListItem vectorList_pop(VectorList l) { + VectorListItem vn = l->head; + if (vn != NULL) l->head = vn->next; + if (l->head == NULL) l->tail = NULL; + return vn; +} +// Append `b` after `a`. `b` is modified and damaged. +inline void vectorList_append(VectorList a, VectorList b) { + if (b->head == NULL) return; + if (a->tail == NULL) { + a->head = b->head; + a->tail = b->tail; + } else { + a->tail->next = b->head; + a->tail = b->tail; + } +} + +/* Choisir des champs de force. `f(x,y,vecteur)` renvoie tous les + * vecteurs de routes qu'on peut faire partir du point `(x,y)`, + * lorsqu'on y arrive par la direction `vecteur`. */ +// champ de force "ligne droite". +// TODO : devrait prendre un segment en paramètre. +VectorList f(Vector xy, Vector previous) { + VectorListItem vli = malloc(sizeof(VectorListItem)); + vli.v = vecteur; + vli.next = NULL; + return { .head = vli, .tail = vli }; + // TODO : tracer chaque segment créé ici. + // TODO : les insérer dans fifo ici. +} + +void forceFields() { + /* Initialiser `fifo` à vide. */ + /* Choisir un point de départ aléatoire, une direction aléatoire, + * et insérer `(x,y,vecteur)` dans `fifo`. */ + Vector origin = { .x = 0, .y = 0 }; + Vector origin_direction = { .x = 1, .y = 0 }; + VectorList fifoA = { .head = &origin, .tail = &origin }; + VectorList fifoB = { .head = &origin_direction, .tail = &origin_direction }; + /* Tant qu'on n'a pas suffisemment créé de routes : */ + int i; + for (i = 0; i < 1000; i++) { + /* Prendre le point `(x,y,vecteur)` en tête de `fifo`. */ + Vector* xy = vectorList_pop(fifoA); + Vector* previous = vectorList_pop(fifoB); + /* new = f(x,y,vecteur,n). */ + f(xy, previous); + } } int main() { diff --git a/roads.md b/roads.md index 5f31cc9..934583d 100644 --- a/roads.md +++ b/roads.md @@ -158,9 +158,9 @@ différentes, puis transformer cette grille. Algo champs de force ==================== -* Choisir des champs de force. `f(x,y,vecteur,n)` renvoie le nième - vecteur de routes qu'on peut faire partir du point `(x,y)`, - lorsqu'on y arrive par la direction vecteur. +* Choisir des champs de force. `f(x,y,vecteur)` renvoie tous les + vecteurs de routes qu'on peut faire partir du point `(x,y)`, + lorsqu'on y arrive par la direction `vecteur`. * Initialiser `fifo` à vide. * Choisir un point de départ aléatoire, une direction aléatoire, et insérer `(x,y,vecteur,0)` dans `fifo`. From 3664e1260b653b89f6cfc19df30518a69d7d1169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Sun, 23 Oct 2011 15:36:11 +0200 Subject: [PATCH 16/18] =?UTF-8?q?Algo=20de=20g=C3=A9n=C3=A9ration=20de=20r?= =?UTF-8?q?outes=20n'utilisant=20pas=20encore=20le=20rattachement=20=C3=A0?= =?UTF-8?q?=20des=20points=20proches.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 94 +++++++++++++++++++++++++++++++++----------------------- roads.md | 10 ++++++ 2 files changed, 65 insertions(+), 39 deletions(-) diff --git a/roads.c b/roads.c index 91f8c5a..3a3fe47 100644 --- a/roads.c +++ b/roads.c @@ -9,7 +9,7 @@ void svg_end() { printf(""); } -void svg_line(Vertex* a, Vertex* b,short color) { +void svg_line(Vertex* a, Vertex* b, short color) { if(color == 0) printf("", a->x, a->y, b->x, b->y); else if(color == 1) @@ -395,25 +395,26 @@ void carreY() { } // Algo « champs de force » -typedef struct Vector { float x; float y; }; -typedef struct VectorListItem { Vector v; struct VectorNext* next; }; -typedef struct VectorList { VectorListItem* head; VectorListItem* tail; }; -inline VectorListItem vectorList_pop(VectorList l) { - VectorListItem vn = l->head; - if (vn != NULL) l->head = vn->next; - if (l->head == NULL) l->tail = NULL; - return vn; +typedef struct FVector { float x; float y; } FVector; +inline FVector fVector_substract(FVector a, FVector b) { return (FVector){ .x = a.x - b.x, .y = a.y - b.y }; } +inline FVector fVector_add(FVector a, FVector b) { return (FVector){ .x = a.x + b.x, .y = a.y + b.y }; } +inline FVector fVector_rotate90(FVector v) { return (FVector){ .x = -v.y, .y = v.x }; } + +typedef struct FSegment { FVector from; FVector to; } FSegment; +inline void fsegment_display(FSegment s) { + printf("", s.from.x, s.from.y, s.to.x, s.to.y); } -// Append `b` after `a`. `b` is modified and damaged. -inline void vectorList_append(VectorList a, VectorList b) { - if (b->head == NULL) return; - if (a->tail == NULL) { - a->head = b->head; - a->tail = b->tail; - } else { - a->tail->next = b->head; - a->tail = b->tail; - } + +// TODO : dimensionner correctement le tableau. +#define FSegmentArray_SIZE 1024 +typedef struct FSegmentArray { FSegment seg[FSegmentArray_SIZE]; int firstUnseen; int firstFree; /* + CollisionGrid collision; */ } FSegmentArray; +inline void fSegmentArray_push(FSegmentArray* a, FSegment s) { + // TODO : check for collisions. + if (a->firstFree >= FSegmentArray_SIZE) return; + a->seg[a->firstFree++] = s; +} +inline FSegment fSegmentArray_pop(FSegmentArray* a) { + return a->seg[a->firstUnseen++]; } /* Choisir des champs de force. `f(x,y,vecteur)` renvoie tous les @@ -421,31 +422,45 @@ inline void vectorList_append(VectorList a, VectorList b) { * lorsqu'on y arrive par la direction `vecteur`. */ // champ de force "ligne droite". // TODO : devrait prendre un segment en paramètre. -VectorList f(Vector xy, Vector previous) { - VectorListItem vli = malloc(sizeof(VectorListItem)); - vli.v = vecteur; - vli.next = NULL; - return { .head = vli, .tail = vli }; - // TODO : tracer chaque segment créé ici. - // TODO : les insérer dans fifo ici. +void f(FSegment s, FSegmentArray* a) { + FVector delta = fVector_substract(s.to, s.from); + FSegment newS = { + .from = s.to, + .to = fVector_add(s.to, delta), + }; + // TODO : s'accrocher aux points proches, et ne pas ajouter le segment à la queue si on s'accroche à un point existant. + // TODO : ne pas utiliser des segments dans la file d'attente, mais juste des vertex, dont on peut énumérer les segments. + fSegmentArray_push(a, newS); + FSegment newS2 = { + .from = s.to, + .to = fVector_add(s.to, fVector_rotate90(delta)), + }; + newS2.to.y += 3; + fSegmentArray_push(a, newS2); } void forceFields() { /* Initialiser `fifo` à vide. */ /* Choisir un point de départ aléatoire, une direction aléatoire, * et insérer `(x,y,vecteur)` dans `fifo`. */ - Vector origin = { .x = 0, .y = 0 }; - Vector origin_direction = { .x = 1, .y = 0 }; - VectorList fifoA = { .head = &origin, .tail = &origin }; - VectorList fifoB = { .head = &origin_direction, .tail = &origin_direction }; - /* Tant qu'on n'a pas suffisemment créé de routes : */ + FSegmentArray a; + a.seg[0] = (FSegment){ + .from = { .x = 100, .y = 100 }, + .to = { .x = 90, .y = 100 } + }; + a.firstUnseen = 0; + a.firstFree = 1; + + grid_initNodesGrid(800, 600, 20); + int i; - for (i = 0; i < 1000; i++) { - /* Prendre le point `(x,y,vecteur)` en tête de `fifo`. */ - Vector* xy = vectorList_pop(fifoA); - Vector* previous = vectorList_pop(fifoB); - /* new = f(x,y,vecteur,n). */ - f(xy, previous); + for (i = 0; i < FSegmentArray_SIZE; i++) { + f(fSegmentArray_pop(&a), &a); + } + + grid_drawGrid(); + for (i = 0; i < FSegmentArray_SIZE; i++) { + fsegment_display(a.seg[i]); } } @@ -459,7 +474,8 @@ int main() { }; int n = 5; svg_start(800,600); - carreY(); + //carreY(); + forceFields(); Vertex a = {1,1}; Vertex b = {4,1}; Vertex c = {1,2}; @@ -476,7 +492,7 @@ int main() { // svg_line(&(points[i]), &(points[(i+1)%n])); // } - grid_drawGrid(); +// grid_drawGrid(); n=n; //roads(points); diff --git a/roads.md b/roads.md index 934583d..a7dfbd0 100644 --- a/roads.md +++ b/roads.md @@ -170,3 +170,13 @@ Algo champs de force * Si new != NULL, tracer le segment `(x,y)--(new)`. * insérer `(x,y,vecteur,n+1)` dans `fifo` si new dit que n+1 existe. * insérer `(new,(x,y)--(new),0) dans `fifo`. + +Représentation simpliste des segments et routes +=============================================== + +* Dans chaque vertex, avoir un pointeur vers un des segments auxquels + il appartient. +* Dans chaque segment, avoir un pointeur vers le segment de même + origine suivant dans le sens des aiguilles d'une montre. +* Dans chaque segment, avoir un pointeur vers le segment de même + extrémité suivant dans le sens des aiguilles d'une montre. From 49007da5291dc4daabbdec88d89d2f7907600924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Mon, 24 Oct 2011 10:37:39 +0200 Subject: [PATCH 17/18] =?UTF-8?q?Description=20de=20l'algorithme=20de=20d?= =?UTF-8?q?=C3=A9coupage=20des=20polygones.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/roads.md b/roads.md index a7dfbd0..a6db3b3 100644 --- a/roads.md +++ b/roads.md @@ -180,3 +180,18 @@ Représentation simpliste des segments et routes origine suivant dans le sens des aiguilles d'une montre. * Dans chaque segment, avoir un pointeur vers le segment de même extrémité suivant dans le sens des aiguilles d'une montre. + +Algorithme de maintien des polygones +==================================== + +* Partir du périmètre du polygone de base. +* Lorsqu'on ajoute un segment partant d'un point de ce périmètre, + étendre ce périmètre pour qu'il fasse l'aller-retour sur le segment. +* Lorsqu'on ajoute un segment reliant deux points existants du + périmètre, séparer le périmètre en deux : le périmètre passant par + le côté gauche du segment, et celui passant par le côté droit du + segment. +* TODO : gestion possible des « trous » ? (càd quand on ajoute un + segment qui n'est pas relié au périmètre). Serait pratique pour + pouvoir ajouter certains gros bâtiments avant la création des + routes. From 04f08e5362301b5b379e31bac37563d9459ed639 Mon Sep 17 00:00:00 2001 From: Yoann Date: Mon, 24 Oct 2011 11:18:12 +0200 Subject: [PATCH 18/18] =?UTF-8?q?Red=C3=A9finition=20de=20quelques=20fonti?= =?UTF-8?q?on=20pour=20coller=20avec=20l'algo=20de=20g=C3=A9n=C3=A9ration?= =?UTF-8?q?=20de=20route.=20Pas=20termin=C3=A9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roads.c | 174 +++++++++++++++++++++++++++++++------------------------- roads.h | 9 ++- 2 files changed, 104 insertions(+), 79 deletions(-) diff --git a/roads.c b/roads.c index 3a3fe47..25dc3d5 100644 --- a/roads.c +++ b/roads.c @@ -33,6 +33,41 @@ void roads(Polygon* quartier) { /* Fonctions de Yoann suffixée par "Y" */ +/* !!!!!!!! Modification de façon de gérer les routes. + * Au départ : + * - Une liste de routes vide. + * - Une grille de nœd de routes vide qui contiendra les nœds de de toutes les routes. + * Initialisation : + * - On initialise la grille avec la taille de la zone à remplir et le nombre max de nœds dans chaque cases. + * - On crée une ou plusieurs routes sue l'on insère dans la liste de routes et on place les nœds de + * ces routes dans la grille. + * Fonctionnement : + * -- La fonction addRoadNode : + * Ajoute un nœed à la route depuis un certain point de route. Si ce point de route n'est pas le dernier + * autrement dit si on crée une division de route alors la nouvelle voie créée constitue une nouvelle route. Et le + * point de route situé à l'intersection est le point d'origine de la nouvelle route. + */ + /* ForceField revision : + * - Initialisation de la grille en fonction de la zone à couvrir. + * - Création d'une ou plusieurs routes de départ et insertion dan sla liste de routes. + * - Création d'un file (fifo) permettant l'avancé parrallèle de la création de routes. + * Cette liste sera constituée de structures à deux champs, l'identifiant de la route et le nœd où on s'est arrêté. + * - Tant que l'on à pas atteint la fin de la file on utilise le premier point de route non vu. + * Et on ajoute à la route le ou les nouveau segments retournées par la fonction f potentiellement filtrée. + * Ces nouveau morceaux de routes seraont également ajouté dans la file pour qu'il puissent faire l'objet d'un + * nouveau départ de route(s). Si une route est créer par division de route existante alors cette route sera ajoutée dans la liste de routes. + * ... + * !!!!!!!!! */ + + + +/* Initialisation de la liste de routes. + */ +void initRoadslIst(int nb){ + roadsList = (roadPointY**) malloc(sizeof(roadPointY*)*nb); +} + + /* La route est constituée d'une série de points, chaque point contient un nœd de route qui peut-être propre à cette route comme * appartenir à plusieurs routes. Le nœd contient un Vertex qui permet de le positionner sur la carte. Il contient également * le nombre et les portions de routes auxquelles il appartient. @@ -46,6 +81,7 @@ int toX(Vertex *v) { return x; } + // Transforme des coordonnées du plan en coordonées du tableau sur y. int toY(Vertex *v) { int y = v->y*(nbYSubDivision)/quarterHeight; @@ -53,6 +89,7 @@ int toY(Vertex *v) { return y; } + /* Convertion de coordonnées polaires en coordonnées cartésiennes. * @param Vertex* origin : Origine du vecteur. * @param short angle : Angle. @@ -67,6 +104,7 @@ cartesianCoord* ptc(Vertex *origin, short angle, short length) { return cc; } + /* Convertion de coordonnées cartésiennes en coordonnées polaires. * @param Vertex* origin : Origine du vecteur. * @param Vertex* end : Fin du vecteur. @@ -80,6 +118,7 @@ polarCoord* ctp(Vertex *origin, Vertex *end) { return pc; } + /* Initialise la grille de nœuds. * @param int width : Largeur du quartier à remplir. * @param int height : Hauteur du quartier à remplir. @@ -109,6 +148,7 @@ void grid_initNodesGrid(int width, int height, int segmentSize) { } } + /* Détermine si il existe une intersection entre deux segments de droite. Dans le cas * ou une intersection existe les coordonnées du point d'intersection sont retournées. * Dans le cas contraire la fonction retourne NULL. @@ -139,7 +179,8 @@ Vertex* intersectionBetween(Vertex *va, Vertex *vb, Vertex *ua, Vertex *ub) { return NULL; return inter; - } +} + void grid_drawGrid() { int i, j; @@ -155,6 +196,7 @@ void grid_drawGrid() { } } + short grid_insertRoadNode(roadNodeY *rn) { if(rn == NULL || rn->v == NULL) return 0; @@ -170,23 +212,43 @@ short grid_insertRoadNode(roadNodeY *rn) { return 0; } -void addRoadNode(roadPointY *rp, roadNodeY *rn) { - if(rp->rn == NULL) { + +roadStep* addRoadNode(roadPointY *rp, roadPointY *rpc, roadNodeY *rn) { + roadStep * rStep = (roadStep*) malloc(sizeof(roadStep)); + + if(rpc == rp) { rp->next = NULL; + rp->previous = NULL; rp->rn = rn; - return; + rStep->roadId = rp; + rStep->rpc = rp; + return rStep; } - while(rp->next != NULL) - rp = rp->next; - + roadPointY *rpp = (roadPointY*) malloc(sizeof(roadPointY)); rpp->next = NULL; - rpp->rn = rn; - rp->next = rpp; - // TODO : previous + + if(rpc->next != NULL) { + rpp->previous = NULL; + rpp->rn = rn; + rStep->roadId = rpp; + rStep->rpc = rpp; + return rStep; + } + else { + rpp->previous = rpc; + rpp->rn = rn; + rpc->next = rpp; + rStep->roadId = rp; + rStep->rpc = rpp; + } + + return rStep; + // TODO modif les intersections de previous. } + /* Retourne le nœd le plus proche dans un certain voisinage. Si aucun nœd n'est trouvé alors * la fonction renvoie NULL. * @param Vertex *v : Le nœd pour lequel on souhaite trouver un nœd proche. @@ -229,6 +291,7 @@ roadNodeY* grid_getNearestRoadNode(Vertex *v) { return nearestNode; } + /* Ajoute un segment de route à la fin d'une route. * Le point d'origine du segment est le dernier de la route actuellement en place. Il est passé en paramètre pour * éviter le parcour de la route entière pour le trouver. @@ -244,20 +307,21 @@ roadNodeY* grid_getNearestRoadNode(Vertex *v) { * @param int lag : le décalage maximal autorisé pour le placement du nœd d'arrivé. * @return roadNodeY* : Le nœd d'arrivé du vecteur potentiellement modifié. */ -roadNodeY* insertRoadSegment(roadPointY *road, roadNodeY *rnb, roadNodeY *rne, int lag) { - int segLength = distBetween(rnb->v, rne->v); +roadStep* insertRoadSegment(roadPointY *road, roadPointY *rpb, roadNodeY *rne, int lag) { + int segLength = distBetween(rpb->rn->v, rne->v); float coef = ((float)segLength-lag)/(float)segLength; roadNodeY *nearestNode = NULL; Vertex tmpEnd; + roadStep * rstep; // ------- TODO à compléter et à vérifier. - Segment **segs = grid_getNearSegments(rnb->v->x,rnb->v->y); + Segment **segs = grid_getNearSegments(rpb->rn->v->x,rpb->rn->v->y); Segment *seg = segs[0]; int s = 0; int intersec = 0; // Booléen si intersection = 1 sinon = 0; while(seg != NULL) { - Vertex *intersection = intersectionBetween(rnb->v,rne->v,seg->u,seg->v); + Vertex *intersection = intersectionBetween(rpb->rn->v,rne->v,seg->u,seg->v); if(intersection != NULL) { // Créer un nœd, l'insérer au segment qui à causé l'intersection. @@ -268,10 +332,10 @@ roadNodeY* insertRoadSegment(roadPointY *road, roadNodeY *rnb, roadNodeY *rne, i } // ------- if(intersec == 0) { - tmpEnd.x = rnb->v->x+coef*(rne->v->x - rnb->v->x); - tmpEnd.y = rnb->v->y+coef*(rne->v->y - rnb->v->y); + tmpEnd.x = rpb->rn->v->x+coef*(rne->v->x - rpb->rn->v->x); + tmpEnd.y = rpb->rn->v->y+coef*(rne->v->y - rpb->rn->v->y); fprintf(stderr,"segLength : %d\n",segLength); - fprintf(stderr," ostart : %d %d\t oend : %d %d\n",rnb->v->x,rnb->v->y,rne->v->x,rne->v->y); + fprintf(stderr," ostart : %d %d\t oend : %d %d\n",rpb->rn->v->x,rpb->rn->v->y,rne->v->x,rne->v->y); fprintf(stderr," end : %d %d\n",tmpEnd.x,tmpEnd.y); nearestNode = grid_getNearestRoadNode(&tmpEnd); @@ -281,12 +345,12 @@ roadNodeY* insertRoadSegment(roadPointY *road, roadNodeY *rnb, roadNodeY *rne, i rne = nearestNode; } - grid_insertRoadNode(rnb); grid_insertRoadNode(rne); - addRoadNode(road,rne); - return rne; + rstep = addRoadNode(road,rpb,rne); + return rstep; } + int distBetween(Vertex *v, Vertex *u) { return sqrt((v->x-u->x)*(v->x-u->x)+(v->y-u->y)*(v->y-u->y)); } @@ -295,10 +359,12 @@ roadNodeY** grid_getNearNodes(Vertex *v) { return nodesGrid[toX(v)][toY(v)]; } + roadNodeY** grid_getNearNodes2(int x, int y) { return nodesGrid[x][y]; } + /* Récupère tout les segement potentiellement sécant avec un segment ayant pour arrivée x et y. */ Segment** grid_getNearSegments(int x, int y) { @@ -337,62 +403,10 @@ Segment** grid_getNearSegments(int x, int y) { return segs; } -void carreY() { - grid_initNodesGrid(800,600,10); - roadPointY *roada = (roadPointY*) malloc(sizeof(roadPointY)); - roadPointY *roadb = (roadPointY*) malloc(sizeof(roadPointY)); - roadNodeY *rn; - Vertex *v; - roadNodeY *lastNode = NULL; - int i; - - for(i=0;i<36;i++) { - rn = (roadNodeY*)malloc(sizeof(roadNodeY)); - v = (Vertex*) malloc(sizeof(Vertex)); - - v->x = (i+1)*16; - v->y = ((i+1)%3)*(61%(i+1))+100; - rn->v = v; - grid_insertRoadNode(rn); - addRoadNode(roada,rn); - } - - for(i=0;i<30;i++) { - rn = (roadNodeY*)malloc(sizeof(roadNodeY)); - v = (Vertex*) malloc(sizeof(Vertex)); - - v->x = (i+1)*22; - v->y = ((i+1)%5)*(61%(i+2))+120; - rn->v = v; - if(i==4) {fprintf(stderr,"x : %d y : %d\n",toX(v),toY(v));} - if(v->x < 800 && v->y < 600) { - fprintf(stderr,"Noed : %d\n",i); - if(i==0) { - addRoadNode(roadb,rn); - lastNode = rn; - } - else { - insertRoadSegment(roadb,lastNode,rn,10); - lastNode = rn; - } - } - } - - roadPointY *rd = roada; - while(rd->next != NULL) { - svg_line(rd->rn->v,rd->next->rn->v,1); - svg_circle(rd->rn->v->x,rd->rn->v->y,1); - rd = rd->next; - } - - rd = roadb; - while(rd->next != NULL) { - svg_line(rd->rn->v,rd->next->rn->v,2); - svg_circle(rd->rn->v->x,rd->rn->v->y,1); - rd = rd->next; - } -} + + + // Algo « champs de force » typedef struct FVector { float x; float y; } FVector; @@ -405,6 +419,7 @@ inline void fsegment_display(FSegment s) { printf("", s.from.x, s.from.y, s.to.x, s.to.y); } + // TODO : dimensionner correctement le tableau. #define FSegmentArray_SIZE 1024 typedef struct FSegmentArray { FSegment seg[FSegmentArray_SIZE]; int firstUnseen; int firstFree; /* + CollisionGrid collision; */ } FSegmentArray; @@ -417,6 +432,7 @@ inline FSegment fSegmentArray_pop(FSegmentArray* a) { return a->seg[a->firstUnseen++]; } + /* Choisir des champs de force. `f(x,y,vecteur)` renvoie tous les * vecteurs de routes qu'on peut faire partir du point `(x,y)`, * lorsqu'on y arrive par la direction `vecteur`. */ @@ -439,19 +455,20 @@ void f(FSegment s, FSegmentArray* a) { fSegmentArray_push(a, newS2); } + void forceFields() { /* Initialiser `fifo` à vide. */ /* Choisir un point de départ aléatoire, une direction aléatoire, * et insérer `(x,y,vecteur)` dans `fifo`. */ FSegmentArray a; a.seg[0] = (FSegment){ - .from = { .x = 100, .y = 100 }, - .to = { .x = 90, .y = 100 } + .from = { .x = 400, .y = 300 }, + .to = { .x = 360, .y = 300 } }; a.firstUnseen = 0; a.firstFree = 1; - grid_initNodesGrid(800, 600, 20); + grid_initNodesGrid(800, 600, 40); int i; for (i = 0; i < FSegmentArray_SIZE; i++) { @@ -464,6 +481,7 @@ void forceFields() { } } + int main() { Vertex points[] = { { .x=10, .y=10 }, diff --git a/roads.h b/roads.h index a4fcd5c..08e7062 100644 --- a/roads.h +++ b/roads.h @@ -49,7 +49,14 @@ typedef struct polarCoord { int length; // Norme du vecteur. } polarCoord; +typedef struct roadSet { + roadPointY *roadId; // Identifiant de la route. + roadPointY *rpc; // Nœd courrant. +} roadStep; + + roadNodeY ****nodesGrid; +roadPointY **roadsList; short nbXSubDivision; short nbYSubDivision; short maxSegmentSize; @@ -61,7 +68,7 @@ int toX(Vertex*); int toY(Vertex*); void grid_initNodesGrid(int w, int h, int maxSegmentSize); short grid_insertRoadNode(roadNodeY *rn); -void addRoadNode(roadPointY *rp, roadNodeY *rn); +roadStep* addRoadNode(roadPointY *rp, roadPointY *rpc, roadNodeY *rn); int distBetween(Vertex *v, Vertex *u); roadNodeY** grid_getNearNodes(Vertex *v); roadNodeY** grid_getNearNodes2(int x, int y);