private int FindNextNeighbor(int c)
 {
     MyConnectedComponentsAnalysisFast.MyBlob char1 = _char_list[c];
     for (int i = 0; i < char1.neighbors.Count; i++)
     {
         int idx = char1.neighbors[i];
         if (_char_list[idx].sizefilter_included)
         {
             return(idx);
         }
     }
     return(-1);
 }
        private void TraceCharacters(List <int> substring_list, int p1, int p3, int min_angle)
        {
            if (_char_list[p3].neighbors.Count <= 0)
            {
                return;
            }

            double max_angle     = -1;
            int    max_angle_idx = 0;

            if (_debug)
            {
                Console.WriteLine("*****Trace:Char " + p1 + " and " + p3);
            }
            MyConnectedComponentsAnalysisFast.MyBlob char1 = _char_list[p3];
            for (int i = 0; i < char1.neighbors.Count; i++)
            {
                int idx = char1.neighbors[i];
                if (_char_list[idx].sizefilter_included)
                {
                    double angel = CosAngel(p1, idx, p3);
                    if (angel > max_angle)
                    {
                        max_angle = angel; max_angle_idx = idx;
                    }
                }
            }
            if (max_angle_idx >= 0 && max_angle > min_angle)
            {
                substring_list.Add(max_angle_idx);
                _char_list[max_angle_idx].neighbors.Remove(p3);
                _char_list[p3].neighbors.Remove(max_angle_idx);
                if (_debug)
                {
                    Console.WriteLine("     Found: " + max_angle_idx + " Angle: " + max_angle + " Min Angle: " + min_angle);
                }
                if (_char_list[p3].split_here || _char_list[max_angle_idx].split_here)
                {
                    TraceCharacters(substring_list, p3, max_angle_idx, _larger_angle_threshold); // strict
                }
                else
                {
                    TraceCharacters(substring_list, p3, max_angle_idx, _smaller_angle_threshold);
                }
            }
            else
            if (_debug)
            {
                Console.WriteLine("     Found none: " + max_angle_idx + " Angle: " + max_angle + " Min Angle: " + min_angle);
            }
        }
        private double ShortestDistance(MyConnectedComponentsAnalysisFast.MyBlob char_blob)
        {
            double min_distance = Double.MaxValue;
            Point  a            = char_blob.mass_center;

            for (int i = 0; i < _char_list.Count; i++)
            {
                Point  b        = _char_list[i].mass_center;
                double distance = Math.Sqrt((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y));
                if (distance < min_distance)
                {
                    min_distance = distance;
                }
            }
            return(min_distance);
        }
 private void MergeOne(List <int> tmp_list4one)
 {
     if (_debug)
     {
         Console.WriteLine("*******Merge One******");
     }
     for (int i = 0; i < tmp_list4one.Count; i++)
     {
         // for small cc only since small cc still has neighbors
         int idx1 = tmp_list4one[i];
         MyConnectedComponentsAnalysisFast.MyBlob char1 = _char_list[idx1];
         for (int ni = 0; ni < char1.neighbors.Count; ni++)
         {
             int idx = char1.neighbors[ni];
             for (int j = 0; j < _final_string_list.Count; j++)
             {
                 TextString ts = _final_string_list[j];
                 if (ts._char_list.Contains(_char_list[idx]))
                 {
                     _char_list[idx1].included = true;
                     ts.AddChar(_char_list[idx1]);
                     if (_debug)
                     {
                         Console.WriteLine("                 Add TS: " + idx1 + " to TS: " + j);
                     }
                 }
             }
         }
         if (_debug)
         {
             Console.WriteLine(idx1 + " is not a small cc");
         }
         if (!_char_list[idx1].included)
         {
             _char_list[idx1].included = true;
             List <int> tmp_list = new List <int>();
             tmp_list.Add(idx1);
             AddSubstring(tmp_list);
         }
     }
 }
        public void Update(ref TextString srcString)
        {
            MyConnectedComponentsAnalysisFast.MyBlob char_blob0 = srcString.char_list[0];
            char_blob0.mass_center.X += srcString.x_offset;
            char_blob0.mass_center.Y += srcString.y_offset;
            char_blob0.bbx.X         += srcString.x_offset;
            char_blob0.bbx.Y         += srcString.y_offset;
            Rectangle bbx = char_blob0.bbx;

            for (int i = 1; i < srcString.char_list.Count; i++)
            {
                MyConnectedComponentsAnalysisFast.MyBlob char_blob = srcString.char_list[i];
                char_blob.mass_center.X += srcString.x_offset;
                char_blob.mass_center.Y += srcString.y_offset;
                char_blob.bbx.X         += srcString.x_offset;
                char_blob.bbx.Y         += srcString.y_offset;

                int x = bbx.X, y = bbx.Y, xx = bbx.X + bbx.Width - 1, yy = bbx.Y + bbx.Height - 1;
                int x1 = char_blob.bbx.X, y1 = char_blob.bbx.Y, xx1 = char_blob.bbx.X + char_blob.bbx.Width - 1, yy1 = char_blob.bbx.Y + char_blob.bbx.Height - 1;

                int x2, y2, xx2, yy2;

                if (x < x1)
                {
                    x2 = x;
                }
                else
                {
                    x2 = x1;
                }
                if (y < y1)
                {
                    y2 = y;
                }
                else
                {
                    y2 = y1;
                }

                if (xx < xx1)
                {
                    xx2 = xx1;
                }
                else
                {
                    xx2 = xx;
                }
                if (yy < yy1)
                {
                    yy2 = yy1;
                }
                else
                {
                    yy2 = yy;
                }

                bbx.X      = x2; bbx.Y = y2;
                bbx.Width  = xx2 - x2 + 1;
                bbx.Height = yy2 - y2 + 1;
            }
            srcString.bbx = bbx;
        }
        public void AddChar(MyConnectedComponentsAnalysisFast.MyBlob char_blob)
        {
            if (_char_list.Contains(char_blob))
            {
                return;
            }
            for (int i = 0; i < _char_list.Count; i++)
            {
                if (Distance(_char_list[i].mass_center, char_blob.mass_center) < 3)
                {
                    return;
                }
            }
            _mean_height = (_mean_height * _char_list.Count + char_blob.bbx.Height);
            _mean_width  = (_mean_width * _char_list.Count + char_blob.bbx.Width);
            _char_list.Add(char_blob);
            _mean_height /= (double)_char_list.Count;
            _mean_width  /= (double)_char_list.Count;
            // Extend bbx
            if (_bbx.Width == 0)
            {
                _bbx = char_blob.bbx;
            }
            else
            {
                int x = _bbx.X, y = _bbx.Y, xx = _bbx.X + _bbx.Width - 1, yy = _bbx.Y + _bbx.Height - 1;
                int x1 = char_blob.bbx.X, y1 = char_blob.bbx.Y, xx1 = char_blob.bbx.X + char_blob.bbx.Width - 1, yy1 = char_blob.bbx.Y + char_blob.bbx.Height - 1;

                int x2, y2, xx2, yy2;

                if (x < x1)
                {
                    x2 = x;
                }
                else
                {
                    x2 = x1;
                }
                if (y < y1)
                {
                    y2 = y;
                }
                else
                {
                    y2 = y1;
                }

                if (xx < xx1)
                {
                    xx2 = xx1;
                }
                else
                {
                    xx2 = xx;
                }
                if (yy < yy1)
                {
                    yy2 = yy1;
                }
                else
                {
                    yy2 = yy;
                }

                _bbx.X      = x2; _bbx.Y = y2;
                _bbx.Width  = xx2 - x2 + 1;
                _bbx.Height = yy2 - y2 + 1;
            }
        }