20 static boolean spline_merge(
node_t * n)
25 static boolean swap_ends_p(
edge_t * e)
30 static splineInfo sinfo = { swap_ends_p, spline_merge };
57 static int cmpItem(
Dt_t * d,
int p1[],
int p2[],
Dtdisc_t * disc)
64 else if (p1[0] > p2[0])
66 else if (p1[1] < p2[1])
68 else if (p1[1] > p2[1])
81 newp->
a[0] = objp->
a[0];
82 newp->
a[1] = objp->
a[1];
105 static void addMap(
Dt_t * map,
int a,
int b,
int t)
130 for (i = 0; i < sf->
nfaces; i++) {
134 addMap(map, a, b, i);
135 addMap(map, b, c, i);
136 addMap(map, c, a, i);
141 static int findMap(
Dt_t * map,
int a,
int b)
167 static int cmpIpair(
Dt_t * d,
int *p1,
int *p2,
Dtdisc_t * disc)
194 offsetof(
Ipair, link),
203 static void vmapAdd(
Dt_t * map,
int i,
int j)
211 static int vMap(
Dt_t * map,
int i)
221 static void mapTri(
Dt_t * map,
tri * tp)
223 for (; tp; tp = tp->
nxttri) {
224 tp->
v.
i = vMap(map, tp->
v.
i);
225 tp->
v.
j = vMap(map, tp->
v.
j);
232 addTri(
int i,
int j,
tri * oldp)
247 theta = atan2(np.
y - cp.
y, np.
x - cp.
x);
248 phi = atan2(pp.
y - cp.
y, pp.
x - cp.
x);
249 return (theta + phi) / 2.0;
257 int wa =
wind(v, w, a);
258 int wb =
wind(v, w, b);
262 return (
wind(v, b, w) *
wind(v, b, a) >= 0);
264 return (
wind(v, a, w) *
wind(v, a, b) >= 0);
275 if (raySeg(v, w, a, b))
304 psComment (
"Failure in triPoint");
324 for (i = 1; i < polys->
pn; i++) {
326 if ((w.
x == v.
x) && (w.
y == v.
y))
348 int idx = ctrlPtIdx(v, &(trip->
poly));
350 double d, sep, theta, sinTheta, cosTheta;
357 theta = bisect(prev, v, nxt);
358 sinTheta = sin(theta);
359 cosTheta = cos(theta);
360 w.
x = v.
x + 100 * cosTheta;
361 w.
y = v.
y + 100 * sinTheta;
363 if (
wind(prev, v, w) != 1) {
366 w.
x = v.
x + 100 * cosTheta;
367 w.
y = v.
y + 100 * sinTheta;
369 }
else if (
wind(prev, v, w) != -1) {
372 w.
x = v.
x + 100 * cosTheta;
373 w.
y = v.
y + 100 * sinTheta;
376 if (triPoint(trip, idx, v, w, &q)) {
386 for (i = 0; i < mult; i++) {
387 ps[i].
x = v.
x + i * sep * cosTheta;
388 ps[i].
y = v.
y + i * sep * sinTheta;
391 for (i = 0; i < mult; i++) {
392 ps[mult - i - 1].
x = v.
x + i * sep * cosTheta;
393 ps[mult - i - 1].
y = v.
y + i * sep * sinTheta;
441 p.
x = (a.
x + b.
x + c.
x) / 3.0;
442 p.
y = (a.
y + b.
y + c.
y) / 3.0;
453 static boxf bbox(
Ppoly_t** obsp,
int npoly,
int *np)
463 for (i = 0; i < npoly; i++) {
465 for (j = 0; j < obs->
pn; j++) {
492 memcpy(tris, sf->
faces, 3 * sf->
nfaces *
sizeof(
int));
500 static int degT(
int *ip)
515 static ipair sharedEdge(
int *p,
int *q)
522 if ((p2 != *(q + 1)) && (p2 != *(q + 2))) {
525 }
else if (p1 == *(q + 1)) {
526 if ((p2 != *q) && (p2 != *(q + 2))) {
529 }
else if (p1 == *(q + 2)) {
530 if ((p2 != *q) && (p2 != *(q + 1))) {
551 static void addTriEdge(
tgraph * g,
int t,
int h,
double d,
ipair seg)
568 static void freeTriGraph(
tgraph * tg)
589 for (i = 0; i < 3 * sf->
nfaces; i++)
590 if (sf->
neigh[i] != -1)
605 for (i = 0; i < sf->
nfaces; i++) {
609 np->
ctr = triCenter(pts, sf->
faces + 3 * i);
610 edgei += degT(sf->
neigh + 3 * i) + 1;
618 np->
edges = edgei + maxv;
620 for (i = 0; i < sf->
nfaces; i++) {
622 jp = sf->
neigh + 3 * i;
624 while ((ne < 3) && ((j = *jp++) != -1)) {
628 sharedEdge(sf->
faces + 3 * i, sf->
faces + 3 * j);
629 addTriEdge(g, i, j, dist, seg);
644 freeTriGraph(rtr->
tg);
650 prTriPoly (
tripoly_t *poly,
int si,
int ei)
652 FILE* fp = fopen (
"dumppoly",
"w");
655 psPoly (&(poly->
poly));
656 psPoint (poly->
poly.
ps[si]);
657 psPoint (poly->
poly.
ps[ei]);
665 FILE* fp = fopen (
"dump",
"w");
672 for (i=0;i < rtr->
tn; i++) {
677 sprintf (buf,
"%d", i);
678 psTxt (buf, nodes[i].ctr);
680 for (i=rtr->
tn;i < n; i++) {
681 sprintf (buf,
"%d", i);
682 psTxt (buf, nodes[i].ctr);
685 for (i=0;i < rtr->
tg->
nedges; i++) {
687 psSeg (nodes[e->
t].
ctr, nodes[e->
h].
ctr);
708 int *obsi =
N_NEW(npoly + 1,
int);
709 int i, j, ix = 4, six = 0;
711 bb = bbox(obsp, npoly, &npts);
714 segs =
N_GNEW(2 * npts,
int);
723 for (i = 1; i <= 4; i++) {
732 for (i = 0; i < npoly; i++) {
735 for (j = 1; j <= obs->
pn; j++) {
738 segs[six++] = ix + 1;
740 segs[six++] = obsi[i];
741 pts[ix++] = obs->
ps[j - 1];
751 for (i = 0; i < npts; i++) {
763 rtr->
tris = mkTriIndices(sf);
764 rtr->
trimap = mapSegToTri(sf);
766 rtr->
tg = mkTriGraph(sf, maxv, pts);
784 for (j = 0; j < spl.
pn; j++) {
785 spline[spl.
pn - 1 - j] = spl.
ps[j];
791 for (j = 0; j < spl.
pn; j++) {
792 spline[j] = spl.
ps[j];
805 #define EQPT(p,q) (((p).x==(q).x)&&((p).y==(q).y))
827 nxt = poly.
ps[(s + 1) % poly.
pn];
829 prv = poly.
ps[poly.
pn-1];
831 prv = poly.
ps[s - 1];
835 m.
x = (nxt.
x + prv.
x)/2.0 - p.
x;
836 m.
y = (nxt.
y + prv.
y)/2.0 - p.
y;
847 pl.
ps[0] = tweakEnd (poly, s, pl, pl.
ps[1]);
848 pl.
ps[pl.
pn-1] = tweakEnd (poly, t, pl, pl.
ps[pl.
pn-2]);
888 evs[0].
x = evs[0].
y = 0;
889 evs[1].
x = evs[1].
y = 0;
893 for (j = 0; j < poly.
pn; j++) {
894 medges[j].
a = poly.
ps[j];
895 medges[j].
b = poly.
ps[(j + 1) % poly.
pn];
897 tweakPath (poly, s, t, pl);
903 finishEdge (g, e, spl,
aghead(e) != head, eps[0], eps[1]);
909 pn = 2 * (pl.
pn - 1);
912 for (i = 0; i < pl.
pn - 2; i++) {
914 mkCtrlPts(t, mult+1, pl.
ps[i], pl.
ps[i + 1], pl.
ps[i + 2], trip);
925 for (i = 0; i < mult; i++) {
927 for (j = 1; j < pl.
pn - 1; j++) {
928 poly.
ps[j] = cpts[j - 1][i];
930 poly.
ps[pl.
pn - 1] = eps[1];
931 for (j = 1; j < pl.
pn - 1; j++) {
932 poly.
ps[pn - j] = cpts[j - 1][i + 1];
944 for (j = 0; j < poly.
pn; j++) {
945 medges[j].
a = poly.
ps[j];
946 medges[j].
b = poly.
ps[(j + 1) % poly.
pn];
948 tweakPath (poly, 0, pl.
pn-1, mmpl);
950 agerr(
AGWARN,
"Could not create control points for multiple spline for edge (%s,%s)\n",
956 finishEdge (g, e, spl,
aghead(e) != head, eps[0], eps[1]);
963 for (i = 0; i < pl.
pn - 2; i++)
972 #define NSMALL -0.0000000001
983 static pointf north = {0, 1};
984 static pointf northeast = {1, 1};
985 static pointf east = {1, 0};
986 static pointf southeast = {1, -1};
987 static pointf south = {0, -1};
988 static pointf southwest = {-1, -1};
989 static pointf west = {-1, 0};
990 static pointf northwest = {-1, 1};
1002 int starti = rtr->
obs[obs_id];
1003 int endi = rtr->
obs[obs_id + 1];
1011 vr = add_pointf (p, north);
1012 v0 = add_pointf (p, northwest);
1013 v1 = add_pointf (p, northeast);
1016 vr = add_pointf (p, northeast);
1017 v0 = add_pointf (p, north);
1018 v1 = add_pointf (p, east);
1021 vr = add_pointf (p, east);
1022 v0 = add_pointf (p, northeast);
1023 v1 = add_pointf (p, southeast);
1026 vr = add_pointf (p, southeast);
1027 v0 = add_pointf (p, east);
1028 v1 = add_pointf (p, south);
1031 vr = add_pointf (p, south);
1032 v0 = add_pointf (p, southeast);
1033 v1 = add_pointf (p, southwest);
1036 vr = add_pointf (p, southwest);
1037 v0 = add_pointf (p, south);
1038 v1 = add_pointf (p, west);
1041 vr = add_pointf (p, west);
1042 v0 = add_pointf (p, southwest);
1043 v1 = add_pointf (p, northwest);
1046 vr = add_pointf (p, northwest);
1047 v0 = add_pointf (p, west);
1048 v1 = add_pointf (p, north);
1059 for (i = starti; i < endi; i++) {
1066 t = findMap(rtr->
trimap, seg.
i, seg.
j);
1067 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]))
1070 addTriEdge(rtr->
tg, v_id, t, d, seg);
1088 for (i = 0; i < np->
ne; i++) {
1090 if ((ep->
t == j) || (ep->
h == j))
1106 for (i = 0; i < trip->
poly.
pn; i++) {
1107 for (tp = trip->
triMap[i]; tp; tp = nxt) {
1153 for (nxt = dad[t]; nxt != s; nxt = dad[nxt])
1160 p = edgeToSeg(rtr->
tg, nxt, t);
1161 side1[cnt1].
ts = addTri(-1, p.
j,
NULL);
1162 side1[cnt1++].
v = p.
i;
1163 side2[cnt2].
ts = addTri(-1, p.
i,
NULL);
1164 side2[cnt2++].
v = p.
j;
1167 for (nxt = dad[t]; nxt >= 0; nxt = dad[nxt]) {
1168 p = edgeToSeg(rtr->
tg, t, nxt);
1169 if (p.
i == side1[cnt1 - 1].
v) {
1170 side1[cnt1 - 1].
ts =
1171 addTri(side2[cnt2 - 1].v, p.
j, side1[cnt1 - 1].
ts);
1172 side2[cnt2 - 1].
ts =
1173 addTri(side1[cnt1 - 1].v, p.
j, side2[cnt2 - 1].
ts);
1175 addTri(side2[cnt2 - 1].v, side1[cnt1 - 1].v,
NULL);
1176 side2[cnt2++].
v = p.
j;
1177 }
else if (p.
i == side2[cnt2 - 1].
v) {
1178 side1[cnt1 - 1].
ts =
1179 addTri(side2[cnt2 - 1].v, p.
j, side1[cnt1 - 1].
ts);
1180 side2[cnt2 - 1].
ts =
1181 addTri(side1[cnt1 - 1].v, p.
j, side2[cnt2 - 1].
ts);
1183 addTri(side2[cnt2 - 1].v, side1[cnt1 - 1].v,
NULL);
1184 side1[cnt1++].
v = p.
j;
1185 }
else if (p.
j == side1[cnt1 - 1].
v) {
1186 side1[cnt1 - 1].
ts =
1187 addTri(side2[cnt2 - 1].v, p.
i, side1[cnt1 - 1].
ts);
1188 side2[cnt2 - 1].
ts =
1189 addTri(side1[cnt1 - 1].v, p.
i, side2[cnt2 - 1].
ts);
1191 addTri(side2[cnt2 - 1].v, side1[cnt1 - 1].v,
NULL);
1192 side2[cnt2++].
v = p.
i;
1194 side1[cnt1 - 1].
ts =
1195 addTri(side2[cnt2 - 1].v, p.
i, side1[cnt1 - 1].
ts);
1196 side2[cnt2 - 1].
ts =
1197 addTri(side1[cnt1 - 1].v, p.
i, side2[cnt2 - 1].
ts);
1199 addTri(side2[cnt2 - 1].v, side1[cnt1 - 1].v,
NULL);
1200 side1[cnt1++].
v = p.
i;
1204 side1[cnt1 - 1].
ts = addTri(-2, side2[cnt2 - 1].v, side1[cnt1 - 1].ts);
1205 side2[cnt2 - 1].
ts = addTri(-2, side1[cnt1 - 1].v, side2[cnt2 - 1].ts);
1211 vmapAdd(vmap, -1, 0);
1212 vmapAdd(vmap, -2, cnt1 + 1);
1217 for (i = 0; i < cnt1; i++) {
1218 vmapAdd(vmap, side1[i].v, idx);
1219 *pps++ = rtr->
ps[side1[i].
v];
1220 trim[idx++] = side1[i].
ts;
1224 for (i = cnt2 - 1; i >= 0; i--) {
1225 vmapAdd(vmap, side2[i].v, idx);
1226 *pps++ = rtr->
ps[side2[i].
v];
1227 trim[idx++] = side2[i].
ts;
1230 for (i = 0; i < nt + 4; i++) {
1231 mapTri(vmap, trim[i]);
1249 static void resetGraph(
tgraph * g,
int ncnt,
int ecnt)
1254 for (i = 0; i < ncnt; i++) {
1255 if (np->
edges + np->
ne == (np + 1)->edges)
1262 #define PQVTYPE float
1274 #define N_VAL(pq,n) ((PPQ*)pq)->vals[n]
1275 #define N_IDX(pq,n) ((PPQ*)pq)->idxs[n]
1281 #define N_DAD(n) dad[n]
1282 #define E_WT(e) (e->dist)
1283 #define UNSEEN -MAXFLOAT
1292 triPath(
tgraph * g,
int n,
int v0,
int v1, PQ * pq)
1298 int *dad =
N_NEW(n,
int);
1300 for (i = 0; i < pq->PQsize; i++)
1309 while ((i = PQremove(pq)) != -1) {
1314 for (j = 0; j < np->
ne; j++) {
1320 if (
N_VAL(pq, adjn) < 0) {
1323 N_VAL(pq, adjn) = d;
1326 }
else if (
N_VAL(pq, adjn) < d) {
1327 PQupdate(pq, adjn, d);
1352 int h_id = rtr->
tn + 1;
1364 PQgen(&pq.
pq, rtr->
tn + 2, -1);
1372 sp = triPath(rtr->
tg, rtr->
tn+2, h_id, t_id, (PQ *) & pq);
1376 PQfree(&(pq.
pq), 0);
1380 poly = mkPoly(rtr, sp, h_id, t_id, h_p, t_p, &idx);
1384 ret = genroute(g, poly, 0, idx, e, doPolyline);
1389 resetGraph(rtr->
tg, rtr->
tn, ecnt);
int(* Dtcompar_f)(Dt_t *, void *, void *, Dtdisc_t *)
unsigned int(* Dthash_f)(Dt_t *, void *, Dtdisc_t *)
CDT_API int dtclose(Dt_t *)
void *(* Dtmake_f)(Dt_t *, void *, Dtdisc_t *)
CDT_API Dtmethod_t * Dtoset
int Proutespline(Pedge_t *barriers, int n_barriers, Ppolyline_t input_route, Pvector_t endpoint_slopes[2], Ppolyline_t *output_route)
COORD area2(Ppoint_t, Ppoint_t, Ppoint_t)
void make_polyline(Ppolyline_t line, Ppolyline_t *sline)
void clip_and_install(edge_t *fe, node_t *hn, pointf *ps, int pn, splineInfo *info)
int agerr(agerrlevel_t level, const char *fmt,...)
router_t * mkRouter(Ppoly_t **obsp, int npoly)
int makeMultiSpline(graph_t *g, edge_t *e, router_t *rtr, int doPolyline)
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
CGRAPH_API Agraph_t * agraphof(void *obj)
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
void addEdgeLabels(graph_t *g, edge_t *e, pointf rp, pointf rq)
void PQinsert(Halfedge *he, Site *v, double offset)
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
CGRAPH_API char * agnameof(void *)
void *(* Dtmemory_f)(Dt_t *, void *, size_t, Dtdisc_t *)
int wind(Ppoint_t a, Ppoint_t b, Ppoint_t c)
if(aagss+aagstacksize-1<=aagssp)
void freeSurface(surface_t *s)
EXTERN unsigned char Concentrate
int line_intersect(pointf a, pointf b, pointf c, pointf d, pointf *p)
EXTERN unsigned char Verbose
int Pshortestpath(Ppoly_t *boundary, Ppoint_t endpoints[2], Ppolyline_t *output_route)
surface_t * mkSurface(double *x, double *y, int n, int *segs, int nsegs)
void makeStraightEdge(graph_t *g, edge_t *e, int edgetype, splineInfo *info)
int(* Dtevent_f)(Dt_t *, int, void *, Dtdisc_t *)
void(* Dtfree_f)(Dt_t *, void *, Dtdisc_t *)
double dist(Site *s, Site *t)
void freeRouter(router_t *rtr)