mirror of
git://projects.qi-hardware.com/cae-tools.git
synced 2024-12-23 05:01:10 +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:
parent
0bc780611d
commit
54d8549fa2
@ -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;
|
||||
}
|
||||
|
64
cameo/path.c
64
cameo/path.c
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user