示例#1
0
 public void ShiftGenerations(ConnectedComponentSet complete)
 {
     // add first generation to the second
     Spans.UnionWith(FrontalSpans);
     // if the Generation 0 hasn't been filled,
     // it means the component is complete and won't grow anymore
     if (NewFrontalSpans.Count == 0)
     {
         // add it to the list of complete components
         complete.Add(this);
     }
     else
     {
         // Generation 0 grows older and becomes Generation 1
         FrontalSpans = NewFrontalSpans;
         // And a new Generation 0 is born
         NewFrontalSpans = new SpanList();
     }
 }
示例#2
0
        /// <summary>
        /// Calculates and returns a set of 4-connected components in a field
        /// </summary>
        /// <param name="field">The two-dimensional matrix with colors</param>
        /// <returns></returns>
        public static ConnectedComponentSet FindConnectedComponents(Field field)
        {
            ConnectedComponentSet result  = new ConnectedComponentSet();
            ConnectedComponentSet current = new ConnectedComponentSet();

            // we scan the entire matrix line by line
            for (int y = 0; y < field.Size.Height; y++)
            {
                SpanList spansOnCurrentLine = GetSpansFromLine(field, y);
                foreach (var span in spansOnCurrentLine)
                {
                    PlaceSpan(span, current);
                }

                // check which components didn't change since the previous iteration
                ConnectedComponentSet complete = new ConnectedComponentSet();

                foreach (var component in current)
                {
                    component.ShiftGenerations(complete);
                }

                foreach (var component in complete)
                {
                    component.FrontalSpans.Clear();
                    current.Remove(component);
                    result.Add(component);
                }
            }

            // We reached the bottom
            // For all the remaining components, add them to the result
            foreach (var component in current)
            {
                component.Spans.UnionWith(component.FrontalSpans);
                component.Spans.UnionWith(component.NewFrontalSpans);
                result.Add(component);
            }

            return(result);
        }
示例#3
0
        /// <summary>
        /// Classifies a span with regard to already processed spans
        /// </summary>
        /// <param name="currentSpan"></param>
        /// <param name="currentComponentSet"></param>
        static void PlaceSpan(Span currentSpan, ConnectedComponentSet currentComponentSet)
        {
            if (currentSpan.Y == 0)
            {
                // for the first row, just accumulate the spans in the Generation 0
                currentComponentSet.AddNewComponentFromSpan(currentSpan);
                return;
            }

            // find all spans from Generation 1 that "touch" this span
            ConnectedComponentSet componentsToJoin = new ConnectedComponentSet();

            componentsToJoin.AddRange(
                currentComponentSet.Where(
                    component => component.FrontalSpans.IntersectsWith(currentSpan)));

            // if we "touch" 0 existing components, create a new one
            if (componentsToJoin.Count == 0)
            {
                currentComponentSet.AddNewComponentFromSpan(currentSpan);
            }
            // if we touch one component, append the current span to its bottom
            else if (componentsToJoin.Count == 1)
            {
                componentsToJoin[0].NewFrontalSpans.Add(currentSpan);
            }
            // if we touch more than one component, it means they all belong together.
            // Now we unite all of these components into one.
            else
            {
                for (int i = 1; i < componentsToJoin.Count; i++)
                {
                    componentsToJoin[0].NewFrontalSpans.Add(currentSpan);
                    componentsToJoin[0].UnionWith(componentsToJoin[i]);
                    currentComponentSet.Remove(componentsToJoin[i]);
                }
            }
        }