Exemplo n.º 1
0
        public void FindCells()
        {
            // First we construct "wedges", which are pairs of sequential edges around each vtx.
            // we then put all in a hash set, we will iterate until we use up all the available wedges.
            // Edges are sorted by positive angle, so they are in clockwise order
            // Hence, going from edge n to n+1 is a left-turn, and so "inside" cells are oriented clockwise
            int NV        = Graph.MaxVertexID;
            var wedges    = new Index2i[NV][];
            var remaining = new HashSet <Index2i>();

            foreach (int vid in Graph.VertexIndices())
            {
                int[] sorted = Graph.SortedVtxEdges(vid);
                wedges[vid] = new Index2i[sorted.Length];

                for (int k = 0; k < sorted.Length; ++k)
                {
                    wedges[vid][k] = new Index2i(sorted[k], sorted[(k + 1) % sorted.Length]);
                    remaining.Add(new Index2i(vid, k));
                }
            }

            CellLoops = new List <int[]>();

            var loopv = new List <int>();

            while (remaining.Count > 0)
            {
                Index2i idx = remaining.First();
                remaining.Remove(idx);

                int start_vid = idx.a;
                int wid       = idx.b;
                int e0        = wedges[start_vid][wid].a; e0 = e0 + 1 - 1;            // get rid of unused variable warning, want to keep this for debugging
                int e1        = wedges[start_vid][wid].b;

                loopv.Clear();
                loopv.Add(start_vid);

                int cur_v      = start_vid;
                int outgoing_e = e1;

                // walk around loop taking immediate left-turns
                bool done = false;
                while (!done)
                {
                    // find outgoing edge and vtx at far end
                    Index2i ev     = Graph.GetEdgeV(outgoing_e);
                    int     next_v = (ev.a == cur_v) ? ev.b : ev.a;

                    if (next_v == start_vid)
                    {
                        done = true;
                        continue;
                    }

                    // now find wedge at that vtx where this is incoming edge
                    Index2i[] next_wedges   = wedges[next_v];
                    int       use_wedge_idx = -1;
                    for (int k = 0; k < next_wedges.Length; ++k)
                    {
                        if (next_wedges[k].a == outgoing_e)
                        {
                            use_wedge_idx = k;
                            break;
                        }
                    }
                    if (use_wedge_idx == -1)
                    {
                        throw new Exception("could not find next wedge?");
                    }

                    remaining.Remove(new Index2i(next_v, use_wedge_idx));
                    loopv.Add(next_v);
                    cur_v      = next_v;
                    outgoing_e = next_wedges[use_wedge_idx].b;
                }

                CellLoops.Add(loopv.ToArray());
            }
        }