public static Tuple <int, int>[] GetCoords(Segment segment)
        {
            if (segment is Pixel)
            {
                Tuple <int, int>[] result = { ((Pixel)segment).Coordinate };

                return(result);
            }
            else
            {
                Parent seg = (Parent)segment;

                Tuple <int, int>[] result = new Tuple <int, int> [SegmentModule.SegmentSize(segment)];

                Tuple <int, int>[] seg1Result = GetCoords(seg.Seg1);
                Tuple <int, int>[] seg2Result = GetCoords(seg.Seg2);

                for (int i = 0; i < result.Length; i++)
                {
                    if (i < seg1Result.Length)
                    {
                        result[i] = seg1Result[i];
                    }
                    else
                    {
                        result[i] = seg2Result[i - seg1Result.Length];
                    }
                }

                return(result);
            }
        }
        public static Segment CreateBestNeighbour(Segment segment, float threshold, int N)
        {
            var neighbours = CreateNeighbours(segment, N);

            Tuple <float, Segment>[] mergers = new Tuple <float, Segment> [neighbours.Length];

            float   minCost = threshold;
            Segment minSeg  = null;

            for (int i = 0; i < neighbours.Length; i++)
            {
                if (SegmentModule.MergeCost(neighbours[i], segment) < minCost)
                {
                    minSeg = neighbours[i];
                }
            }

            return(minSeg);
        }
        //Find the neighbour(s) of the given segment that has the (equal) best merge cost
        // (exclude neighbours if their merge cost is greater than the threshold)
        private HashSet <Segment> FindBestNeighbours(Segment inputSegment)
        {
            HashSet <Segment> setOfNeighbours     = NeighboursSegment(inputSegment);
            HashSet <Segment> setOfBestNeighbours = new HashSet <Segment>();
            float             bestMergeCost       = FindBestMergeCost(setOfNeighbours, inputSegment);

            if (setOfNeighbours.Count != 0)
            {
                foreach (Segment neighbourSeg in setOfNeighbours)
                {
                    float currentMergeCost = SegmentModule.CalculateMergeCost(inputSegment, neighbourSeg);
                    if ((currentMergeCost == bestMergeCost) && (currentMergeCost <= this.currentThreshold))
                    {
                        setOfBestNeighbours.Add(neighbourSeg);
                    }
                }
            }

            return(setOfBestNeighbours);
        }
        // find Best MergeCost of a list helper function
        private float FindBestMergeCost(HashSet <Segment> segmentSet, Segment segment)
        {
            float bestMergeCost = 0;

            if (segmentSet.Count != 0)
            {
                bool firstPosition = true;
                foreach (Segment neighbourSeg in segmentSet)
                {
                    if (firstPosition)
                    {
                        bestMergeCost = SegmentModule.CalculateMergeCost(segment, neighbourSeg);
                        firstPosition = false;
                    }
                    float currentMergeCost = SegmentModule.CalculateMergeCost(segment, neighbourSeg);
                    if (currentMergeCost < bestMergeCost)
                    {
                        bestMergeCost = currentMergeCost;
                    }
                }
            }
            return(bestMergeCost);
        }