| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- export default function(topology, arcs) {
- var stitchedArcs = {},
- fragmentByStart = {},
- fragmentByEnd = {},
- fragments = [],
- emptyIndex = -1;
- // Stitch empty arcs first, since they may be subsumed by other arcs.
- arcs.forEach(function(i, j) {
- var arc = topology.arcs[i < 0 ? ~i : i], t;
- if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {
- t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;
- }
- });
- arcs.forEach(function(i) {
- var e = ends(i),
- start = e[0],
- end = e[1],
- f, g;
- if (f = fragmentByEnd[start]) {
- delete fragmentByEnd[f.end];
- f.push(i);
- f.end = end;
- if (g = fragmentByStart[end]) {
- delete fragmentByStart[g.start];
- var fg = g === f ? f : f.concat(g);
- fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;
- } else {
- fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
- }
- } else if (f = fragmentByStart[end]) {
- delete fragmentByStart[f.start];
- f.unshift(i);
- f.start = start;
- if (g = fragmentByEnd[start]) {
- delete fragmentByEnd[g.end];
- var gf = g === f ? f : g.concat(f);
- fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;
- } else {
- fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
- }
- } else {
- f = [i];
- fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;
- }
- });
- function ends(i) {
- var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;
- if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });
- else p1 = arc[arc.length - 1];
- return i < 0 ? [p1, p0] : [p0, p1];
- }
- function flush(fragmentByEnd, fragmentByStart) {
- for (var k in fragmentByEnd) {
- var f = fragmentByEnd[k];
- delete fragmentByStart[f.start];
- delete f.start;
- delete f.end;
- f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });
- fragments.push(f);
- }
- }
- flush(fragmentByEnd, fragmentByStart);
- flush(fragmentByStart, fragmentByEnd);
- arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });
- return fragments;
- }
|