mirror of
git://projects.qi-hardware.com/cae-tools.git
synced 2025-01-09 01:10:15 +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;
|
char *in = NULL, *out = NULL;
|
||||||
double r;
|
double r;
|
||||||
struct path *paths;
|
struct path *paths;
|
||||||
|
int left;
|
||||||
|
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
case 4:
|
case 4:
|
||||||
@ -50,14 +51,13 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* To do:
|
* To do:
|
||||||
* - auto-detect orientation
|
|
||||||
* - handle multiple paths
|
* - handle multiple paths
|
||||||
* - instead of reversing the path, reverse the handedness
|
|
||||||
*/
|
*/
|
||||||
paths = gnuplot_read(in, r);
|
paths = gnuplot_read(in, r);
|
||||||
assert(!paths->next); /* we don't handle this yet */
|
assert(!paths->next); /* we don't handle this yet */
|
||||||
paths = path_reverse(paths);
|
// paths = path_reverse(paths);
|
||||||
paths = path_offset(paths, 1);
|
left = path_tool_is_left(paths);
|
||||||
|
paths = path_offset(paths, left, 1);
|
||||||
gnuplot_write(out, paths);
|
gnuplot_write(out, paths);
|
||||||
return 0;
|
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,
|
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 ax, ay, bx, by;
|
||||||
double aa, bb;
|
double aa, bb;
|
||||||
@ -113,8 +113,13 @@ static struct point *offset_point(const struct point *a, const struct point *b,
|
|||||||
|
|
||||||
aa = hypot(ax, ay);
|
aa = hypot(ax, ay);
|
||||||
bb = hypot(bx, by);
|
bb = hypot(bx, by);
|
||||||
nx = -(ay/aa+by/bb);
|
if (left) {
|
||||||
ny = ax/aa+bx/bb;
|
nx = -(ay/aa+by/bb);
|
||||||
|
ny = ax/aa+bx/bb;
|
||||||
|
} else {
|
||||||
|
nx = ay/aa+by/bb;
|
||||||
|
ny = -(ax/aa+bx/bb);
|
||||||
|
}
|
||||||
|
|
||||||
nx *= off;
|
nx *= off;
|
||||||
ny *= 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
|
* 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.
|
* 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;
|
struct path *new;
|
||||||
const struct point *prev, *p, *next;
|
const struct point *prev, *p, *next;
|
||||||
@ -188,8 +240,8 @@ struct path *path_offset(const struct path *path, int notch)
|
|||||||
prev = path->first;
|
prev = path->first;
|
||||||
for (p = path->first->next; p; p = p->next) {
|
for (p = path->first->next; p; p = p->next) {
|
||||||
next = p->next ? p->next : path->first->next;
|
next = p->next ? p->next : path->first->next;
|
||||||
n = offset_point(prev, p, next, path->r_tool);
|
n = offset_point(prev, p, next, path->r_tool, left);
|
||||||
dog = notch && left_turn(prev, p, next);
|
dog = notch && left_turn(prev, p, next) == left;
|
||||||
if (dog)
|
if (dog)
|
||||||
n2 = clone_point(n);
|
n2 = clone_point(n);
|
||||||
path_add_point(new, n);
|
path_add_point(new, n);
|
||||||
|
@ -30,7 +30,9 @@ struct path {
|
|||||||
struct path *path_new(double r_tool);
|
struct path *path_new(double r_tool);
|
||||||
void path_add(struct path *path, double x, double y, double z);
|
void path_add(struct path *path, double x, double y, double z);
|
||||||
struct path *path_reverse(const struct path *path);
|
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);
|
void path_free(struct path *path);
|
||||||
|
|
||||||
#endif /* !PATH_H */
|
#endif /* !PATH_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user