00001
00012 #include "path_simplifier.h"
00013
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
00053 l->a1 = 1.0;
00054 l->a2 = 0.0;
00055 l->b = x1;
00056 }else if (y1 == y2){
00057
00058 l->a1 = 0.0;
00059 l->a2 = 1.0;
00060 l->b = y1;
00061 }else{
00062
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;
00142 float x1,y1,x2,y2;
00143 int i;
00144 float dist;
00145 Line line;
00146 int points_simplify = 1;
00147 PathPoint *last_point;
00148
00149
00150 first_point->x = *(path);
00151 first_point->y = *(path+1);
00152 first_point->next = NULL;
00153 last_point = first_point;
00154
00155
00156
00157
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
00164
00165
00166 calc_line(x1,y1, x2, y2, &line);
00167
00168
00169
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
00174 if (dist > max_err) max_err = dist;
00175 }
00176
00177
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
00183 last_point->next = newPathPoint(last_point, x2, y2);
00184 last_point = last_point->next;
00185 points_simplify++;
00186
00187 } else {
00188 step = ceil ((last_index - first_index)/2);
00189 last_index = first_index + step;
00190
00191 }
00192
00193 if (last_index > (nbpoints -1)) last_index = nbpoints -1;
00194 }
00195
00196 (*angle) = atan2((y2-y1),(x2-x1));
00197
00198
00199 return points_simplify;
00200 }
00208 void freePathMemory(PathPoint * simple_path){
00209 PathPoint * tmp;
00210 PathPoint * toFree;
00211
00212 tmp = simple_path;
00213 while(tmp!= NULL){
00214 toFree = tmp;
00215 tmp = tmp->next;
00216
00217 free(toFree);
00218 }
00219 }
00220
00221
00222