-I$(top_srcdir)/lib/cdt @GD_INCLUDES@ @EXPAT_INCLUDES@ @Z_INCLUDES@
pkginclude_HEADERS = const.h globals.h htmllex.h htmltable.h macros.h \
- pointset.h render.h renderprocs.h types.h utils.h colortbl.h
+ pointset.h render.h renderprocs.h types.h utils.h colortbl.h geom.h
noinst_LTLIBRARIES = libcommon.la
if !DISABLE_CODEGENS
args.c gdtextsize.c gdusershape.c \
globals.c htmllex.c htmlparse.y htmltable.c input.c \
pointset.c postproc.c psusershape.c routespl.c splines.c \
- svgusershape.c timing.c labels.c ns.c shapes.c utils.c \
+ svgusershape.c timing.c labels.c ns.c shapes.c utils.c geom.c \
output.c emit.c $(CODEGENS)
psgen.o psgen.lo : ps.h
#define EPSILON .0001
-#define sqr(a) ((double) (a) * (a))
-#define dstsq(a, b) (sqr (a.x - b.x) + sqr (a.y - b.y))
-#define dst(a, b) sqrt (dsts
-
/* standard arrow length in points */
#define ARROW_LENGTH 10.
/* inside function for calls to bezier_clip */
static boolean inside(inside_t * inside_context, pointf p)
{
- return dstsq(p, inside_context->a.p[0]) <= inside_context->a.r[0];
+ return DIST2(p, inside_context->a.p[0]) <= inside_context->a.r[0];
}
int arrowEndClip(edge_t* e, point * ps, int startp,
elen = arrow_length(e, eflag);
elen2 = elen * elen;
spl->eflag = eflag, spl->ep = ps[endp + 3];
- if (endp > startp && dstsq(ps[endp], ps[endp + 3]) < elen2) {
+ if (endp > startp && DIST2(ps[endp], ps[endp + 3]) < elen2) {
endp -= 3;
}
P2PF(ps[endp], sp[3]);
slen = arrow_length(e, sflag);
slen2 = slen * slen;
spl->sflag = sflag, spl->sp = ps[startp];
- if (endp > startp && dstsq(ps[startp], ps[startp + 3]) < slen2) {
+ if (endp > startp && DIST2(ps[startp], ps[startp + 3]) < slen2) {
startp += 3;
}
P2PF(ps[startp + 3], sp[0]);
int box_connection(node_t * n, pointf p)
{
int i = 0, j, sides, conn = 0, peripheries, z;
- double xsize, ysize, mindist = 0.0, dist;
+ double xsize, ysize, mindist2 = 0.0, dist2;
polygon_t *poly;
pointf P, *vertices;
static point *A;
z = 0;
while (z < i) {
- dist = DIST(p.x, p.y, diapt(A[z]).x, diapt(A[z]).y);
+ dist2 = DIST2(p, diapt(A[z]));
if (z == 0) {
- mindist = dist;
+ mindist2 = dist2;
conn = 0;
}
- if (dist < mindist) {
- mindist = dist;
+ if (dist2 < mindist2) {
+ mindist2 = dist2;
conn = 2 * z;
}
z++;
z = 0;
while (z < i) {
- dist =
- DIST(p.x, p.y, (diapt(A[z]).x + diapt(A[z + 1]).x) / 2,
- (diapt(A[z]).y + diapt(A[z + 1]).y) / 2);
- if (dist < mindist) {
- mindist = dist;
+ P.x = (diapt(A[z]).x + diapt(A[z + 1]).x) / 2;
+ P.y = (diapt(A[z]).y + diapt(A[z + 1]).y) / 2;
+ dist2 = DIST2(p, P);
+ if (dist2 < mindist2) {
+ mindist2 = dist2;
conn = 2 * z + 1;
}
z++;
* AT&T Research, Florham Park NJ *
**********************************************************/
+/* geometric functions (e.g. on points and boxes) with application to, but
+ * no specific dependance on graphs */
+
#include <assert.h>
#include <math.h>
#include <stdio.h>
return p;
}
-/* from Glassner's Graphics Gems */
-#define W_DEGREE 5
-
-/*
- * Bezier :
- * Evaluate a Bezier curve at a particular parameter value
- * Fill in control points for resulting sub-curves if "Left" and
- * "Right" are non-null.
- *
- */
-pointf Bezier(pointf * V, int degree, double t, pointf * Left,
- pointf * Right)
-{
- int i, j; /* Index variables */
- pointf Vtemp[W_DEGREE + 1][W_DEGREE + 1];
-
- /* Copy control points */
- for (j = 0; j <= degree; j++) {
- Vtemp[0][j] = V[j];
- }
-
- /* Triangle computation */
- for (i = 1; i <= degree; i++) {
- for (j = 0; j <= degree - i; j++) {
- Vtemp[i][j].x =
- (1.0 - t) * Vtemp[i - 1][j].x + t * Vtemp[i - 1][j + 1].x;
- Vtemp[i][j].y =
- (1.0 - t) * Vtemp[i - 1][j].y + t * Vtemp[i - 1][j + 1].y;
- }
- }
-
- if (Left != NULL)
- for (j = 0; j <= degree; j++)
- Left[j] = Vtemp[j][0];
- if (Right != NULL)
- for (j = 0; j <= degree; j++)
- Right[j] = Vtemp[degree - j][j];
-
- return (Vtemp[degree][0]);
-}
-
box box_bb(box b0, box b1)
{
box b;
return CONTAINS(b0, b1);
}
-point closest_spline_point(splines * spl, point p)
-{
- int i, j, k, besti, bestj;
- double bestdist2, d2, dlow2, dhigh2; /* squares of distances */
- double low, high, t;
- pointf c[4], pt2, pt;
- point rv;
- bezier bz;
-
- besti = bestj = -1;
- bestdist2 = 1e+38;
- P2PF(p, pt);
- for (i = 0; i < spl->size; i++) {
- bz = spl->list[i];
- for (j = 0; j < bz.size; j++) {
- pointf b;
-
- b.x = bz.list[j].x;
- b.y = bz.list[j].y;
- d2 = DIST2(b, pt);
- if ((bestj == -1) || (d2 < bestdist2)) {
- besti = i;
- bestj = j;
- bestdist2 = d2;
- }
- }
- }
-
- bz = spl->list[besti];
- j = bestj / 3;
- if (j >= spl->size)
- j--;
- for (k = 0; k < 4; k++) {
- c[k].x = bz.list[j + k].x;
- c[k].y = bz.list[j + k].y;
- }
- low = 0.0;
- high = 1.0;
- dlow2 = DIST2(c[0], pt);
- dhigh2 = DIST2(c[3], pt);
- do {
- t = (low + high) / 2.0;
- pt2 = Bezier(c, 3, t, NULL, NULL);
- if (fabs(dlow2 - dhigh2) < 1.0)
- break;
- if (fabs(high - low) < .00001)
- break;
- if (dlow2 < dhigh2) {
- high = t;
- dhigh2 = DIST2(pt2, pt);
- } else {
- low = t;
- dlow2 = DIST2(pt2, pt);
- }
- } while (1);
- PF2P(pt2, rv);
- return rv;
-}
-
-point spline_at_y(splines * spl, int y)
-{
- int i, j;
- double low, high, d, t;
- pointf c[4], pt2;
- point pt;
- static bezier bz;
-
-/* this caching seems to prevent pt.x from getting set from bz.list[0].x
- - optimizer problem ? */
-
-#if 0
- static splines *mem = NULL;
-
- if (mem != spl) {
- mem = spl;
-#endif
- for (i = 0; i < spl->size; i++) {
- bz = spl->list[i];
- if (BETWEEN(bz.list[bz.size - 1].y, y, bz.list[0].y))
- break;
- }
-#if 0
- }
-#endif
- if (y > bz.list[0].y)
- pt = bz.list[0];
- else if (y < bz.list[bz.size - 1].y)
- pt = bz.list[bz.size - 1];
- else {
- for (i = 0; i < bz.size; i += 3) {
- for (j = 0; j < 3; j++) {
- if ((bz.list[i + j].y <= y) && (y <= bz.list[i + j + 1].y))
- break;
- if ((bz.list[i + j].y >= y) && (y >= bz.list[i + j + 1].y))
- break;
- }
- if (j < 3)
- break;
- }
- assert(i < bz.size);
- for (j = 0; j < 4; j++) {
- c[j].x = bz.list[i + j].x;
- c[j].y = bz.list[i + j].y;
- /* make the spline be monotonic in Y, awful but it works for now */
- if ((j > 0) && (c[j].y > c[j - 1].y))
- c[j].y = c[j - 1].y;
- }
- low = 0.0;
- high = 1.0;
- do {
- t = (low + high) / 2.0;
- pt2 = Bezier(c, 3, t, NULL, NULL);
- d = pt2.y - y;
- if (ABS(d) <= 1)
- break;
- if (d < 0)
- high = t;
- else
- low = t;
- } while (1);
- pt.x = pt2.x;
- pt.y = pt2.y;
- }
- pt.y = y;
- return pt;
-}
-
-point neato_closest(splines * spl, point p)
-{
-/* this is a stub so that we can share a common emit.c between dot and neato */
-
- return spline_at_y(spl, p.y);
-}
-
/*
*--------------------------------------------------------------
*
* AT&T Research, Florham Park NJ *
**********************************************************/
+/* geometric functions (e.g. on points and boxes) with application to, but
+ * no specific dependance on graphs */
+
#ifdef __cplusplus
extern "C" {
#endif
-
+
extern point pointof(int, int);
extern pointf cvt2ptf(point);
extern point cvt2pt(pointf);
extern pointf flip_ptf(pointf p, int rankdir);
extern point invflip_pt(point p, int rankdir);
- extern pointf Bezier(pointf *, int, double, pointf *, pointf *);
- extern point closest_spline_point(splines * spl, point p);
- extern point neato_closest(splines * spl, point p);
- extern point spline_at_y(splines * spl, int y);
-
#ifdef __cplusplus
}
#endif
#define NOTUSED(var) (void) var
#endif
+#ifndef NULL
+#define NULL (void *)0
+#endif
+
#ifndef NIL
#define NIL(type) ((type)0)
#endif
#define ROUND(f) ((f>=0)?(int)(f + .5):(int)(f - .5))
#define RADIANS(deg) ((deg)/180.0 * PI)
#define DEGREES(rad) ((rad)/PI * 180.0)
-#define DIST(x1,y1,x2,y2) (sqrt(((x1) - (x2))*((x1) - (x2)) + ((y1) - (y2))*((y1) - (y2))))
+
+#define SQR(v) ((v) * (v))
+#define DIST2(p1,p2) (SQR((p1.x) - (p2.x))) + (SQR((p1.y) - (p2.y)))
+#define DIST(p1,p2) (sqrt(DIST2((p1),(p2))))
+
#define POINTS_PER_INCH 72
#define POINTS(f_inch) (ROUND((f_inch)*POINTS_PER_INCH))
#define PS2INCH(ps) ((ps)/(double)POINTS_PER_INCH)
return cvt2pt(pf);
}
-point pointof(int x, int y)
-{
- point rv;
- rv.x = x, rv.y = y;
- return rv;
-}
-
-point cvt2pt(pointf p)
-{
- point rv;
- rv.x = POINTS(p.x);
- rv.y = POINTS(p.y);
- return rv;
-}
-
-pointf cvt2ptf(point p)
-{
- pointf rv;
- rv.x = PS2INCH(p.x);
- rv.y = PS2INCH(p.y);
- return rv;
-}
-
-box boxof(int llx, int lly, int urx, int ury)
-{
- box b;
-
- b.LL.x = llx, b.LL.y = lly;
- b.UR.x = urx, b.UR.y = ury;
- return b;
-}
-
-boxf boxfof(double llx, double lly, double urx, double ury)
-{
- boxf b;
-
- b.LL.x = llx, b.LL.y = lly;
- b.UR.x = urx, b.UR.y = ury;
- return b;
-}
-
-box mkbox(point p0, point p1)
-{
- box rv;
-
- if (p0.x < p1.x) {
- rv.LL.x = p0.x;
- rv.UR.x = p1.x;
- } else {
- rv.LL.x = p1.x;
- rv.UR.x = p0.x;
- }
- if (p0.y < p1.y) {
- rv.LL.y = p0.y;
- rv.UR.y = p1.y;
- } else {
- rv.LL.y = p1.y;
- rv.UR.y = p0.y;
- }
- return rv;
-}
-
-boxf mkboxf(pointf p0, pointf p1)
-{
- boxf rv;
-
- if (p0.x < p1.x) {
- rv.LL.x = p0.x;
- rv.UR.x = p1.x;
- } else {
- rv.LL.x = p1.x;
- rv.UR.x = p0.x;
- }
- if (p0.y < p1.y) {
- rv.LL.y = p0.y;
- rv.UR.y = p1.y;
- } else {
- rv.LL.y = p1.y;
- rv.UR.y = p0.y;
- }
- return rv;
-}
-
-point add_points(point p0, point p1)
-{
- p0.x += p1.x;
- p0.y += p1.y;
- return p0;
-}
-
-point sub_points(point p0, point p1)
-{
- p0.x -= p1.x;
- p0.y -= p1.y;
- return p0;
-}
-
-pointf add_pointfs(pointf p0, pointf p1)
-{
- p0.x += p1.x;
- p0.y += p1.y;
- return p0;
-}
-
-pointf sub_pointfs(pointf p0, pointf p1)
-{
- p0.x -= p1.x;
- p0.y -= p1.y;
- return p0;
-}
-
-point exch_xy(point p)
-{
- int t;
- t = p.x;
- p.x = p.y;
- p.y = t;
- return p;
-}
-
-pointf exch_xyf(pointf p)
-{
- double t;
- t = p.x;
- p.x = p.y;
- p.y = t;
- return p;
-}
-
/* from Glassner's Graphics Gems */
#define W_DEGREE 5
}
}
-box box_bb(box b0, box b1)
-{
- box b;
-
- b.LL.x = MIN(b0.LL.x, b1.LL.x);
- b.LL.y = MIN(b0.LL.y, b1.LL.y);
- b.UR.x = MAX(b0.UR.x, b1.UR.x);
- b.UR.y = MAX(b0.UR.y, b1.UR.y);
-
- return b;
-}
-
-boxf boxf_bb(boxf b0, boxf b1)
-{
- boxf b;
-
- b.LL.x = MIN(b0.LL.x, b1.LL.x);
- b.LL.y = MIN(b0.LL.y, b1.LL.y);
- b.UR.x = MAX(b0.UR.x, b1.UR.x);
- b.UR.y = MAX(b0.UR.y, b1.UR.y);
-
- return b;
-}
-
-box box_intersect(box b0, box b1)
-{
- box b;
-
- b.LL.x = MAX(b0.LL.x, b1.LL.x);
- b.LL.y = MAX(b0.LL.y, b1.LL.y);
- b.UR.x = MIN(b0.UR.x, b1.UR.x);
- b.UR.y = MIN(b0.UR.y, b1.UR.y);
-
- return b;
-}
-
-boxf boxf_intersect(boxf b0, boxf b1)
-{
- boxf b;
-
- b.LL.x = MAX(b0.LL.x, b1.LL.x);
- b.LL.y = MAX(b0.LL.y, b1.LL.y);
- b.UR.x = MIN(b0.UR.x, b1.UR.x);
- b.UR.y = MIN(b0.UR.y, b1.UR.y);
-
- return b;
-}
-
-boolean box_overlap(box b0, box b1)
-{
- return OVERLAP(b0, b1);
-}
-
-boolean boxf_overlap(boxf b0, boxf b1)
-{
- return OVERLAP(b0, b1);
-}
-
-boolean box_contains(box b0, box b1)
-{
- return CONTAINS(b0, b1);
-}
-
-boolean boxf_contains(boxf b0, boxf b1)
-{
- return CONTAINS(b0, b1);
-}
-
int maptoken(char *p, char **name, int *val)
{
int i;
return atoi(p);
}
-static double dist2(pointf p, pointf q) /* return square of dist between p and q */
-{
- double d0, d1;
-
- d0 = p.x - q.x;
- d1 = p.y - q.y;
- return (d0 * d0 + d1 * d1);
-}
-
point dotneato_closest(splines * spl, point p)
{
int i, j, k, besti, bestj;
return r;
}
-/* flip_ptf:
- * Transform point =>
- * LR - rotate ccw by 90
- * BT - reflect across x axis
- * RL - TB o LR
- */
-point flip_pt(point p, int rankdir)
-{
- int x = p.x, y = p.y;
- switch (rankdir) {
- case RANKDIR_TB:
- break;
- case RANKDIR_LR:
- p.x = -y;
- p.y = x;
- break;
- case RANKDIR_BT:
- p.x = x;
- p.y = -y;
- break;
- case RANKDIR_RL:
- p.x = y;
- p.y = x;
- break;
- }
- return p;
-}
-
-/* flip_ptf:
- * flip_pt for pointf type.
- */
-pointf flip_ptf(pointf p, int rankdir)
-{
- double x = p.x, y = p.y;
- switch (rankdir) {
- case RANKDIR_TB:
- break;
- case RANKDIR_LR:
- p.x = -y;
- p.y = x;
- break;
- case RANKDIR_BT:
- p.x = x;
- p.y = -y;
- break;
- case RANKDIR_RL:
- p.x = y;
- p.y = x;
- break;
- }
- return p;
-}
-
-/* invflip_pt:
- * Transform point =>
- * LR - rotate cw by 90
- * BT - reflect across x axis
- * RL - TB o LR
- * Note that flip and invflip only differ on LR
- */
-point invflip_pt(point p, int rankdir)
-{
- int x = p.x, y = p.y;
- switch (rankdir) {
- case RANKDIR_TB:
- break;
- case RANKDIR_LR:
- p.x = y;
- p.y = -x;
- break;
- case RANKDIR_BT:
- p.x = x;
- p.y = -y;
- break;
- case RANKDIR_RL:
- p.x = y;
- p.y = x;
- break;
- }
- return p;
-}
-
-box flip_rec_box(box b, point p)
-{
- box rv;
- /* flip box */
- rv.UR.x = b.UR.y;
- rv.UR.y = b.UR.x;
- rv.LL.x = b.LL.y;
- rv.LL.y = b.LL.x;
- /* move box */
- rv.LL.x += p.x;
- rv.LL.y += p.y;
- rv.UR.x += p.x;
- rv.UR.y += p.y;
- return rv;
-}
-
/* addLabelBB:
*/
static box addLabelBB(box bb, textlabel_t * lp, boolean flipxy)
b.LL = sub_points(pt, s2);
b.UR = add_points(pt, s2);
- bb.LL.x = MIN(bb.LL.x, b.LL.x);
- bb.LL.y = MIN(bb.LL.y, b.LL.y);
- bb.UR.x = MAX(bb.UR.x, b.UR.x);
- bb.UR.y = MAX(bb.UR.y, b.UR.y);
+ EXPANDBB(bb,b);
for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
if (ED_spl(e) == 0)
continue;
for (i = 0; i < ED_spl(e)->size; i++) {
for (j = 0; j < ED_spl(e)->list[i].size; j++) {
pt = ED_spl(e)->list[i].list[j];
- if (bb.LL.x > pt.x)
- bb.LL.x = pt.x;
- if (bb.LL.y > pt.y)
- bb.LL.y = pt.y;
- if (bb.UR.x < pt.x)
- bb.UR.x = pt.x;
- if (bb.UR.y < pt.y)
- bb.UR.y = pt.y;
+ EXPANDBP(bb,pt);
}
}
if (ED_label(e) && ED_label(e)->set)
}
for (i = 1; i <= GD_n_cluster(g); i++) {
- bb.LL.x = MIN(bb.LL.x, GD_clust(g)[i]->u.bb.LL.x);
- bb.LL.y = MIN(bb.LL.y, GD_clust(g)[i]->u.bb.LL.y);
- bb.UR.x = MAX(bb.UR.x, GD_clust(g)[i]->u.bb.UR.x);
- bb.UR.y = MAX(bb.UR.y, GD_clust(g)[i]->u.bb.UR.y);
+ EXPANDBB(bb,GD_clust(g)[i]->u.bb);
}
GD_bb(g) = bb;
return ns;
}
-/*
- *--------------------------------------------------------------
- *
- * lineToBox --
- *
- * Determine whether a line lies entirely inside, entirely
- * outside, or overlapping a given rectangular area.
- *
- * Results:
- * -1 is returned if the line given by p1 and p2
- * is entirely outside the rectangle given by b.
- * 0 is returned if the polygon overlaps the rectangle, and
- * 1 is returned if the polygon is entirely inside the rectangle.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
-/* This code steals liberally from algorithms in tk/generic/tkTrig.c -- jce */
-
-static int lineToBox(pointf p1, pointf p2, boxf b)
-{
- int inside1, inside2;
-
- /*
- * First check the two points individually to see whether they
- * are inside the rectangle or not.
- */
-
- inside1 = (p1.x >= b.LL.x) && (p1.x <= b.UR.x)
- && (p1.y >= b.LL.y) && (p1.y <= b.UR.y);
- inside2 = (p2.x >= b.LL.x) && (p2.x <= b.UR.x)
- && (p2.y >= b.LL.y) && (p2.y <= b.UR.y);
- if (inside1 != inside2) {
- return 0;
- }
- if (inside1 & inside2) {
- return 1;
- }
-
- /*
- * Both points are outside the rectangle, but still need to check
- * for intersections between the line and the rectangle. Horizontal
- * and vertical lines are particularly easy, so handle them
- * separately.
- */
-
- if (p1.x == p2.x) {
- /*
- * Vertical line.
- */
-
- if (((p1.y >= b.LL.y) ^ (p2.y >= b.LL.y))
- && (p1.x >= b.LL.x)
- && (p1.x <= b.UR.x)) {
- return 0;
- }
- } else if (p1.y == p2.y) {
- /*
- * Horizontal line.
- */
- if (((p1.x >= b.LL.x) ^ (p2.x >= b.LL.x))
- && (p1.y >= b.LL.y)
- && (p1.y <= b.UR.y)) {
- return 0;
- }
- } else {
- double m, x, y, low, high;
-
- /*
- * Diagonal line. Compute slope of line and use
- * for intersection checks against each of the
- * sides of the rectangle: left, right, bottom, top.
- */
-
- m = (p2.y - p1.y)/(p2.x - p1.x);
- if (p1.x < p2.x) {
- low = p1.x; high = p2.x;
- } else {
- low = p2.x; high = p1.x;
- }
-
- /*
- * Left edge.
- */
-
- y = p1.y + (b.LL.x - p1.x)*m;
- if ((b.LL.x >= low) && (b.LL.x <= high)
- && (y >= b.LL.y) && (y <= b.UR.y)) {
- return 0;
- }
-
- /*
- * Right edge.
- */
-
- y += (b.UR.x - b.LL.x)*m;
- if ((y >= b.LL.y) && (y <= b.UR.y)
- && (b.UR.x >= low) && (b.UR.x <= high)) {
- return 0;
- }
-
- /*
- * Bottom edge.
- */
-
- if (p1.y < p2.y) {
- low = p1.y; high = p2.y;
- } else {
- low = p2.y; high = p1.y;
- }
- x = p1.x + (b.LL.y - p1.y)/m;
- if ((x >= b.LL.x) && (x <= b.UR.x)
- && (b.LL.y >= low) && (b.LL.y <= high)) {
- return 0;
- }
-
- /*
- * Top edge.
- */
-
- x += (b.UR.y - b.LL.y)/m;
- if ((x >= b.LL.x) && (x <= b.UR.x)
- && (b.UR.y >= low) && (b.UR.y <= high)) {
- return 0;
- }
- }
- return -1;
-}
-
boolean overlap_node(node_t *n, boxf b)
{
boxf bb;
#include "config.h"
#endif
+#include "geom.h"
+
#ifndef HAVE_STRCASECMP
extern int strcasecmp(const char *s1, const char *s2);
#endif
extern void UF_singleton(Agnode_t *);
extern void UF_setname(Agnode_t *, Agnode_t *);
- extern point pointof(int, int);
- extern pointf cvt2ptf(point);
- extern point cvt2pt(pointf);
- extern point add_points(point, point);
- extern pointf add_pointfs(pointf, pointf);
- extern point sub_points(point, point);
- extern pointf sub_pointfs(pointf, pointf);
- extern point exch_xy(point p);
- extern pointf exch_xyf(pointf p);
- extern point flip_pt(point p, int rankdir);
- extern pointf flip_ptf(pointf p, int rankdir);
- extern point invflip_pt(point p, int rankdir);
-
- extern box boxof(int llx, int lly, int urx, int ury);
- extern boxf boxfof(double llx, double lly, double urx, double ury);
- extern box mkbox(point, point);
- extern boxf mkboxf(pointf, pointf);
- extern box box_bb(box, box);
- extern boxf boxf_bb(boxf, boxf);
- extern box box_intersect(box, box);
- extern boxf boxf_intersect(boxf, boxf);
- extern boolean box_overlap(box, box);
- extern boolean boxf_overlap(boxf, boxf);
- extern boolean box_contains(box, box);
- extern boolean boxf_contains(boxf, boxf);
- extern box flip_rec_box(box b, point p);
-
- extern pointf Bezier(pointf *, int, double, pointf *, pointf *);
- extern point dotneato_closest(splines * spl, point p);
- extern point neato_closest(splines * spl, point p);
- extern point spline_at_y(splines * spl, int y);
-
extern char *username(void);
extern char *safefile(char *shapefilename);
extern void cat_libfile(FILE *, char **, char **);
extern char *latin1ToUTF8(char *);
extern char* utf8ToLatin1 (char* ins);
+ extern pointf Bezier(pointf *, int, double, pointf *, pointf *);
+ extern point dotneato_closest(splines * spl, point p);
+ extern point neato_closest(splines * spl, point p);
+ extern point spline_at_y(splines * spl, int y);
+
#ifdef __cplusplus
}
#endif
static context_t cstk[MAXNEST];
static int SP;
-static double DIST2(pointf p, point q)
-{
- double delx = p.x - q.x;
- double dely = p.y - q.y;
- return (delx*delx + dely*dely);
-}
-
static char *nodeURL(node_t * n, char *buf)
{
sprintf(buf, "node%d.png", n->id);
}
}
-static double
-idist2 (point p0, point p1)
-{
- double delx, dely;
-
- delx = p0.x - p1.x;
- dely = p0.y - p1.y;
- return (delx*delx + dely*dely);
-}
-
/* interpolate_zcoord:
* Given 2 points in 3D p = (fst.x,fst.y,fstz) and q = (snd.x, snd.y, sndz),
* and a point p1 in the xy plane lying on the line segment connecting
rv = fstz + (sndz - fstz) * (p1.y - fst.y) / (snd.y - fst.y);
}
else {
- len = sqrt(idist2(fst, snd));
- d = sqrt(DIST2(p1, fst))/len;
+ len = DIST(fst, snd);
+ d = DIST(p1, fst)/len;
rv = fstz + d*(sndz - fstz);
}
return rv;
dely = p0.y - p1.y;
delz = z0 - z1;
EdgeLen = sqrt(delx*delx + dely*dely + delz*delz);
- d0 = sqrt(idist2(A[0],p0));
- d1 = sqrt(idist2(A[3],p1));
+ d0 = DIST(A[0],p0);
+ d1 = DIST(A[3],p1);
CylHt = EdgeLen - d0 - d1;
TailHt = HeadHt = 0;
p0.x = (A[0].x + A[2].x)/2.0;
p0.y = (A[0].y + A[2].y)/2.0;
- rad = sqrt(idist2(A[0],A[2]))/2.0;
- ht = sqrt(DIST2(p0,A[1]));
+ rad = DIST(A[0],A[2])/2.0;
+ ht = DIST(p0,A[1]);
y = (CylHt + ht)/2.0;
tp = ND_coord_i(Curedge->tail);
hp = ND_coord_i(Curedge->head);
fprintf(Output_file, "Transform {\n");
- if (idist2(A[1], tp) < idist2(A[1], hp)) {
+ if (DIST2(A[1], tp) < DIST2(A[1], hp)) {
TailHt = ht;
fprintf(Output_file, " translation 0 -%.3f 0\n", y);
fprintf(Output_file, " rotation 0 0 1 %.3f\n", PI);
return ans;
}
-static double dist2(pointf p, pointf q) /* square of distance between p and q */
-{
- double d0, d1;
-
- d0 = p.x - q.x;
- d1 = p.y - q.y;
- return (d0 * d0 + d1 * d1);
-}
-
point closest(splines * spl, point p)
{
int i, j, k, besti, bestj;
b.x = bz.list[j].x;
b.y = bz.list[j].y;
- d2 = dist2(b, pt);
+ d2 = DIST2(b, pt);
if ((bestj == -1) || (d2 < bestdist2)) {
besti = i;
bestj = j;
}
low = 0.0;
high = 1.0;
- dlow2 = dist2(c[0], pt);
- dhigh2 = dist2(c[3], pt);
+ dlow2 = DIST2(c[0], pt);
+ dhigh2 = DIST2(c[3], pt);
do {
t = (low + high) / 2.0;
pt2 = Bezier(c, 3, t, NULL, NULL);
break;
if (dlow2 < dhigh2) {
high = t;
- dhigh2 = dist2(pt2, pt);
+ dhigh2 = DIST2(pt2, pt);
} else {
low = t;
- dlow2 = dist2(pt2, pt);
+ dlow2 = DIST2(pt2, pt);
}
} while (1);
PF2P(pt2, rv);