mirror of
git://projects.qi-hardware.com/cae-tools.git
synced 2024-12-23 04:23:55 +02:00
cameo: consider inside/outside also when checking corner points
This commit is contained in:
parent
7a61482a04
commit
340fb2cf8b
81
cameo/above.fig
Normal file
81
cameo/above.fig
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#FIG 3.2 Produced by xfig version 3.2.5b
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Metric
|
||||||
|
A4
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
5 1 1 2 14 7 68 -1 -1 6.000 0 0 0 0 5398.867 4722.104 8550 5535 8467 5807 7512 7197
|
||||||
|
6 7605 5715 7965 5985
|
||||||
|
2 1 0 1 4 7 50 -1 0 4.000 0 0 -1 1 0 2
|
||||||
|
1 1 1.00 30.00 30.00
|
||||||
|
7650 5760 7920 5760
|
||||||
|
4 1 4 50 -1 18 15 0.0000 4 135 300 7785 5985 na\001
|
||||||
|
-6
|
||||||
|
1 3 0 2 0 7 50 -1 0 0.000 1 0.0000 5625 6750 45 45 5625 6750 5670 6750
|
||||||
|
1 3 0 2 0 7 50 -1 0 0.000 1 0.0000 8100 6525 45 45 8100 6525 8145 6525
|
||||||
|
1 3 0 2 0 7 50 -1 0 0.000 1 0.0000 8550 7425 45 45 8550 7425 8595 7425
|
||||||
|
1 3 0 2 0 7 50 -1 0 0.000 1 0.0000 5400 4725 45 45 5400 4725 5445 4725
|
||||||
|
1 3 0 2 0 7 50 -1 0 0.000 1 0.0000 9315 4365 45 45 9315 4365 9360 4365
|
||||||
|
1 3 0 2 0 7 50 -1 0 0.000 1 0.0000 7053 5826 45 45 7053 5826 7098 5826
|
||||||
|
2 1 1 2 0 7 45 -1 0 6.000 0 0 -1 1 0 2
|
||||||
|
0 0 2.00 150.00 180.00
|
||||||
|
8100 6525 5400 4725
|
||||||
|
2 1 0 2 0 7 45 -1 0 0.000 0 0 -1 0 0 2
|
||||||
|
5625 6750 9315 4365
|
||||||
|
2 1 0 2 1 7 55 -1 0 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 2.00 150.00 180.00
|
||||||
|
5635 6763 8100 6525
|
||||||
|
2 1 0 2 1 7 55 -1 0 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 2.00 150.00 180.00
|
||||||
|
8100 6525 8550 7425
|
||||||
|
2 1 0 2 4 7 60 -1 0 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 2.00 150.00 180.00
|
||||||
|
8100 6525 7965 4995
|
||||||
|
2 1 0 2 4 7 60 -1 0 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 2.00 150.00 180.00
|
||||||
|
8100 6525 9450 5850
|
||||||
|
2 1 1 2 1 7 55 -1 0 6.000 0 0 -1 0 0 2
|
||||||
|
8550 7425 8775 8550
|
||||||
|
2 1 1 2 1 7 55 -1 0 6.000 0 0 -1 0 0 2
|
||||||
|
5625 6750 4275 7200
|
||||||
|
2 3 0 0 1 7 70 -1 44 0.000 0 0 -1 0 0 6
|
||||||
|
4500 7155 5625 6750 8100 6525 8550 7425 8730 8325 4500 7155
|
||||||
|
2 1 0 2 14 7 55 -1 0 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 2.00 150.00 180.00
|
||||||
|
2925 4725 5400 4725
|
||||||
|
2 1 0 1 4 7 50 -1 0 4.000 0 0 -1 1 0 2
|
||||||
|
1 1 1.00 30.00 30.00
|
||||||
|
8595 6435 8865 6435
|
||||||
|
2 1 0 1 0 7 50 -1 0 4.000 0 0 -1 1 0 2
|
||||||
|
1 1 1.00 30.00 30.00
|
||||||
|
4185 4950 4500 4950
|
||||||
|
2 1 0 1 0 7 50 -1 0 4.000 0 0 -1 1 0 2
|
||||||
|
1 1 1.00 30.00 30.00
|
||||||
|
4140 5400 4500 5400
|
||||||
|
2 1 0 1 0 7 50 -1 0 4.000 0 0 -1 1 0 2
|
||||||
|
1 1 1.00 30.00 30.00
|
||||||
|
4365 5850 4680 5850
|
||||||
|
2 1 0 2 4 7 60 -1 0 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 2.00 150.00 180.00
|
||||||
|
7974 5013 9324 4338
|
||||||
|
2 1 0 2 4 7 60 -1 0 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 2.00 150.00 180.00
|
||||||
|
9450 5850 9315 4320
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 180 180 5355 6660 A\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 180 180 8685 7515 C\001
|
||||||
|
4 1 4 50 -1 18 15 0.0000 4 180 300 8730 6660 nb\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 180 180 8145 6345 B\001
|
||||||
|
4 1 14 50 -1 18 15 0.0000 4 180 165 5400 4590 P\001
|
||||||
|
4 1 0 50 -1 18 15 0.0000 4 195 195 6750 5445 Q\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 195 1470 3150 5175 Q = A+u*AM\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 195 1425 3150 5625 P = B+v*BQ\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 195 1650 3150 6075 Q = B+1/v*BP\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 180 1695 2925 4635 Tool direction\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 240 1890 5715 7785 Polygon, inside\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 180 975 3150 7020 v >= 0 ?\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 225 1590 3150 6660 u in [0, 1] &&\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 180 210 9225 4275 M\001
|
||||||
|
4 0 0 50 -1 18 15 0.0000 4 240 2115 7155 4005 Midpoint, outside\001
|
122
cameo/area.c
122
cameo/area.c
@ -25,7 +25,7 @@
|
|||||||
#include "area.h"
|
#include "area.h"
|
||||||
|
|
||||||
|
|
||||||
#define EPSILON 0.0001
|
#define EPSILON 1e-6
|
||||||
|
|
||||||
|
|
||||||
static int bbox(const struct path *path,
|
static int bbox(const struct path *path,
|
||||||
@ -107,13 +107,14 @@ static int cramer2(double a, double b, double c, double d, double e, double f,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Solve
|
* Solve
|
||||||
* ax+na*bx = cx+nb*dx
|
*
|
||||||
* ay+na*by = cy+nb*dy
|
* ax + na*bx = cx + nb*dx
|
||||||
|
* ay + na*by = cy + nb*dy
|
||||||
*
|
*
|
||||||
* which is
|
* which is
|
||||||
*
|
*
|
||||||
* na*bx + nb*-dx = cx-ax
|
* na*bx + nb*-dx = cx - ax
|
||||||
* na*by + nb*-dy = cy-ay
|
* na*by + nb*-dy = cy - ay
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int intersect(double ax, double ay, double bx, double by,
|
static int intersect(double ax, double ay, double bx, double by,
|
||||||
@ -123,6 +124,55 @@ static int intersect(double ax, double ay, double bx, double by,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See above.fig. The equation we solve is
|
||||||
|
*
|
||||||
|
* Q = A+u*(AM)
|
||||||
|
* Q = B+v*(BP)
|
||||||
|
*
|
||||||
|
* equals
|
||||||
|
*
|
||||||
|
* ax + u*(mx-ax) = bx + v*(px-bx)
|
||||||
|
* ay + u*(my-ay) = by + v*(py-by)
|
||||||
|
*
|
||||||
|
* equals
|
||||||
|
*
|
||||||
|
* u*(mx-ax) + v*(bx-px) = bx - ax
|
||||||
|
* u*(my-ay) + v*(by-py) = by - ay
|
||||||
|
*
|
||||||
|
* For BC, the equation becomes
|
||||||
|
*
|
||||||
|
* Q = C+u*(CM)
|
||||||
|
* Q = B+v*(BP)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int above(const struct point *a, const struct point *b,
|
||||||
|
const struct point *c, double px, double py)
|
||||||
|
{
|
||||||
|
double ab, bc;
|
||||||
|
double mx, my;
|
||||||
|
double u, v;
|
||||||
|
|
||||||
|
ab = hypot(a->x-b->x, a->y-b->y);
|
||||||
|
bc = hypot(b->x-c->x, b->y-c->y);
|
||||||
|
if (fabs(ab) < EPSILON || fabs(bc) < EPSILON)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mx = b->x-(b->y-a->y)/ab-(c->y-b->y)/bc;
|
||||||
|
my = b->y+(b->x-a->x)/ab+(c->x-b->x)/bc;
|
||||||
|
|
||||||
|
if (cramer2(mx-a->x, b->x-px, my-a->y, b->y-py, b->x-a->x, b->y-a->y,
|
||||||
|
&u, &v))
|
||||||
|
if (u >= 0 && u <= 1 && v >= 0)
|
||||||
|
return 1;
|
||||||
|
if (cramer2(mx-c->x, b->x-px, my-c->y, b->y-py, b->x-c->x, b->y-c->y,
|
||||||
|
&u, &v))
|
||||||
|
if (u >= 0 && u <= 1 && v >= 0)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Solve
|
* Solve
|
||||||
*
|
*
|
||||||
@ -131,7 +181,7 @@ static int intersect(double ax, double ay, double bx, double by,
|
|||||||
* http://en.wikipedia.org/wiki/Quadratic_equation
|
* http://en.wikipedia.org/wiki/Quadratic_equation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int touch(double ax, double ay, double bx, double by,
|
static int touch_solve(double ax, double ay, double bx, double by,
|
||||||
double cx, double cy, double r, int enter, double *n)
|
double cx, double cy, double r, int enter, double *n)
|
||||||
{
|
{
|
||||||
double dx = cx-ax;
|
double dx = cx-ax;
|
||||||
@ -153,9 +203,42 @@ static int touch(double ax, double ay, double bx, double by,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The points A, B, and C are (if the path is left-handed):
|
||||||
|
*
|
||||||
|
* - A: the beginning of the segment leading into the corner
|
||||||
|
* - B: the corner point
|
||||||
|
* - C: the beginning of the segment leading out of the corner
|
||||||
|
*
|
||||||
|
* If the path is right-handed, we swap A and C, making it left-handed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int touch(double ax, double ay, double bx, double by,
|
||||||
|
const struct point *a, const struct point *b, const struct point *c,
|
||||||
|
double r, int enter, int left, double *n)
|
||||||
|
{
|
||||||
|
double px, py;
|
||||||
|
|
||||||
|
if (!touch_solve(ax, ay, bx, by, b->x, b->y, r, enter, n))
|
||||||
|
return 0;
|
||||||
|
px = ax+*n*bx;
|
||||||
|
py = ay+*n*by;
|
||||||
|
return above(a, b, c, px, py) == left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here, the points A, B, C, and D are:
|
||||||
|
*
|
||||||
|
* - A: before the beginning of the current segment
|
||||||
|
* - B: the beginning
|
||||||
|
* - C: the end
|
||||||
|
* - D: the next point beyond the end
|
||||||
|
*/
|
||||||
|
|
||||||
static int hit_segment(double fx, double fy, double tx, double ty,
|
static int hit_segment(double fx, double fy, double tx, double ty,
|
||||||
const struct point *a, const struct point *b, double r, int enter,
|
const struct point *a, const struct point *b, const struct point *c,
|
||||||
int left, double *n)
|
const struct point *d, double r, int enter, int left, double *n)
|
||||||
{
|
{
|
||||||
double dx, dy, nx, ny, nn;
|
double dx, dy, nx, ny, nn;
|
||||||
double px, py;
|
double px, py;
|
||||||
@ -164,8 +247,8 @@ static int hit_segment(double fx, double fy, double tx, double ty,
|
|||||||
tx -= fx;
|
tx -= fx;
|
||||||
ty -= fy;
|
ty -= fy;
|
||||||
|
|
||||||
dx = b->x-a->x;
|
dx = c->x-b->x;
|
||||||
dy = b->y-a->y;
|
dy = c->y-b->y;
|
||||||
|
|
||||||
if (left) {
|
if (left) {
|
||||||
nx = dx;
|
nx = dx;
|
||||||
@ -181,17 +264,17 @@ static int hit_segment(double fx, double fy, double tx, double ty,
|
|||||||
|
|
||||||
nn = hypot(nx, ny);
|
nn = hypot(nx, ny);
|
||||||
|
|
||||||
px = a->x-ny/nn*r;
|
px = b->x-ny/nn*r;
|
||||||
py = a->y+nx/nn*r;
|
py = b->y+nx/nn*r;
|
||||||
|
|
||||||
if (!intersect(fx, fy, tx, ty, px, py, dx, dy, &na, &nb))
|
if (!intersect(fx, fy, tx, ty, px, py, dx, dy, &na, &nb))
|
||||||
return 0;
|
return 0;
|
||||||
if (nb <= 0) {
|
if (nb <= 0) {
|
||||||
if (!touch(fx, fy, tx, ty, a->x, a->y, r, enter, &na))
|
if (!touch(fx, fy, tx, ty, a, b, c, r, enter, left, &na))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (nb >= 1) {
|
if (nb >= 1) {
|
||||||
if (!touch(fx, fy, tx, ty, b->x, b->y, r, enter, &na))
|
if (!touch(fx, fy, tx, ty, b, c, d, r, enter, left, &na))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (na <= 0 || na >= 1)
|
if (na <= 0 || na >= 1)
|
||||||
@ -204,21 +287,28 @@ static int hit_segment(double fx, double fy, double tx, double ty,
|
|||||||
static int hit_path(double fx, double fy, double tx, double ty,
|
static int hit_path(double fx, double fy, double tx, double ty,
|
||||||
const struct path *path, int inside, int enter, double r, double *x)
|
const struct path *path, int inside, int enter, double r, double *x)
|
||||||
{
|
{
|
||||||
const struct point *p;
|
const struct point *p, *last, *next2;
|
||||||
int left;
|
int left;
|
||||||
double nx, tmp;
|
double nx, tmp;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @@@ We don't wrap around the ends properly and create a zero-sized
|
||||||
|
* imaginary segment between path->first and path->last.
|
||||||
|
*/
|
||||||
left = path_tool_is_left(path);
|
left = path_tool_is_left(path);
|
||||||
if (inside)
|
if (inside)
|
||||||
left = !left;
|
left = !left;
|
||||||
|
last = path->last;
|
||||||
for (p = path->first; p != path->last; p = p->next) {
|
for (p = path->first; p != path->last; p = p->next) {
|
||||||
if (hit_segment(fx, fy, tx, ty, p, p->next,
|
next2 = p->next->next ? p->next->next : path->first;
|
||||||
|
if (hit_segment(fx, fy, tx, ty, last, p, p->next, next2,
|
||||||
r, enter, left, &tmp)) {
|
r, enter, left, &tmp)) {
|
||||||
if (!found || nx > tmp)
|
if (!found || nx > tmp)
|
||||||
nx = tmp;
|
nx = tmp;
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
|
last = p;
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
*x = fx+nx*(tx-fx);
|
*x = fx+nx*(tx-fx);
|
||||||
|
Loading…
Reference in New Issue
Block a user