1
0
mirror of git://projects.qi-hardware.com/cae-tools.git synced 2024-12-22 23:43:00 +02:00

cameo: detect and adjust handedness

- cameo/path.h, cameo/path.c (offset_point, path_offset): added "left"
  argument to indicate the handedness
- cameo/path.h, cameo/path.c (path_tool_is_left): new function to determine
  which way the path turns
- cameo/cameo.c: auto-detect handedness and instruct path_offset accordingly
This commit is contained in:
Werner Almesberger 2010-11-01 15:43:37 -03:00
parent 0bc780611d
commit 54d8549fa2
3 changed files with 65 additions and 11 deletions

View File

@ -32,6 +32,7 @@ int main(int argc, char **argv)
char *in = NULL, *out = NULL;
double r;
struct path *paths;
int left;
switch (argc) {
case 4:
@ -50,14 +51,13 @@ int main(int argc, char **argv)
/*
* To do:
* - auto-detect orientation
* - handle multiple paths
* - instead of reversing the path, reverse the handedness
*/
paths = gnuplot_read(in, r);
assert(!paths->next); /* we don't handle this yet */
paths = path_reverse(paths);
paths = path_offset(paths, 1);
// paths = path_reverse(paths);
left = path_tool_is_left(paths);
paths = path_offset(paths, left, 1);
gnuplot_write(out, paths);
return 0;
}

View File

@ -99,7 +99,7 @@ struct path *path_reverse(const struct path *path)
static struct point *offset_point(const struct point *a, const struct point *b,
const struct point *c, double off)
const struct point *c, double off, int left)
{
double ax, ay, bx, by;
double aa, bb;
@ -113,8 +113,13 @@ static struct point *offset_point(const struct point *a, const struct point *b,
aa = hypot(ax, ay);
bb = hypot(bx, by);
nx = -(ay/aa+by/bb);
ny = ax/aa+bx/bb;
if (left) {
nx = -(ay/aa+by/bb);
ny = ax/aa+bx/bb;
} else {
nx = ay/aa+by/bb;
ny = -(ax/aa+bx/bb);
}
nx *= off;
ny *= off;
@ -143,6 +148,53 @@ static int left_turn(const struct point *a, const struct point *b,
}
/*
* Angle in counter-clockwise direction to turn at point B when coming from A
* in order to face towards C.
*/
static double angle(const struct point *a, const struct point *b,
const struct point *c)
{
double ax, ay, bx, by;
double aa, bb;
double angle;
ax = b->x-a->x;
ay = b->y-a->y;
bx = c->x-b->x;
by = c->y-b->y;
aa = hypot(ax, ay);
bb = hypot(bx, by);
angle = acos((ax*bx+ay*by)/aa/bb)/M_PI*180.0;
return (ax*by-ay*bx) >= 0 ? angle : -angle;
}
/*
* If we predominantly turn to the right, then the tool must be on the
* left-hand side. Otherwise, it's on the right.
*/
int path_tool_is_left(const struct path *path)
{
const struct point *prev, *p, *next;
double a = 0;
assert(path_is_closed(path));
prev = path->first;
for (p = path->first->next; p; p = p->next) {
next = p->next ? p->next : path->first->next;
a += angle(prev, p, next);
prev = p;
}
return a < 0;
}
/*
* http://www.makecnc.com/bones.jpg
*/
@ -176,7 +228,7 @@ static struct point *dog_point(const struct point *edge,
* 6 o'clock to 12 o'clock, the tool would be at 9 o'clock.
*/
struct path *path_offset(const struct path *path, int notch)
struct path *path_offset(const struct path *path, int left, int notch)
{
struct path *new;
const struct point *prev, *p, *next;
@ -188,8 +240,8 @@ struct path *path_offset(const struct path *path, int notch)
prev = path->first;
for (p = path->first->next; p; p = p->next) {
next = p->next ? p->next : path->first->next;
n = offset_point(prev, p, next, path->r_tool);
dog = notch && left_turn(prev, p, next);
n = offset_point(prev, p, next, path->r_tool, left);
dog = notch && left_turn(prev, p, next) == left;
if (dog)
n2 = clone_point(n);
path_add_point(new, n);

View File

@ -30,7 +30,9 @@ struct path {
struct path *path_new(double r_tool);
void path_add(struct path *path, double x, double y, double z);
struct path *path_reverse(const struct path *path);
struct path *path_offset(const struct path *path, int notch);
int path_direction(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);
void path_free(struct path *path);
#endif /* !PATH_H */