From a030eff963032f3cc31eac472eabaf6d4c3c4a76 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Thu, 23 Aug 2012 09:04:44 -0300 Subject: [PATCH] cameo/: new command "flip" to flip paths on the X or Y axis --- cameo/README | 4 ++++ cameo/lang.l | 3 +++ cameo/lang.y | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/cameo/README b/cameo/README index 4bbe16b..67407ae 100644 --- a/cameo/README +++ b/cameo/README @@ -99,6 +99,7 @@ Horizontal adjustments: array translate rotate + flip [
] reset "translate" shifts the currently loaded paths by the specified distance. @@ -139,6 +140,9 @@ Note that rotation is applied before translation. Therefore, using "rotate" after "translate", "array", or "align" may yield unexpected results. +"flip" flips X/Y coordinates on the respective axis ("x" or "y"). If +the center is omitted, the piece is flipped on (xymin+xymax)/2. + "reset" sets translation and rotation to zero. The way "reset" is currently implemented, it does not affect the currently loaded toolpath. (But it's better to use it only with "clean".) diff --git a/cameo/lang.l b/cameo/lang.l index a6048b9..70bdd5a 100644 --- a/cameo/lang.l +++ b/cameo/lang.l @@ -45,6 +45,7 @@ NUM -?[0-9]+\.?[0-9]* clear return TOK_CLEAR; drill return TOK_DRILL; empty return TOK_EMPTY; +flip return TOK_FLIP; keep return TOK_KEEP; mill return TOK_MILL; offset return TOK_OFFSET; @@ -57,6 +58,8 @@ NUM -?[0-9]+\.?[0-9]* rotate return TOK_ROTATE; stats return TOK_STATS; translate return TOK_TRANSLATE; +x return TOK_X; +y return TOK_Y; z return TOK_Z; append { BEGIN(FILENAME); diff --git a/cameo/lang.y b/cameo/lang.y index 1c12aae..b572271 100644 --- a/cameo/lang.y +++ b/cameo/lang.y @@ -80,6 +80,43 @@ static void rotate(struct path *list, double angle) } +static void flip(struct path *list, enum axis axis, double center) +{ + const struct path *path; + struct point *p; + + for (path = list; path; path = path->next) + for (p = path->first; p; p = p->next) { + if (axis == axis_x) + p->x = 2*center-p->x; + else + p->y = 2*center-p->y; + } +} + + + +static void flip_center(struct path *list, enum axis axis) +{ + double min = 0, max = 0; + double coord; + const struct path *path; + const struct point *p; + int first = 1; + + for (path = list; path; path = path->next) + for (p = path->first; p; p = p->next) { + coord = axis == axis_x ? p->x : p->y; + if (first || coord < min) + min = coord; + if (first || coord > max) + max = coord; + first = 0; + } + flip(list, axis, (min+max)/2); +} + + static double ref_pick_1(int ref, double a, double b) { switch (ref) { @@ -184,14 +221,19 @@ static struct path **classify(struct path **anchor, struct path *path) OO_DOG = 1 << 0, OO_INSIDE = 1 << 1, } oopt; + enum axis { + axis_x, + axis_y + } axis; }; %token TOK_ALIGN TOK_AREA TOK_ARRAY TOK_CLEAR TOK_DRILL TOK_EMPTY -%token TOK_KEEP TOK_MILL TOK_OFFSET TOK_OPTIMIZE +%token TOK_FLIP TOK_KEEP TOK_MILL TOK_OFFSET TOK_OPTIMIZE %token TOK_OUTSIDE TOK_REMAINDER %token TOK_REMOVE TOK_RESET -%token TOK_REVERSE TOK_ROTATE TOK_STATS TOK_TRANSLATE TOK_Z +%token TOK_REVERSE TOK_ROTATE TOK_STATS TOK_TRANSLATE +%token TOK_X TOK_Y TOK_Z %token TOK_APPEND TOK_GERBER TOK_GNUPLOT TOK_EXCELLON TOK_WRITE %token TOK_DOG TOK_INSIDE TOK_ANY @@ -202,6 +244,7 @@ static struct path **classify(struct path **anchor, struct path *path) %type dimen number x_size y_size %type opt_any %type offset_options offset_option +%type axis %% @@ -283,6 +326,14 @@ command: rotate(paths, $2); rot += $2; } + | TOK_FLIP axis + { + flip_center(paths, $2); + } + | TOK_FLIP axis dimen + { + flip(paths, $2, $3); + } | TOK_STATS { path_stats(paths); @@ -489,6 +540,17 @@ offset_option: } ; +axis: + TOK_X + { + $$ = axis_x; + } + | TOK_Y + { + $$ = axis_y; + } + ; + opt_comma: | ',' ;