public void Split()
        {
            firstSubSegment  = new ReduceSegment(Points.Take(maxDistanceIndex + 1).ToArray());
            secondSubSegment = new ReduceSegment(Points.Skip(maxDistanceIndex).ToArray());

            Splitted = true;
        }
        private List <TrackPoint> GetPoints(ReduceSegment segment)
        {
            var points = new List <TrackPoint>();

            if (!segment.Splitted)
            {
                return(points);
            }

            points.AddRange(GetPoints(segment.firstSubSegment));
            points.Add(segment.maxDistancePoint);
            points.AddRange(GetPoints(segment.secondSubSegment));

            return(points);
        }
        private ReduceSegment FindSegmentWithMaxDistance(ReduceSegment segment)
        {
            if (!segment.Splitted)
            {
                return(segment);
            }

            var firstSegment  = FindSegmentWithMaxDistance(segment.firstSubSegment);
            var secondSegment = FindSegmentWithMaxDistance(segment.secondSubSegment);

            if (firstSegment.maxDistance >= secondSegment.maxDistance)
            {
                return(firstSegment);
            }

            return(secondSegment);
        }
        public TrackPoint[] Process(TrackPoint[] points)
        {
            List <TrackPoint> result = new List <TrackPoint>();

            if (points.Length <= MaxNrOfPoints)
            {
                return(points);
            }

            var rootSegment = new ReduceSegment(points);

            for (var i = 0; i < MaxNrOfPoints; i++)
            {
                var segment = FindSegmentWithMaxDistance(rootSegment);

                segment.Split();
            }

            result.Add(rootSegment.Points.First());
            result.AddRange(GetPoints(rootSegment));
            result.Add(rootSegment.Points.Last());

            return(result.ToArray());
        }