public static Contour TraceContour(int a_iStartingPixelIndex, NeighborDirection a_eStartingDirection, int a_iContourLabel, BinarizedImage a_rBinarizedImage, int[] a_rLabelMap)
    {
        int iPixelIndexTrace;
        NeighborDirection eDirectionNext = a_eStartingDirection;

        FindNextPoint(a_iStartingPixelIndex, a_eStartingDirection, a_rBinarizedImage, a_rLabelMap, out iPixelIndexTrace, out eDirectionNext);
        Contour oContour = new Contour(a_iContourLabel);

        oContour.AddFirst(a_rBinarizedImage.PixelIndex2Coords(iPixelIndexTrace));
        int  iPreviousPixelIndex = a_iStartingPixelIndex;
        int  iCurrentPixelIndex  = iPixelIndexTrace;
        bool bDone = (a_iStartingPixelIndex == iPixelIndexTrace);

        // Choose a bias factor
        // The bias factor points to exterior if tracing an outer contour
        // The bias factor points to interior if tracing an inner contour
        float fOrthoBiasFactor;

        if (a_eStartingDirection == NeighborDirection.DirectionUpRight)                 // inner contour
        {
            fOrthoBiasFactor = -0.2f;
        }
        else         // outer contour
        {
            fOrthoBiasFactor = 0.2f;
        }

        while (bDone == false)
        {
            a_rLabelMap[iCurrentPixelIndex] = a_iContourLabel;
            NeighborDirection eDirectionSearch = (NeighborDirection)(((int)eDirectionNext + 6) % 8);
            int iNextPixelIndex;
            FindNextPoint(iCurrentPixelIndex, eDirectionSearch, a_rBinarizedImage, a_rLabelMap, out iNextPixelIndex, out eDirectionNext);

            iPreviousPixelIndex = iCurrentPixelIndex;
            iCurrentPixelIndex  = iNextPixelIndex;
            bDone = (iPreviousPixelIndex == a_iStartingPixelIndex && iCurrentPixelIndex == iPixelIndexTrace);

            if (bDone == false)
            {
                // Apply some bias to inner and outer contours to avoid them overlap
                // Use the orthogonal vector to direction
                NeighborDirection eOrthoBiasDirection = (NeighborDirection)(((int)eDirectionNext + 6) % 8);                       // == direction - 2 % 8 but easier to compute (always positive)
                Vector2           f2Bias = fOrthoBiasFactor * BinarizedImage.GetDirectionVector(eOrthoBiasDirection);

                // Add bias to pixel pos
                Vector2 f2BiasedPos = f2Bias + a_rBinarizedImage.PixelIndex2Coords(iNextPixelIndex);

                // Add biased pos to contour
                oContour.AddFirst(f2BiasedPos);
            }
        }

        return(oContour);
    }