Graphviz  2.29.20120523.0446
lib/pathplan/cvt.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 
00015 #include <stdio.h>
00016 #include "vis.h"
00017 
00018 #ifdef DMALLOC
00019 #include "dmalloc.h"
00020 #endif
00021 
00022 typedef Ppoint_t ilcoord_t;
00023 
00024 #ifdef DEBUG
00025 static void printVconfig(vconfig_t * cp);
00026 static void printVis(char *lbl, COORD * vis, int n);
00027 static void printDad(int *vis, int n);
00028 #endif
00029 
00030 #ifdef GASP
00031 static void gasp_print_obstacles(vconfig_t * conf);
00032 static void gasp_print_point(Ppoint_t p);
00033 static void gasp_print_polyline(Ppolyline_t * route);
00034 static void gasp_print_bezier(Ppolyline_t * route);
00035 #endif
00036 
00037 #if 0                           /* not used */
00038 static void *myrealloc(void *p, size_t newsize)
00039 {
00040     void *rv;
00041 
00042     if (p == (void *) 0)
00043         rv = malloc(newsize);
00044     else
00045         rv = realloc(p, newsize);
00046     return rv;
00047 }
00048 #endif
00049 
00050 static void *mymalloc(size_t newsize)
00051 {
00052     void *rv;
00053 
00054     if (newsize > 0)
00055         rv = malloc(newsize);
00056     else
00057         rv = (void *) 0;
00058     return rv;
00059 }
00060 
00061 
00062 vconfig_t *Pobsopen(Ppoly_t ** obs, int n_obs)
00063 {
00064     vconfig_t *rv;
00065     int poly_i, pt_i, i, n;
00066     int start, end;
00067 
00068     rv = malloc(sizeof(vconfig_t));
00069     if (!rv) {
00070         return NULL;
00071     }
00072 
00073     /* get storage */
00074     n = 0;
00075     for (poly_i = 0; poly_i < n_obs; poly_i++)
00076         n = n + obs[poly_i]->pn;
00077     rv->P = mymalloc(n * sizeof(Ppoint_t));
00078     rv->start = mymalloc((n_obs + 1) * sizeof(int));
00079     rv->next = mymalloc(n * sizeof(int));
00080     rv->prev = mymalloc(n * sizeof(int));
00081     rv->N = n;
00082     rv->Npoly = n_obs;
00083 
00084     /* build arrays */
00085     i = 0;
00086     for (poly_i = 0; poly_i < n_obs; poly_i++) {
00087         start = i;
00088         rv->start[poly_i] = start;
00089         end = start + obs[poly_i]->pn - 1;
00090         for (pt_i = 0; pt_i < obs[poly_i]->pn; pt_i++) {
00091             rv->P[i] = obs[poly_i]->ps[pt_i];
00092             rv->next[i] = i + 1;
00093             rv->prev[i] = i - 1;
00094             i++;
00095         }
00096         rv->next[end] = start;
00097         rv->prev[start] = end;
00098     }
00099     rv->start[poly_i] = i;
00100     visibility(rv);
00101     return rv;
00102 }
00103 
00104 void Pobsclose(vconfig_t * config)
00105 {
00106     free(config->P);
00107     free(config->start);
00108     free(config->next);
00109     free(config->prev);
00110     if (config->vis) {
00111         free(config->vis[0]);
00112         free(config->vis);
00113     }
00114     free(config);
00115 }
00116 
00117 int Pobspath(vconfig_t * config, Ppoint_t p0, int poly0, Ppoint_t p1,
00118              int poly1, Ppolyline_t * output_route)
00119 {
00120     int i, j, *dad;
00121     int opn;
00122     Ppoint_t *ops;
00123     COORD *ptvis0, *ptvis1;
00124 
00125 #ifdef GASP
00126     gasp_print_obstacles(config);
00127 #endif
00128     ptvis0 = ptVis(config, poly0, p0);
00129     ptvis1 = ptVis(config, poly1, p1);
00130 
00131 #ifdef GASP
00132     gasp_print_point(p0);
00133     gasp_print_point(p1);
00134 #endif
00135     dad = makePath(p0, poly0, ptvis0, p1, poly1, ptvis1, config);
00136 
00137     opn = 1;
00138     for (i = dad[config->N]; i != config->N + 1; i = dad[i])
00139         opn++;
00140     opn++;
00141     ops = malloc(opn * sizeof(Ppoint_t));
00142 
00143     j = opn - 1;
00144     ops[j--] = p1;
00145     for (i = dad[config->N]; i != config->N + 1; i = dad[i])
00146         ops[j--] = config->P[i];
00147     ops[j] = p0;
00148     assert(j == 0);
00149 
00150 #ifdef DEBUG
00151     printVconfig(config);
00152     printVis("p", ptvis0, config->N + 1);
00153     printVis("q", ptvis1, config->N + 1);
00154     printDad(dad, config->N + 1);
00155 #endif
00156 
00157     if (ptvis0)
00158         free(ptvis0);
00159     if (ptvis1)
00160         free(ptvis1);
00161 
00162     output_route->pn = opn;
00163     output_route->ps = ops;
00164 #ifdef GASP
00165     gasp_print_polyline(output_route);
00166 #endif
00167     free(dad);
00168     return TRUE;
00169 }
00170 
00171 int Pobsbarriers(vconfig_t * config, Pedge_t ** barriers, int *n_barriers)
00172 {
00173     int i, j;
00174 
00175     *barriers = malloc(config->N * sizeof(Pedge_t));
00176     *n_barriers = config->N;
00177 
00178     for (i = 0; i < config->N; i++) {
00179         barriers[i]->a.x = config->P[i].x;
00180         barriers[i]->a.y = config->P[i].y;
00181         j = config->next[i];
00182         barriers[i]->b.x = config->P[j].x;
00183         barriers[i]->b.y = config->P[j].y;
00184     }
00185     return 1;
00186 }
00187 
00188 #ifdef DEBUG
00189 static void printVconfig(vconfig_t * cp)
00190 {
00191     int i, j;
00192     int *next, *prev;
00193     Ppoint_t *pts;
00194     array2 arr;
00195 
00196     next = cp->next;
00197     prev = cp->prev;
00198     pts = cp->P;
00199     arr = cp->vis;
00200 
00201     printf("this next prev point\n");
00202     for (i = 0; i < cp->N; i++)
00203         printf("%3d  %3d  %3d    (%3g,%3g)\n", i, next[i], prev[i],
00204                pts[i].x, pts[i].y);
00205 
00206     printf("\n\n");
00207 
00208     for (i = 0; i < cp->N; i++) {
00209         for (j = 0; j < cp->N; j++)
00210             printf("%4.1f ", arr[i][j]);
00211         printf("\n");
00212     }
00213 }
00214 
00215 static void printVis(char *lbl, COORD * vis, int n)
00216 {
00217     int i;
00218 
00219     printf("%s: ", lbl);
00220     for (i = 0; i < n; i++)
00221         printf("%4.1f ", vis[i]);
00222     printf("\n");
00223 }
00224 
00225 static void printDad(int *vis, int n)
00226 {
00227     int i;
00228 
00229     printf("     ");
00230     for (i = 0; i < n; i++) {
00231         printf("%3d ", i);
00232     }
00233     printf("\n");
00234     printf("dad: ");
00235     for (i = 0; i < n; i++) {
00236         printf("%3d ", vis[i]);
00237     }
00238     printf("\n");
00239 }
00240 #endif
00241 
00242 static Ppoint_t Bezpt[1000];
00243 static int Bezctr;
00244 
00245 static void addpt(Ppoint_t p)
00246 {
00247     if ((Bezctr == 0) ||
00248         (Bezpt[Bezctr - 1].x != p.x) || (Bezpt[Bezctr - 1].y != p.y))
00249         Bezpt[Bezctr++] = p;
00250 }
00251 
00252 #define W_DEGREE 5
00253 static ilcoord_t Bezier(ilcoord_t * V, int degree, double t,
00254                         ilcoord_t * Left, ilcoord_t * Right)
00255 {
00256     int i, j;                   /* Index variables  */
00257     ilcoord_t Vtemp[W_DEGREE + 1][W_DEGREE + 1];
00258 
00259     /* Copy control points  */
00260     for (j = 0; j <= degree; j++) {
00261         Vtemp[0][j] = V[j];
00262     }
00263 
00264     /* Triangle computation */
00265     for (i = 1; i <= degree; i++) {
00266         for (j = 0; j <= degree - i; j++) {
00267             Vtemp[i][j].x =
00268                 (1.0 - t) * Vtemp[i - 1][j].x + t * Vtemp[i - 1][j + 1].x;
00269             Vtemp[i][j].y =
00270                 (1.0 - t) * Vtemp[i - 1][j].y + t * Vtemp[i - 1][j + 1].y;
00271         }
00272     }
00273 
00274     if (Left != NIL(ilcoord_t *))
00275         for (j = 0; j <= degree; j++)
00276             Left[j] = Vtemp[j][0];
00277     if (Right != NIL(ilcoord_t *))
00278         for (j = 0; j <= degree; j++)
00279             Right[j] = Vtemp[degree - j][j];
00280     return (Vtemp[degree][0]);
00281 }
00282 
00283 static void append_bezier(Ppoint_t * bezier)
00284 {
00285     double a;
00286     ilcoord_t left[4], right[4];
00287 
00288     a = fabs(area2(bezier[0], bezier[1], bezier[2]))
00289         + fabs(area2(bezier[2], bezier[3], bezier[0]));
00290     if (a < .5) {
00291         addpt(bezier[0]);
00292         addpt(bezier[3]);
00293     } else {
00294         (void) Bezier(bezier, 3, .5, left, right);
00295         append_bezier(left);
00296         append_bezier(right);
00297     }
00298 }
00299 
00300 #ifdef GASP
00301 
00302 FILE *GASPout = stderr;
00303 
00304 static void gasp_print_point(Ppoint_t p)
00305 {
00306     fprintf(GASPout, "%3g %3g\n", p.x, p.y);
00307 }
00308 
00309 void gasp_print_obstacles(vconfig_t * conf)
00310 {
00311     int i, j;
00312     Ppoly_t poly;
00313 
00314     fprintf(GASPout, "%d\n", conf->Npoly);
00315     for (i = 0; i < conf->Npoly; i++) {
00316         poly.ps = &(conf->P[conf->start[i]]);
00317         poly.pn = conf->start[i + 1] - conf->start[i];
00318         fprintf(GASPout, "%d\n", poly.pn);
00319         for (j = 0; j < poly.pn; j++)
00320             gasp_print_point(poly.ps[j]);
00321     }
00322 }
00323 
00324 void gasp_print_bezier(Ppolyline_t * route)
00325 {
00326     int i;
00327 
00328     Bezctr = 0;
00329     for (i = 0; i + 3 < route->pn; i += 3)
00330         append_bezier(route->ps + i);
00331     fprintf(GASPout, "%d\n", Bezctr);
00332     for (i = 0; i < Bezctr; i++)
00333         gasp_print_point(Bezpt[i]);
00334     Bezctr = 0;
00335 }
00336 
00337 void gasp_print_polyline(Ppolyline_t * route)
00338 {
00339     int i;
00340 
00341     fprintf(GASPout, "%d\n", route->pn);
00342     for (i = 0; i < route->pn; i++)
00343         gasp_print_point(route->ps[i]);
00344 }
00345 #endif