diff --git a/cameo/cameo.c b/cameo/cameo.c index 9c2fcf6..02fc4ed 100644 --- a/cameo/cameo.c +++ b/cameo/cameo.c @@ -13,12 +13,38 @@ #include #include -#include #include "path.h" #include "gnuplot.h" + +static void process_path(struct path *path, int inside) +{ + int left; + struct path *new; + + left = path_tool_is_left(path); + if (inside) + new = path_offset(path, !left, 0); + else + new = path_offset(path, left, 1); + path_replace(path, new); +} + + +static void process_paths(struct path *paths) +{ + struct path *leftmost, *path; + + leftmost = path_find_leftmost(paths); + for (path = paths; path; path = path->next) + if (path != leftmost) + process_path(path, 1); + process_path(leftmost, 0); +} + + static void usage(const char *name) { fprintf(stderr, "usage: %s r_mm [in.gnuplot [out.gnuplot]]\n", @@ -32,7 +58,6 @@ int main(int argc, char **argv) char *in = NULL, *out = NULL; double r; struct path *paths; - int left; switch (argc) { case 4: @@ -48,16 +73,9 @@ int main(int argc, char **argv) usage(*argv); } - -/* - * To do: - * - handle multiple paths - */ paths = gnuplot_read(in, r); - assert(!paths->next); /* we don't handle this yet */ -// paths = path_reverse(paths); - left = path_tool_is_left(paths); - paths = path_offset(paths, left, 1); + process_paths(paths); gnuplot_write(out, paths); + return 0; } diff --git a/cameo/path.c b/cameo/path.c index e9719f0..13d4930 100644 --- a/cameo/path.c +++ b/cameo/path.c @@ -20,6 +20,25 @@ #include "path.h" +static void free_points(struct point *points) +{ + struct point *next; + + while (points) { + next = points->next; + free(points); + points = next; + } +} + + +void path_free(struct path *path) +{ + free_points(path->first); + free(path); +} + + struct path *path_new(double r_tool) { struct path *path; @@ -77,6 +96,17 @@ void path_add(struct path *path, double x, double y, double z) } +void path_replace(struct path *old, struct path *new) +{ + struct path *next = old->next; + + free_points(old->first); + *old = *new; + old->next = next; + free(new); +} + + struct path *path_reverse(const struct path *path) { struct path *new; @@ -265,14 +295,20 @@ struct path *path_offset(const struct path *path, int left, int notch) } -void path_free(struct path *path) +struct path *path_find_leftmost(struct path *path) { - struct point *next; + const struct point *p; + struct path *best = NULL; + double best_x = HUGE_VAL; - while (path->first) { - next = path->first->next; - free(path->first); - path->first = next; + while (path) { + for (p = path->first; p; p = p->next) + if (p->x < best_x) { + best = path; + best_x = p->x; + break; + } + path = path->next; } - free(path); + return best; } diff --git a/cameo/path.h b/cameo/path.h index 6853590..d84e12f 100644 --- a/cameo/path.h +++ b/cameo/path.h @@ -29,9 +29,11 @@ struct path { struct path *path_new(double r_tool); void path_add(struct path *path, double x, double y, double z); +void path_replace(struct path *old, struct path *new); struct path *path_reverse(const struct path *path); int path_tool_is_left(const struct path *path); struct path *path_offset(const struct path *path, int left, int notch); +struct path *path_find_leftmost(struct path *path); void path_free(struct path *path); #endif /* !PATH_H */