commit 6a420da8ac549cd3923bd2a2375f6c316a286b48
parent 99f5b1ae4423e7f2e9f01ef9e5a3e4c9bd28a964
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date: Sat, 22 Oct 2011 16:13:04 +0200
Merge branch 'master' of github:jsmaniac/2011-m2s3-city-builder
Diffstat:
| M | roads.c | | | 123 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
| M | roads.h | | | 12 | ++++++++++++ |
2 files changed, 130 insertions(+), 5 deletions(-)
diff --git 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.
@@ -67,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;
@@ -84,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.
+ 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;
+ Jx = ub->x - ua->x;
+ Jy = ub->y - ua->y;
+
+ 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 B<A).
+ if(va->x == 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;
@@ -128,6 +210,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;
@@ -165,6 +252,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;
@@ -268,6 +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]));
diff --git 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);