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);
    }
	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;	
	}