26 #define ISBOX(p) ((p)->kind & BOX)
28 #define ISCIRCLE(p) ((p)->kind & CIRCLE)
30 static int maxcnt = 0;
56 xmin = xmax = verts->
x;
57 ymin = ymax = verts->
y;
58 for (i = 1; i < cnt; i++) {
76 static void inflate(
Point * prev,
Point * cur,
Point * next,
double margin)
78 double theta = atan2(prev->
y - cur->
y, prev->
x - cur->
x);
79 double phi = atan2(next->
y - cur->
y, next->
x - cur->
x);
80 double beta = (theta + phi) / 2.0;
81 double gamma = (
M_PI + phi - theta) / 2.0;
85 cur->
x -= margin * (cos(beta)) / denom;
86 cur->
y -= margin * (sin(beta)) / denom;
89 static void inflatePts(
Point * verts,
int cnt,
double margin)
95 Point *prev = &prevpoint;
100 prevpoint = verts[cnt - 1];
103 for (i = 0; i < cnt - 1; i++) {
105 inflate(prev, cur, next, margin);
108 prevpoint = savepoint;
112 inflate(prev, cur, next, margin);
115 static void inflatePts(
Point * verts,
int cnt,
float xmargin,
float ymargin)
121 for (i = 0; i < cnt; i++) {
129 static int isBox(
Point * verts,
int cnt)
134 if (verts[0].y == verts[1].y)
135 return ((verts[2].y == verts[3].y) &&
136 (verts[0].x == verts[3].x) && (verts[1].x == verts[2].x));
138 return ((verts[0].x == verts[1].x) &&
139 (verts[2].x == verts[3].x) &&
140 (verts[0].y == verts[3].y) && (verts[1].y == verts[2].y));
143 static Point makeScaledTransPoint(
int x,
int y,
float dx,
float dy)
151 static Point makeScaledPoint(
double x,
double y)
159 static Point *genRound(
Agnode_t * n,
int *sidep,
float xm,
float ym)
163 char *p =
agget(n,
"samplepoints");
171 for (i = 0; i < sides; i++) {
173 (
ND_width(n) / 2.0 + xm) * cos(i / (
double) sides *
M_PI * 2.0);
175 (
ND_height(n) / 2.0 + ym) * sin(i / (
double) sides *
M_PI * 2.0);
181 #define PUTPT(P,X,Y) ((P).x=(X),(P).y=(Y))
235 for (i = 0; i < sides; i++) {
237 verts[i].
x = poly->
vertices[i].
x * (1.0 + xmargin/h);
238 verts[i].
y = poly->
vertices[i].
y * (1.0 + ymargin/h);
244 verts = genRound(n, &sides, xmargin, ymargin);
250 verts[0] = makeScaledTransPoint(b.
LL.
x, b.
LL.
y, -xmargin, -ymargin);
251 verts[1] = makeScaledTransPoint(b.
UR.
x, b.
LL.
y, xmargin, -ymargin);
252 verts[2] = makeScaledTransPoint(b.
UR.
x, b.
UR.
y, xmargin, ymargin);
253 verts[3] = makeScaledTransPoint(b.
LL.
x, b.
UR.
y, -xmargin, ymargin);
258 verts = genRound(n, &sides, xmargin, ymargin);
261 agerr(
AGERR,
"makeAddPoly: unknown shape type %s\n",
301 for (i = 0; i < sides; i++) {
306 verts = genRound(n, &sides, 0, 0);
311 && isBox(verts, sides))
323 verts[0] = makeScaledPoint(b.
LL.
x, b.
LL.
y);
324 verts[1] = makeScaledPoint(b.
UR.
x, b.
LL.
y);
325 verts[2] = makeScaledPoint(b.
UR.
x, b.
UR.
y);
326 verts[3] = makeScaledPoint(b.
LL.
x, b.
UR.
y);
331 verts = genRound(n, &sides, 0, 0);
334 agerr(
AGERR,
"makePoly: unknown shape type %s\n",
341 inflatePts(verts, sides, margin);
343 if ((xmargin != 1.0) || (ymargin != 1.0))
344 inflatePts(verts, sides, xmargin, ymargin);
359 return ((originp.
x <= cornerq.
x) && (originq.
x <= cornerp.
x) &&
360 (originp.
y <= cornerq.
y) && (originq.
y <= cornerp.
y));
367 #define advance(A,B,N) (B++, A = (A+1)%N)
369 static int edgesIntersect(
Point * P,
Point * Q,
int n,
int m)
385 a1 = (a + n - 1) % n;
386 b1 = (b + m - 1) % m;
388 subpt(&A, P[a], P[a1]);
389 subpt(&B, Q[b], Q[b1]);
392 bHA =
leftOf(P[a1], P[a], Q[b]);
393 aHB =
leftOf(Q[b1], Q[b], P[a]);
400 if ((cross == 0) && !bHA && !aHB) {
405 }
else if (cross >= 0)
418 }
while (((aa < n) || (ba < m)) && (aa < 2 * n) && (ba < 2 * m));
432 double crossings = 0;
438 for (i = 0; i < n; i++) {
439 tp3[i].
x = vertex[i].
x - q.
x;
440 tp3[i].
y = vertex[i].
y - q.
y;
444 for (i = 0; i < n; i++) {
445 i1 = (i + n - 1) % n;
448 if ((tp3[i].y == 0) && (tp3[i1].
y == 0)) {
449 if ((tp3[i].x * tp3[i1].x) < 0) {
457 if (((tp3[i].y >= 0) && (tp3[i1].
y <= 0)) ||
458 ((tp3[i1].
y >= 0) && (tp3[i].y <= 0))) {
460 x = (tp3[i].
x * tp3[i1].
y - tp3[i1].
x * tp3[i].
y)
461 / (
double) (tp3[i1].
y - tp3[i].
y);
469 if ((tp3[i].y == 0) || (tp3[i1].
y == 0)) {
479 if ((((
int) crossings) % 2) == 1)
487 return ((p.
x <= corner.
x) &&
488 (p.
x >= origin.
x) && (p.
y <= corner.
y) && (p.
y >= origin.
y));
496 for (i = 0; i < cnt; i++) {
497 outp->
x = inp->
x + off.
x;
498 outp->
y = inp->
y + off.
y;
516 if (!pintersect(op, cp, oq, cq))
524 double dx = p.
x - q.
x;
525 double dy = p.
y - q.
y;
526 if ((dx * dx + dy * dy) > (d * d) / 4.0)
539 return (edgesIntersect(tp1, tp2, pp->
nverts, qp->
nverts) ||
540 (inBox(*tp1, oq, cq) && inPoly(tp2, qp->
nverts, *tp1)) ||
541 (inBox(*tp2, op, cp) && inPoly(tp1, pp->
nverts, *tp2)));
shape_kind shapeOf(node_t *)
int makeAddPoly(Poly *pp, Agnode_t *n, float xmargin, float ymargin)
int agerr(agerrlevel_t level, const char *fmt,...)
#define PS2INCH(a_points)
char * agget(void *obj, char *name)
int leftOf(Point a, Point b, Point c)
int makePoly(Poly *pp, Agnode_t *n, float xmargin, float ymargin)
if(aagss+aagstacksize-1<=aagssp)
double area_2(Point a, Point b, Point c)
void addpt(Point *c, Point a, Point b)
void subpt(Point *a, Point b, Point c)
int polyOverlap(Point p, Poly *pp, Point q, Poly *qp)
int intersection(Point a, Point b, Point c, Point d, Point *p)