path_simplifier.c

Go to the documentation of this file.
00001 
00012 #include "path_simplifier.h"
00013 //for DBG function
00014 #define DBG printf
00015 #include <math.h>
00016 #include <stdlib.h>
00017 #define ABS_VAL(x)      ((x > 0.0)?(x):(-x))    
00018 #define POW(x)          (x*x)
00019 
00020 #define PATH_ERROR 0.09         
00030 PathPoint * newPathPoint(PathPoint * last ,  float x, float y){
00031         PathPoint *p = malloc(sizeof(PathPoint));
00032         p->x = x;
00033         p->y = y;
00034         p->next = NULL;
00035         last->next = p;
00036         return p;
00037 }
00048 void calc_line(float x1,float y1, float x2, float y2, Line * l ){
00051         if (x1 == x2){
00052                 // It is a vertical line
00053                 l->a1 = 1.0;
00054                 l->a2 = 0.0;
00055                 l->b = x1;
00056         }else if (y1 == y2){
00057                 // It is a horizontal line
00058                 l->a1 = 0.0;
00059                 l->a2 = 1.0;
00060                 l->b = y1;
00061         }else{ 
00062                 // It is a normal line
00063                 l->a1 = -(y2-y1)/(x2-x1);
00064                 l->a2 = 1.0;
00065                 l->b = (y1*x2-y2*x1)/(x2-x1);
00066         }
00067 }
00077 float calc_dist(Line * l, float x,float y){
00078         float dist, abs_value, sqrt_value;
00079         if (l->a1 == 0){
00081                 dist = y - (l->b);
00082         }else if(l->a2 == 0){
00084                 dist = x-(l->b);
00085         }else{
00087                 abs_value = (l->a1) * x + (l->a2) * y - (l->b);
00088                 sqrt_value = sqrt( POW(l->a1) + POW(l->a2) );
00089                 dist = abs_value/ sqrt_value;
00090         }
00091         if (dist< 0.0 ) dist = -dist;
00092         return dist;
00093 }
00094 
00095 
00106 int path_simplifier (double * path, int nbpoints, PathPoint * first_point, double * angle){
00138         int first_index     = 0;
00139         int last_index      = nbpoints - 1; 
00140         int step            = floor ((last_index - first_index)/2);
00141         float max_err;                          // Max error
00142         float x1,y1,x2,y2;                      // Limits of the line
00143         int i;                                  // Auxiliar value
00144         float dist;                             // Distance betwen actual point and the line
00145         Line line;                              // Parameters of the line (x1,y1), (x2,y2)
00146         int points_simplify = 1;
00147         PathPoint *last_point;                  // A pointer to the last point of the list
00148         
00149         
00150         first_point->x = *(path);
00151         first_point->y = *(path+1);
00152         first_point->next = NULL;
00153         last_point = first_point;               // In the begining, the last point of the list is the first one (there are only one)
00154         
00155         
00156         //DBG("path_simplifier: Nb of points %d :",nbpoints);
00157         //for(i=0;i<nbpoints;i++) printf("(%f,%f)", (*(path+i*2)), (*(path + i*2 + 1)));        printf("\n");
00158         
00159         while ((first_index < (nbpoints-1)) && (last_index <= (nbpoints-1)) ){
00160                 x1=*(path + first_index*2);     y1=*(path + first_index*2 +1);
00161                 x2=*(path + last_index*2);      y2=*(path + last_index*2 +1);
00162                 
00163                 //DBG("path_simplifier: Taking indexes %d to %d\n",first_index, last_index);
00164                 //DBG("path_simplifier: Points : (%f,%f),(%f,%f)\n", x1,y1,x2,y2);
00165                 
00166                 calc_line(x1,y1, x2, y2, &line);
00167                 //DBG("path_simplifier: Line : %f * x + %f * y = %f\n", line.a1, line.a2, line.b);
00168 
00169                 // Error Calculus
00170                 max_err = 0;
00171                 for (i=(first_index+1);i<last_index;i++){
00172                         dist= calc_dist(&line ,(*(path + i*2)) ,(*(path + i*2 +1)));
00173                         //DBG("path_simplifier: Distance from [%d](%f,%f) to Line : %f\n",i,(*(path + i*2)) ,(*(path + i*2 +1)), dist);
00174                         if (dist > max_err) max_err = dist;
00175                 }
00176 
00177                 // Error decision
00178                 if (max_err < PATH_ERROR ){
00179                         step = floor ((last_index - first_index)*2);
00180                         first_index = last_index;
00181                         last_index = first_index + step;
00182                         //DBG("path_simplifier: Adding Point : (%f,%f)\n", x2,y2);
00183                         last_point->next = newPathPoint(last_point, x2, y2);
00184                         last_point = last_point->next;
00185                         points_simplify++;
00186                         //DBG("path_simplifier: error ok\n");
00187                 } else { 
00188                         step = ceil ((last_index - first_index)/2);
00189                         last_index = first_index + step;
00190                         //DBG("path_simplifier: error ko\n");
00191                 }
00192                 // last index correction
00193                 if (last_index > (nbpoints -1)) last_index = nbpoints -1;
00194         }
00195         //The final angle must be the angle of the slope of the last line
00196         (*angle) = atan2((y2-y1),(x2-x1)); 
00197         
00198         // Return the nb of points in the path
00199         return points_simplify;
00200 }
00208 void freePathMemory(PathPoint * simple_path){
00209         PathPoint * tmp;
00210         PathPoint * toFree;
00211         // Add this simple path to the trajectory
00212         tmp = simple_path;
00213         while(tmp!= NULL){
00214                 toFree = tmp;
00215                 tmp = tmp->next;
00216                 //Free allocated memory
00217                 free(toFree);
00218         }
00219 }
00220 
00221 
00222 

Generated on Thu Sep 13 11:28:28 2007 for DCE-Eurobot by  doxygen 1.5.3