public static void FinalizeSubCurves(ArrayList subcurves, ArrayList chains) { int numchains = chains.Count; if (numchains == 0) { return; } if ((numchains & 1) != 0) { throw new SystemException("Odd number of chains!"); } var tempArray = chains.ToArray(); ChainEnd[] endlist = new ChainEnd[tempArray.Length]; for (int i = 0; i < tempArray.Length; i++) { endlist[i] = tempArray[i] as ChainEnd; } for (int i = 1; i < numchains; i += 2) { ChainEnd open = endlist[i - 1]; ChainEnd close = endlist[i]; CurveLink subcurve = open.LinkTo(close); if (subcurve != null) { subcurves.Add(subcurve); } } chains.Clear(); }
public ChainEnd(CurveLink first, ChainEnd partner) { _head = first; _tail = first; _partner = partner; _etag = first.GetEdgeTag(); }
/* * Returns head of a complete chain to be added to subcurves * or null if the links did not complete such a chain. */ public CurveLink LinkTo(ChainEnd that) { if (_etag == AreaOp.ETAG_IGNORE || that._etag == AreaOp.ETAG_IGNORE) { throw new SystemException("ChainEnd linked more than once!"); } if (_etag == that._etag) { throw new SystemException("Linking chains of the same type!"); } ChainEnd enter, exit; // assert(partner.etag != that.partner.etag); if (_etag == AreaOp.ETAG_ENTER) { enter = this; exit = that; } else { enter = that; exit = this; } // Now make sure these ChainEnds are not linked to any others... _etag = AreaOp.ETAG_IGNORE; that._etag = AreaOp.ETAG_IGNORE; // Now link everything up... enter._tail.SetNext(exit._head); enter._tail = exit._tail; if (_partner == that) { // Curve has closed on itself... return(enter._head); } // Link this chain into one end of the chain formed by the partners ChainEnd otherenter = exit._partner; ChainEnd otherexit = enter._partner; otherenter._partner = otherexit; otherexit._partner = otherenter; if (enter._head.GetYTop() < otherenter._head.GetYTop()) { enter._tail.SetNext(otherenter._head); otherenter._head = enter._head; } else { otherexit._tail.SetNext(enter._head); otherexit._tail = enter._tail; } return(null); }
/* * Returns head of a complete chain to be added to subcurves * or null if the links did not complete such a chain. */ public CurveLink LinkTo(ChainEnd that) { if (_etag == AreaOp.ETAG_IGNORE || that._etag == AreaOp.ETAG_IGNORE) { throw new SystemException("ChainEnd linked more than once!"); } if (_etag == that._etag) { throw new SystemException("Linking chains of the same type!"); } ChainEnd enter, exit; // assert(partner.etag != that.partner.etag); if (_etag == AreaOp.ETAG_ENTER) { enter = this; exit = that; } else { enter = that; exit = this; } // Now make sure these ChainEnds are not linked to any others... _etag = AreaOp.ETAG_IGNORE; that._etag = AreaOp.ETAG_IGNORE; // Now link everything up... enter._tail.SetNext(exit._head); enter._tail = exit._tail; if (_partner == that) { // Curve has closed on itself... return enter._head; } // Link this chain into one end of the chain formed by the partners ChainEnd otherenter = exit._partner; ChainEnd otherexit = enter._partner; otherenter._partner = otherexit; otherexit._partner = otherenter; if (enter._head.GetYTop() < otherenter._head.GetYTop()) { enter._tail.SetNext(otherenter._head); otherenter._head = enter._head; } else { otherexit._tail.SetNext(enter._head); otherexit._tail = enter._tail; } return null; }
public void SetOtherEnd(ChainEnd partner) { _partner = partner; }
public static void ResolveLinks(ArrayList subcurves, ArrayList chains, ArrayList links) { int numlinks = links.Count; CurveLink[] linklist; if (numlinks == 0) { linklist = EmptyLinkList; } else { if ((numlinks & 1) != 0) { throw new SystemException("Odd number of new curves!"); } var tempArray = links.ToArray(); linklist = new CurveLink[numlinks + 2]; for (int i = 0; i < tempArray.Length; i++) { linklist[i] = tempArray[i] as CurveLink; } } int numchains = chains.Count; ChainEnd[] endlist; if (numchains == 0) { endlist = EmptyChainList; } else { if ((numchains & 1) != 0) { throw new SystemException("Odd number of chains!"); } var tempArray = chains.ToArray(); endlist = new ChainEnd[numchains + 2]; for (int i = 0; i < tempArray.Length; i++) { endlist[i] = tempArray[i] as ChainEnd; } } int curchain = 0; int curlink = 0; chains.Clear(); ChainEnd chain = endlist[0]; ChainEnd nextchain = endlist[1]; CurveLink link = linklist[0]; CurveLink nextlink = linklist[1]; while (chain != null || link != null) { /* * Strategy 1: * Connect chains or links if they are the only things left... */ bool connectchains = (link == null); bool connectlinks = (chain == null); if (!connectchains && !connectlinks) { // assert(link != null && chain != null); /* * Strategy 2: * Connect chains or links if they close off an open area... */ if (nextchain != null) { connectchains = ((curchain & 1) == 0 && chain.GetX() == nextchain.GetX()); } if (nextlink != null) { connectlinks = ((curlink & 1) == 0 && link.GetX() == nextlink.GetX()); if (!connectchains && !connectlinks) { /* * Strategy 3: * Connect chains or links if their successor is * between them and their potential connectee... */ double cx = chain.GetX(); double lx = link.GetX(); connectchains = (nextchain != null && cx < lx && Obstructs(nextchain.GetX(), lx, curchain)); connectlinks = (lx < cx && Obstructs(nextlink.GetX(), cx, curlink)); } } } if (connectchains) { CurveLink subcurve = chain.LinkTo(nextchain); if (subcurve != null) { subcurves.Add(subcurve); } curchain += 2; chain = endlist[curchain]; nextchain = endlist[curchain + 1]; } if (connectlinks) { ChainEnd openend = new ChainEnd(link, null); ChainEnd closeend = new ChainEnd(nextlink, openend); openend.SetOtherEnd(closeend); chains.Add(openend); chains.Add(closeend); curlink += 2; link = linklist[curlink]; nextlink = linklist[curlink + 1]; } if (!connectchains && !connectlinks) { // assert(link != null); // assert(chain != null); // assert(chain.getEtag() == link.getEtag()); chain.AddLink(link); chains.Add(chain); curchain++; chain = nextchain; nextchain = endlist[curchain + 1]; curlink++; link = nextlink; nextlink = linklist[curlink + 1]; } } }
public static void ResolveLinks(ArrayList subcurves, ArrayList chains, ArrayList links) { int numlinks = links.Count; CurveLink[] linklist; if (numlinks == 0) { linklist = EmptyLinkList; } else { if ((numlinks & 1) != 0) { throw new SystemException("Odd number of new curves!"); } var tempArray = links.ToArray(); linklist = new CurveLink[numlinks + 2]; for (int i = 0; i < tempArray.Length; i++) { linklist[i] = tempArray[i] as CurveLink; } } int numchains = chains.Count; ChainEnd[] endlist; if (numchains == 0) { endlist = EmptyChainList; } else { if ((numchains & 1) != 0) { throw new SystemException("Odd number of chains!"); } var tempArray = chains.ToArray(); endlist = new ChainEnd[numchains+2]; for (int i = 0; i < tempArray.Length; i++) { endlist[i] = tempArray[i] as ChainEnd; } } int curchain = 0; int curlink = 0; chains.Clear(); ChainEnd chain = endlist[0]; ChainEnd nextchain = endlist[1]; CurveLink link = linklist[0]; CurveLink nextlink = linklist[1]; while (chain != null || link != null) { /* * Strategy 1: * Connect chains or links if they are the only things left... */ bool connectchains = (link == null); bool connectlinks = (chain == null); if (!connectchains && !connectlinks) { // assert(link != null && chain != null); /* * Strategy 2: * Connect chains or links if they close off an open area... */ if (nextchain != null) connectchains = ((curchain & 1) == 0 && chain.GetX() == nextchain.GetX()); if (nextlink != null) { connectlinks = ((curlink & 1) == 0 && link.GetX() == nextlink.GetX()); if (!connectchains && !connectlinks) { /* * Strategy 3: * Connect chains or links if their successor is * between them and their potential connectee... */ double cx = chain.GetX(); double lx = link.GetX(); connectchains = (nextchain != null && cx < lx && Obstructs(nextchain.GetX(), lx, curchain)); connectlinks = (lx < cx && Obstructs(nextlink.GetX(), cx, curlink)); } } } if (connectchains) { CurveLink subcurve = chain.LinkTo(nextchain); if (subcurve != null) { subcurves.Add(subcurve); } curchain += 2; chain = endlist[curchain]; nextchain = endlist[curchain + 1]; } if (connectlinks) { ChainEnd openend = new ChainEnd(link, null); ChainEnd closeend = new ChainEnd(nextlink, openend); openend.SetOtherEnd(closeend); chains.Add(openend); chains.Add(closeend); curlink += 2; link = linklist[curlink]; nextlink = linklist[curlink + 1]; } if (!connectchains && !connectlinks) { // assert(link != null); // assert(chain != null); // assert(chain.getEtag() == link.getEtag()); chain.AddLink(link); chains.Add(chain); curchain++; chain = nextchain; nextchain = endlist[curchain + 1]; curlink++; link = nextlink; nextlink = linklist[curlink + 1]; } } }