/// <summary>
        /// Returns the coordinates of the pixels that lie on the sampling line, which is defined by the
        /// <paramref name="startingPosition"/> and its <paramref name="angle"/> to the edge of the
        /// <paramref name="image"/>. The <paramref name="startingPosition"/> will not be returned in the
        /// result set.
        /// </summary>
        /// <remarks>
        /// <example>
        /// Here's an example using the angle of 45 degrees.
        /// <![CDATA[
        /// ^
        /// |   E                         E = edge of the image
        /// |    \                        \ = sampling line
        /// |      \                      c = center
        /// |        \
        /// |          \
        /// |            \
        /// |              c
        /// |
        /// .
        /// .
        /// . --------------------------->
        /// ]]>
        /// </example>
        /// </remarks>
        internal static SamplingLine GetSamplingLineForAngle(
            BinaryImage image,
            MatrixPosition startingPosition,
            int angle)
        {
            const int MaxIterationLimit = 50000;

            var samplingLine = new SamplingLine();

            MatrixPosition nextPosition;
            double         phi = (angle + 180d) * Math.PI / 180d;
            int            r   = 1;

            do
            {
                var deltaN = (int)Math.Round(r * Math.Cos(phi), 0, MidpointRounding.ToZero);
                var deltaM = (int)Math.Round(r * Math.Sin(phi), 0, MidpointRounding.ToZero);
                nextPosition = new MatrixPosition(startingPosition.M + deltaM, startingPosition.N + deltaN);
                if (nextPosition != startingPosition
                    // ReSharper disable once SimplifyLinqExpressionUseAll
                    && !samplingLine.ContainsPosition(nextPosition) &&
                    IsPositionWithinImage(image, nextPosition))
                {
                    var pointOfInterest = new SamplingPoint(nextPosition, r);
                    samplingLine.Add(pointOfInterest);
                }

                r++;
            } while (IsPositionWithinImage(image, nextPosition) && r < MaxIterationLimit);

            return(samplingLine);
        }
 private static IEnumerable <int> FindAllBlackPixelsOnSamplingLine(
     BinaryImage image,
     SamplingLine samplingLine)
 {
     return(from samplingPoints in samplingLine.SamplingPoints
            where image[samplingPoints.Position] == BinaryImage.Black
            select samplingPoints.Radius);
 }
        internal static IReadOnlyCollection <SamplingLine> GetSamplingLines(BinaryImage image, int numberOfSamplingLines)
        {
            CheckNumberOfSamplingLinesIsInRange(numberOfSamplingLines);

            double angleIncrement = 360d / numberOfSamplingLines;
            var    samplingLines  = new SamplingLine[numberOfSamplingLines];

            var center = GetCenterOfObjectIn(image);

            for (int samplingIndex = 0; samplingIndex < numberOfSamplingLines; samplingIndex++)
            {
                // value of the angle, at which the sampling from the center will be taken.
                int angle        = (int)Math.Round(samplingIndex * angleIncrement, 0, MidpointRounding.ToZero);
                var samplingLine = GetSamplingLineForAngle(image, center, angle);

                samplingLines[samplingIndex] = samplingLine;
            }

            return(samplingLines);
        }