33static int debugleveln(
edge_t *e,
int i) {
39static void showPoints(
pointf ps[],
int pn) {
44 for (bi = 0; bi < pn; bi++) {
46 agxbprint(&buf,
"%.5g %.5g point", ps[bi].x, ps[bi].y);
70 j =
info->swapEnds(e);
71 uint32_t sflag, eflag;
73 if (
info->splineMerge(hn))
103 double low, high, t, *idir, *odir;
125 t = (high + low) / 2.0;
127 if (
inside(inside_context, pt)) {
129 for (i = 0; i < 4; i++)
135 }
while (fabs(opt.
x - pt.
x) > .5 || fabs(opt.
y - pt.
y) > .5);
137 for (i = 0; i < 4; i++)
140 for (i = 0; i < 4; i++)
153 double save_real_size;
156 save_real_size =
ND_rw(n);
157 for (i = 0; i < 4; i++) {
164 for (i = 0; i < 4; i++) {
168 ND_rw(n) = save_real_size;
183 double save_real_size;
191 save_real_size =
ND_rw(n);
194 left_inside =
ND_shape(n)->fns->insidefn(&inside_context, c);
195 ND_rw(n) = save_real_size;
196 shape_clip0(&inside_context, n, curve, left_inside);
223 int clipTail, clipHead;
255 inside_t inside_context = {.
s = {.
n = tn, .bp = tbox}};
256 for (start = 0; start < pn - 4; start += 3) {
259 if (!
ND_shape(tn)->fns->insidefn(&inside_context, p2))
262 shape_clip0(&inside_context, tn, &ps[start],
true);
266 inside_t inside_context = {.
s = {.
n = hn, .bp = hbox}};
267 for (end = pn - 4; end > 0; end -= 3) {
270 if (!
ND_shape(hn)->fns->insidefn(&inside_context, p2))
276 for (; start < pn - 4; start += 3)
279 for (; end > 0; end -= 3)
283 for (
size_t i = start, j = 0; i < end + 4;) {
284 const pointf *
const cp = &ps[i];
285 newspl->
list[j++] = ps[i++];
288 newspl->
list[j++] = ps[i++];
289 newspl->
list[j++] = ps[i++];
292 newspl->
size = end - start + 4;
296 double s_in, s_out, m_in, m_out;
301 for (cnt_in = 0; (e =
ND_in(n).list[cnt_in]); cnt_in++)
303 for (cnt_out = 0; (e =
ND_out(n).list[cnt_out]); cnt_out++)
305 const double x1 =
ND_coord(n).x - s_in / cnt_in;
307 m_in = atan2(y1, x1);
308 const double x2 = s_out / cnt_out -
ND_coord(n).x;
310 m_out = atan2(y2, x2);
311 return (m_in + m_out) / 2.0;
350#define HT2(n) (ND_ht(n) / 2)
413 }
else if (side &
BOTTOM) {
419 }
else if (side &
LEFT) {
453 }
else if (side &
BOTTOM) {
472 }
else if (side &
LEFT) {
580 }
else if (side &
BOTTOM) {
609 }
else if (side &
LEFT) {
645 }
else if (side &
BOTTOM) {
664 }
else if (side &
LEFT) {
736 int vertices[] = {12, 4, 6, 2, 3,
738 int i, tail_i, head_i;
741 {11, 12, 13, 14, 15, 16, 17, 18}, {21, 22, 23, 24, 25, 26, 27, 28},
742 {31, 32, 33, 34, 35, 36, 37, 38}, {41, 42, 43, 44, 45, 46, 47, 48},
743 {51, 52, 53, 54, 55, 56, 57, 58}, {61, 62, 63, 64, 65, 66, 67, 68},
744 {71, 72, 73, 74, 75, 76, 77, 78}, {81, 82, 83, 84, 85, 86, 87, 88}};
746 tail_i = head_i = -1;
747 for (i = 0; i < 8; i++) {
748 if (head_side == vertices[i]) {
753 for (i = 0; i < 8; i++) {
754 if (tail_side == vertices[i]) {
760 if (tail_i < 0 || head_i < 0)
763 return pair_a[tail_i][head_i];
772 double hy, ty, stepx,
dx,
dy, height;
777 stepx = fmax(sizex / 2.0 / (
double)
cnt, 2.0);
795 switch (point_pair) {
802 ty = fmin(
dy, 3 * (tp.
y +
dy - np.
y));
803 hy = fmin(
dy, 3 * (hp.
y +
dy - np.
y));
804 for (
size_t i = 0; i <
cnt; i++) {
811 {tp.
x +
dx, tp.
y - ty / 3},
813 {(tp.
x + hp.
x) / 2, np.
y -
dy},
815 {hp.
x -
dx, hp.
y - hy / 3},
827 dy += height - stepy;
829 const size_t pointn =
sizeof(
points) /
sizeof(
points[0]);
832 if (debugleveln(e, 1))
833 showPoints(
points, pointn);
841 double hy, ty, stepx,
dx,
dy, height;
849 stepx = fmax(sizex / 2.0 / (
double)
cnt, 2.0);
866 switch (point_pair) {
908 ty = fmin(
dy, 3 * (np.
y +
dy - tp.
y));
909 hy = fmin(
dy, 3 * (np.
y +
dy - hp.
y));
910 for (
size_t i = 0; i <
cnt; i++) {
918 {tp.
x +
dx, tp.
y + ty / 3},
920 {(tp.
x + hp.
x) / 2, np.
y +
dy},
922 {hp.
x -
dx, hp.
y + hy / 3},
935 dy += height - stepy;
937 const size_t pointn =
sizeof(
points) /
sizeof(
points[0]);
940 if (debugleveln(e, 1))
941 showPoints(
points, pointn);
949 double hx, tx, stepy,
dx,
dy, width;
957 stepy = fmax(sizey / 2.0 / (
double)
cnt, 2.0);
974 switch (point_pair) {
983 tx = fmin(
dx, 3 * (np.
x +
dx - tp.
x));
984 hx = fmin(
dx, 3 * (np.
x +
dx - hp.
x));
985 for (
size_t i = 0; i <
cnt; i++) {
993 {tp.
x + tx / 3, tp.
y +
dy},
995 {np.
x +
dx, (tp.
y + hp.
y) / 2},
997 {hp.
x + hx / 3, hp.
y -
dy},
1010 dx += width - stepx;
1012 const size_t pointn =
sizeof(
points) /
sizeof(
points[0]);
1015 if (debugleveln(e, 1))
1016 showPoints(
points, pointn);
1023 int sgn, point_pair;
1024 double hx, tx, stepy,
dx,
dy, width;
1032 stepy = fmax(sizey / 2.0 / (
double)
cnt, 2.0);
1050 switch (point_pair) {
1059 tx = fmin(
dx, 3 * (tp.
x +
dx - np.
x));
1060 hx = fmin(
dx, 3 * (hp.
x +
dx - np.
x));
1061 for (
size_t i = 0; i <
cnt; i++) {
1069 {tp.
x - tx / 3, tp.
y +
dy},
1071 {np.
x -
dx, (tp.
y + hp.
y) / 2},
1073 {hp.
x - hx / 3, hp.
y -
dy},
1086 dx += width - stepx;
1089 const size_t pointn =
sizeof(
points) /
sizeof(
points[0]);
1092 if (debugleveln(e, 1))
1093 showPoints(
points, pointn);
1211 for (
size_t i = 0; i < spl->
size; i++) {
1213 for (
size_t j = 0, k = 3; k < bz.
size; j += 3, k += 3) {
1220 for (
size_t i = 0; i < spl->
size; i++) {
1222 for (
size_t j = 0, k = 3; k < bz.
size; j += 3, k += 3) {
1305 const double angle =
1306 atan2(
pf.y - pe.
y,
pf.x - pe.
x) +
1324 agerrorf(
"getsplinepoints: no spline points available for edge (%s,%s)\n",
Dynamically expanding string buffers.
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static char * agxbdisown(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
static char * gv_strdup(const char *original)
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
size_t arrowStartClip(edge_t *e, pointf *ps, size_t startp, size_t endp, bezier *spl, uint32_t sflag)
size_t arrowEndClip(edge_t *e, pointf *ps, size_t startp, size_t endp, bezier *spl, uint32_t eflag)
void arrowOrthoClip(edge_t *e, pointf *ps, size_t startp, size_t endp, bezier *spl, uint32_t sflag, uint32_t eflag)
static bool inside(inside_t *inside_context, pointf p)
void arrow_flags(Agedge_t *e, uint32_t *sflag, uint32_t *eflag)
pointf Bezier(const pointf *V, double t, pointf *Left, pointf *Right)
double late_double(void *obj, attrsym_t *attr, double defaultValue, double minimum)
pointf dotneato_closest(splines *spl, pointf pt)
void updateBB(graph_t *g, textlabel_t *lp)
#define PORT_LABEL_DISTANCE
void update_bb_bz(boxf *bb, const pointf *cp)
static double dist(int dim, double *x, double *y)
#define APPROXEQPT(p, q, tol)
geometric functions (e.g. on points and boxes)
static WUR pointf mid_pointf(pointf p, pointf q)
static WUR pointf add_pointf(pointf p, pointf q)
Agsym_t * E_labeldistance
static int cnt(Dict_t *d, Dtlink_t **set)
char * agxget(void *obj, Agsym_t *sym)
void agerrorf(const char *fmt,...)
Agraph_t * agraphof(void *obj)
char * agnameof(void *)
returns a string descriptor for the object.
Arithmetic helper functions.
#define LIST_APPEND(list,...)
static int sgn(int x)
sgn, as defined in Graphics Gems I, §11.8, pp. 99
static void merge(edge_t *e, int minlen, int weight)
port resolvePort(node_t *n, node_t *other, port *oldport)
bezier * new_spline(edge_t *e, size_t sz)
create and attach a new Bézier of size sz to the edge d
void endpath(path *P, edge_t *e, int et, pathend_t *endp, bool merge)
void makePortLabels(edge_t *e)
add head and tail labels if necessary and update bounding box
splines * getsplinepoints(edge_t *e)
static double conc_slope(node_t *n)
void clip_and_install(edge_t *fe, node_t *hn, pointf *ps, size_t pn, splineInfo *info)
static void selfLeft(edge_t *edges[], size_t cnt, double stepx, double sizey, splineInfo *sinfo)
double selfRightSpace(edge_t *e)
static void arrow_clip(edge_t *fe, node_t *hn, pointf *ps, size_t *startp, size_t *endp, bezier *spl, splineInfo *info)
static void selfRight(edge_t *edges[], size_t cnt, double stepx, double sizey, splineInfo *sinfo)
void shape_clip(node_t *n, pointf curve[4])
static int convert_sides_to_points(int tail_side, int head_side)
static void shape_clip0(inside_t *inside_context, node_t *n, pointf curve[4], bool left_inside)
static void selfBottom(edge_t *edges[], size_t cnt, double sizex, double stepy, splineInfo *sinfo)
void addEdgeLabels(edge_t *e)
static void selfTop(edge_t *edges[], size_t cnt, double sizex, double stepy, splineInfo *sinfo)
pointf edgeMidpoint(graph_t *g, edge_t *e)
void beginpath(path *P, edge_t *e, int et, pathend_t *endp, bool merge)
void makeSelfEdge(edge_t *edges[], size_t cnt, double sizex, double sizey, splineInfo *sinfo)
static pointf polylineMidpoint(splines *spl, pointf *pp, pointf *pq)
void add_box(path *P, boxf b)
static void endPoints(splines *spl, pointf *p, pointf *q)
extract the actual end points of the spline, where they touch the node
void bezier_clip(inside_t *inside_context, bool(*inside)(inside_t *inside_context, pointf p), pointf *sp, bool left_inside)
int place_portlabel(edge_t *e, bool head_p)
static bool streq(const char *a, const char *b)
are a and b equal?
size_t nbox
number of subdivisions
int(* pf)(void *, char *,...)