/// In-place split an existing line segment into two parts. public Pair <IIndexedSeg, IIndexedSeg> Split(IIndexedSeg tosplit, IHasLine a, IHasLine b) { LSeg l = tosplit as LSeg; Pair <LSeg, LSeg> r = l.DoSplit(a, b); m_allsegs[r.First.Keyval] = r.First; m_allsegs[r.Second.Keyval] = r.Second; m_allsegs.Remove(l.Keyval); return(new Pair <IIndexedSeg, IIndexedSeg>(r.First, r.Second)); }
public Pair <IIndexedSeg, IIndexedSeg> Split(IIndexedSeg tosplit, IHasLine a, IHasLine b) { Handle na = new Handle(m_segments.AddFirst(a)); Handle nb = new Handle(m_segments.AddFirst(b)); Handle h = tosplit as Handle; m_segments.Remove(h.Node); return(new Pair <IIndexedSeg, IIndexedSeg>(na, nb)); }
private bool insertFrag(T src, LineSeg l, IIndexedSeg cand, Stack <IIndexedSeg> cand_remainders, Stack <LineSeg> l_remainders) { Fragment frag = cand.Val as Fragment; LineSeg a, b, o; bool l_before, l_after; LineSeg.Overlay(l, frag.LineSeg, m_atol, m_dtolsq, out b, out l_before, // leftover before out o, out a, out l_after); // leftover after if (o != null) // There was an overlay... // For partial overlays, manage any leftovers that are // already in the index. { if (b != null && !l_before) { Fragment nfraga, nfragb; frag.Split(out nfraga, b, out nfragb, o); Pair <IIndexedSeg, IIndexedSeg> sp = m_index.Split(cand, nfraga, nfragb); // relable 'c' and 'frag' to point at the overlaping part. cand_remainders.Push(sp.First); cand = sp.Second; frag = nfragb; } if (a != null && !l_after) { Fragment nfraga, nfragb; frag.Split(out nfraga, o, out nfragb, a); Pair <IIndexedSeg, IIndexedSeg> sp = m_index.Split(cand, nfraga, nfragb); // relable 'c' and 'frag' to point at the overlaping part. cand_remainders.Push(sp.Second); cand = sp.First; frag = nfraga; } // Attribute the overlapping portion w/ the source line. frag.Sources = frag.Sources.Cons(src); // And manage any leftovers that are -not- part of the index. if (b != null && l_before) { l_remainders.Push(b); } if (a != null && l_after) { l_remainders.Push(a); } return(true); } else { // No overlap so leftovers are complete. cand_remainders.Push(cand); return(false); } }
/// Insert the given line. /// /// TODO: FUTURE: Make the results of this independent of /// insertion order... (tricky due to tolerance /// issues; what if lines a and b are within the /// tol-distance; ditto b and c, but a and c are /// not -- order will matter!) public void Insert(T line) { // Console.Error.WriteLine("Insert...." + line); Stack <LineSeg> working_set = new Stack <LineSeg>(); working_set.Push(line.LineSeg); // Find all candidates... Stack <IIndexedSeg> candidates = new Stack <IIndexedSeg>(); foreach (IIndexedSeg cand in m_index.SearchByLineSeg(line.LineSeg, m_dtol)) { candidates.Push(cand); } // Match the candidates vs. the given line segment. Stack <LineSeg> unmatched = new Stack <LineSeg>(); while (working_set.Count > 0) { LineSeg l = working_set.Pop(); //Console.Error.WriteLine("Part :" + l); Stack <IIndexedSeg> ncands = new Stack <IIndexedSeg>(); // Console.Error.WriteLine("cands::" + candidates.Count); // foreach (IIndexedSeg c in candidates) // Console.Error.WriteLine(" " + c.Val); bool intersected = false; while (!intersected && candidates.Count > 0) { IIndexedSeg cand = candidates.Pop(); intersected = insertFrag(line, l, cand, ncands, working_set); if (!intersected) { ncands.Push(cand); } } // Console.Error.WriteLine("intr? " + intersected + ", working_set:" + working_set.Count); if (!intersected) { unmatched.Push(l); } while (candidates.Count > 0) { ncands.Push(candidates.Pop()); } candidates = ncands; } // Any unmatched pieces of the line: foreach (LineSeg l in unmatched) { Fragment fresh = new Fragment(); fresh.Prev = null; fresh.Next = null; fresh.Sources = SList <T> .Nil.Cons(line); fresh.LineSeg = l; m_index.Insert(fresh); } }