62static int cmpItem(
void *item1,
void *item2) {
63 const int *p1 = item1;
64 const int *p2 = item2;
65 if (p1[0] < p2[0])
return -1;
66 if (p1[0] > p2[0])
return 1;
67 if (p1[1] < p2[1])
return -1;
68 if (p1[1] > p2[1])
return 1;
79 newp->
a[0] = objp->
a[0];
80 newp->
a[1] = objp->
a[1];
88 .size = 2 *
sizeof(int),
89 .link = offsetof(
item, link),
120 for (i = 0; i < sf->
nfaces; i++) {
158 const int *p1 = pair1;
159 const int *p2 =
pair2;
183 .link = offsetof(
Ipair, link),
209 for (; tp; tp = tp->
nxttri) {
233 theta = atan2(np.
y - cp.
y, np.
x - cp.
x);
234 phi = atan2(pp.
y - cp.
y, pp.
x - cp.
x);
235 return (theta + phi) / 2.0;
243 int wa =
wind(v, w, a);
244 int wb =
wind(v, w, b);
248 return wind(v, b, w) *
wind(v, b, a) >= 0;
250 return wind(v, a, w) *
wind(v, a, b) >= 0;
295 for (
size_t i = 1; i < polys->
pn; i++) {
297 if (w.
x == v.
x && w.
y == v.
y) {
298 assert(i <= INT_MAX);
322 double d, sep, theta, sinTheta, cosTheta;
330 sinTheta = sin(theta);
331 cosTheta = cos(theta);
332 w.
x = v.
x + 100 * cosTheta;
333 w.
y = v.
y + 100 * sinTheta;
338 w.
x = v.
x + 100 * cosTheta;
339 w.
y = v.
y + 100 * sinTheta;
341 }
else if (
wind(
prev, v, w) != -1) {
344 w.
x = v.
x + 100 * cosTheta;
345 w.
y = v.
y + 100 * sinTheta;
348 if (
triPoint(trip, idx, v, w, &q)) {
358 for (i = 0; i < mult; i++) {
359 ps[i].x = v.
x + i * sep * cosTheta;
360 ps[i].y = v.
y + i * sep * sinTheta;
363 for (i = 0; i < mult; i++) {
364 ps[mult - i - 1].x = v.
x + i * sep * cosTheta;
365 ps[mult - i - 1].y = v.
y + i * sep * sinTheta;
414 p.
x = (a.
x + b.
x + c.
x) / 3.0;
415 p.
y = (a.
y + b.
y + c.
y) / 3.0;
433 bb.
LL.
x = bb.
LL.
y = DBL_MAX;
434 bb.
UR.
x = bb.
UR.
y = -DBL_MAX;
436 for (i = 0; i < npoly; i++) {
438 for (
size_t j = 0; j < obs->
pn; j++) {
476 if (p2 != *(q + 1) && p2 != *(q + 2)) {
479 }
else if (p1 == *(q + 1)) {
480 if (p2 != *q && p2 != *(q + 2)) {
483 }
else if (p1 == *(q + 2)) {
484 if (p2 != *q && p2 != *(q + 1)) {
507 sizeof(g->
edges[0]));
518 sizeof(tp->
edges[0]));
521 sizeof(hp->
edges[0]));
529 for (
size_t i = 0; i < tg->
nnodes; ++i) {
547 for (i = 0; i < 3 * sf->
nfaces; i++)
548 if (sf->
neigh[i] != -1)
557 for (i = 0; i < sf->
nfaces; i++) {
562 for (i = 0; i < sf->
nfaces; i++) {
564 jp = sf->
neigh + 3 * i;
566 while (ne < 3 && (j = *jp++) != -1) {
598 int *obsi =
gv_calloc(npoly + 1,
sizeof(
int));
599 int i, ix = 4, six = 0;
601 bb =
bbox(obsp, npoly, &npts);
604 int *segs =
gv_calloc(2 * npts,
sizeof(
int));
613 for (i = 1; i <= 4; i++) {
622 for (i = 0; i < npoly; i++) {
625 for (
size_t j = 1; j <= obs->
pn; j++) {
628 segs[six++] = ix + 1;
630 segs[six++] = obsi[i];
631 pts[ix++] = obs->
ps[j - 1];
637 double *x =
gv_calloc(npts,
sizeof(
double));
638 double *y =
gv_calloc(npts,
sizeof(
double));
639 for (i = 0; i < npts; i++) {
666 for (
size_t j = 0; j < spl.
pn / 2; j++) {
668 spl.
ps[spl.
pn - 1 - j] = spl.
ps[j];
679#define EQPT(p,q) (((p).x==(q).x)&&((p).y==(q).y))
703 prv =
poly.ps[
s - 1];
706 m.
x = (nxt.
x + prv.
x)/2.0 - p.
x;
707 m.
y = (nxt.
y + prv.
y)/2.0 - p.
y;
708 const double d = hypot(m.
x, m.
y);
752 evs[0].
x = evs[0].
y = 0;
753 evs[1].
x = evs[1].
y = 0;
758 for (
size_t j = 0; j <
poly.pn; j++) {
759 medges[j].
a =
poly.ps[j];
760 medges[j].
b =
poly.ps[(j + 1) %
poly.pn];
775 const size_t pn = 2 * (pl.
pn - 1);
778 for (
size_t i = 0; i + 2 < pl.
pn; i++) {
791 for (
int i = 0; i < mult; i++) {
793 for (
size_t j = 1; j + 1 < pl.
pn; j++) {
794 poly.ps[j] = cpts[j - 1][i];
796 poly.ps[pl.
pn - 1] = eps[1];
797 for (
size_t j = 1; j + 1 < pl.
pn; j++) {
798 poly.ps[pn - j] = cpts[j - 1][i + 1];
811 for (
size_t j = 0; j <
poly.pn; j++) {
812 medges[j].
a =
poly.ps[j];
813 medges[j].
b =
poly.ps[(j + 1) %
poly.pn];
816 const bool failed_routing =
Proutespline(medges,
poly.pn, mmpl, evs, &spl) < 0;
818 if (failed_routing) {
819 agwarningf(
"Could not create control points for multiple spline for edge (%s,%s)\n",
832 for (
size_t i = 0; i + 2 < pl.
pn; i++)
840#define NSMALL -0.0000000001
870 int starti = rtr->
obs[obs_id];
871 int endi = rtr->
obs[obs_id + 1];
926 for (i = starti; i < endi; i++) {
934 if (sides && !
inCone (v0, p, v1, pts[seg.
i]) && !
inCone (v0, p, v1, pts[seg.
j]) && !
raySeg(p,vr,pts[seg.
i],pts[seg.
j]))
938 assert(rtr->
tg->
nodes[v_id].
ne > 0 &&
"no edges were added");
955 for (
size_t k = 0; k < np->
ne; k++) {
957 if (ep->
t == j || ep->
h == j)
972 for (
size_t i = 0; i < trip->
poly.
pn; i++) {
973 for (tp = trip->
triMap[i]; tp; tp = nxt) {
1015 for (nxt = dad[t]; nxt !=
s; nxt = dad[nxt]) {
1017 assert (nxt != dad[nxt] &&
"infinite loop due to 'nxt' not changing");
1026 side1[cnt1++].
v = p.
i;
1028 side2[cnt2++].
v = p.
j;
1031 for (nxt = dad[t]; nxt >= 0; nxt = dad[nxt]) {
1033 if (p.
i == side1[cnt1 - 1].
v) {
1034 side1[cnt1 - 1].
ts =
1035 addTri(side2[cnt2 - 1].v, p.
j, side1[cnt1 - 1].
ts);
1036 side2[cnt2 - 1].
ts =
1037 addTri(side1[cnt1 - 1].v, p.
j, side2[cnt2 - 1].
ts);
1039 addTri(side2[cnt2 - 1].v, side1[cnt1 - 1].v,
NULL);
1040 side2[cnt2++].
v = p.
j;
1041 }
else if (p.
i == side2[cnt2 - 1].
v) {
1042 side1[cnt1 - 1].
ts =
1043 addTri(side2[cnt2 - 1].v, p.
j, side1[cnt1 - 1].
ts);
1044 side2[cnt2 - 1].
ts =
1045 addTri(side1[cnt1 - 1].v, p.
j, side2[cnt2 - 1].
ts);
1047 addTri(side2[cnt2 - 1].v, side1[cnt1 - 1].v,
NULL);
1048 side1[cnt1++].
v = p.
j;
1049 }
else if (p.
j == side1[cnt1 - 1].
v) {
1050 side1[cnt1 - 1].
ts =
1051 addTri(side2[cnt2 - 1].v, p.
i, side1[cnt1 - 1].
ts);
1052 side2[cnt2 - 1].
ts =
1053 addTri(side1[cnt1 - 1].v, p.
i, side2[cnt2 - 1].
ts);
1055 addTri(side2[cnt2 - 1].v, side1[cnt1 - 1].v,
NULL);
1056 side2[cnt2++].
v = p.
i;
1058 side1[cnt1 - 1].
ts =
1059 addTri(side2[cnt2 - 1].v, p.
i, side1[cnt1 - 1].
ts);
1060 side2[cnt2 - 1].
ts =
1061 addTri(side1[cnt1 - 1].v, p.
i, side2[cnt2 - 1].
ts);
1063 addTri(side2[cnt2 - 1].v, side1[cnt1 - 1].v,
NULL);
1064 side1[cnt1++].
v = p.
i;
1068 side1[cnt1 - 1].
ts =
addTri(-2, side2[cnt2 - 1].v, side1[cnt1 - 1].ts);
1069 side2[cnt2 - 1].
ts =
addTri(-2, side1[cnt1 - 1].v, side2[cnt2 - 1].ts);
1081 for (
int i = 0; i < cnt1; i++) {
1082 vmapAdd(vmap, side1[i].v, idx);
1083 *pps++ = rtr->
ps[side1[i].
v];
1084 trim[idx++] = side1[i].
ts;
1088 for (
int i = cnt2 - 1; i >= 0; i--) {
1089 vmapAdd(vmap, side2[i].v, idx);
1090 *pps++ = rtr->
ps[side2[i].
v];
1091 trim[idx++] = side2[i].
ts;
1094 for (
size_t i = 0; i < nt + 4; i++) {
1099 ps->poly.pn = nt + 4;
1114 size_t *original_edge_count) {
1118 for (i = 0; i < ncnt; i++) {
1119 np->
ne = original_edge_count[i];
1125#define PQVTYPE float
1137#define N_VAL(pq,n) ((PPQ*)pq)->vals[n]
1138#define N_IDX(pq,n) ((PPQ*)pq)->idxs[n]
1144#define N_DAD(n) dad[n]
1145#define E_WT(e) (e->dist)
1146#define UNSEEN (-FLT_MAX)
1163 for (i = 0; i <
pq->PQsize; i++)
1177 for (
size_t j = 0; j < np->
ne; j++) {
1192 }
else if (
N_VAL(
pq, adjn) < d) {
1217 int h_id = rtr->
tn + 1;
1225 sizeof(original_edge_count[0]));
1226 for (
size_t i = 0; i < rtr->
tg->
nnodes; ++i)
1227 original_edge_count[i] = rtr->
tg->
nodes[i].
ne;
1250 poly =
mkPoly(rtr, sp, h_id, t_id, h_p, t_p, &idx);
1260 free(original_edge_count);
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 void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
CDT_API int dtclose(Dt_t *)
CDT_API Dtmethod_t * Dtoset
ordered set (self-adjusting tree)
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
surface_t * mkSurface(double *x, double *y, int n, int *segs, int nsegs)
void freeSurface(surface_t *s)
void PQupdate(snode *n, int d)
int line_intersect(pointf a, pointf b, pointf c, pointf d, pointf *p)
static pointf add_pointf(pointf p, pointf q)
static int cnt(Dict_t *d, Dtlink_t **set)
void agwarningf(const char *fmt,...)
Agraph_t * agraphof(void *obj)
char * agnameof(void *)
returns a string descriptor for the object.
void PQinsert(pq_t *pq, Halfedge *he, Site *v, double offset)
static tripoly_t * mkPoly(router_t *rtr, int *dad, int s, int t, pointf p_s, pointf p_t, int *sx)
static int findMap(Dt_t *map, int a, int b)
static void addMap(Dt_t *map, int a, int b, int t)
static tgraph * mkTriGraph(surface_t *sf, pointf *pts)
static void mapTri(Dt_t *map, tri *tp)
router_t * mkRouter(Ppoly_t **obsp, int npoly)
static ipair sharedEdge(int *p, int *q)
static int raySegIntersect(pointf v, pointf w, pointf a, pointf b, pointf *p)
static int * mkTriIndices(surface_t *sf)
static bool swap_ends_p(edge_t *e)
static bool spline_merge(node_t *n)
void freeRouter(router_t *rtr)
static void addTriEdge(tgraph *g, int t, int h, ipair seg)
static int vMap(Dt_t *map, int i)
static void finishEdge(edge_t *e, Ppoly_t spl, int flip)
static int inCone(pointf a, pointf b, pointf c, pointf q)
static void * newIpair(void *p, Dtdisc_t *disc)
static int cmpItem(void *item1, void *item2)
static void resetGraph(tgraph *g, int ncnt, int ecnt, size_t *original_edge_count)
int makeMultiSpline(edge_t *e, router_t *rtr, int doPolyline)
static pointf * mkCtrlPts(int s, int mult, pointf prev, pointf v, pointf nxt, tripoly_t *trip)
static ipair edgeToSeg(tgraph *tg, int i, int j)
static void * newItem(void *p, Dtdisc_t *disc)
static tri * addTri(int i, int j, tri *oldp)
static void tweakPath(Ppoly_t poly, size_t t, Ppolyline_t pl)
static int genroute(tripoly_t *trip, int t, edge_t *e, int doPolyline)
static pointf triCenter(pointf *pts, int *idxs)
static Ppoint_t tweakEnd(Ppoly_t poly, size_t s, Ppoint_t q)
static int * triPath(tgraph *g, int n, int v0, int v1, PQ *pq)
static int cmpIpair(void *pair1, void *pair2)
static int raySeg(pointf v, pointf w, pointf a, pointf b)
static Dt_t * mapSegToTri(surface_t *sf)
static Dtdisc_t ipairdisc
static void freeTriGraph(tgraph *tg)
static int triPoint(tripoly_t *trip, int vx, pointf v, pointf w, pointf *ip)
static int ctrlPtIdx(pointf v, Ppoly_t *polys)
static boxf bbox(Ppoly_t **obsp, int npoly, int *np)
static void vmapAdd(Dt_t *map, int i, int j)
static void addEndpoint(router_t *rtr, pointf p, node_t *v, int v_id, int sides)
static double bisect(pointf pp, pointf cp, pointf np)
static void freeTripoly(tripoly_t *trip)
void make_polyline(Ppolyline_t line, Ppolyline_t *sline)
int Proutespline(Pedge_t *barriers, size_t n_barriers, Ppolyline_t input_route, Pvector_t endpoint_slopes[2], Ppolyline_t *output_route)
int Pshortestpath(Ppoly_t *boundary, Ppoint_t endpoints[2], Ppolyline_t *output_route)
PATHUTIL_API int wind(Ppoint_t a, Ppoint_t b, Ppoint_t c)
PATHUTIL_API COORD area2(Ppoint_t, Ppoint_t, Ppoint_t)
void clip_and_install(edge_t *fe, node_t *hn, pointf *ps, size_t pn, splineInfo *info)
void makeStraightEdge(graph_t *g, edge_t *e, int edgetype, splineInfo *info)
void addEdgeLabels(edge_t *e)
bool(* swapEnds)(edge_t *e)