Esempio n. 1
0
        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];
                }
            }
        }