private static List <TimedPosition> LimitValues(List <TimedPosition> values, int count, TimeSpan timeFrom, TimeSpan timeTo, bool isMin) { //if (values.Count <= count) // return values; List <TimedPosition> result = new List <TimedPosition>(); result.Add(values.First()); PositionCollection positions = new PositionCollection(values); TimeSpan duration = timeTo - timeFrom; TimeSpan step = duration.Divide(count); int indexMin = (int)Math.Floor((values.First().TimeStamp - timeFrom).Divide(step)); int indexMax = (int)Math.Floor((values.Last().TimeStamp - timeFrom).Divide(step)); for (int index = indexMin; index <= indexMax; index++) { TimeSpan tFrom = timeFrom + step.Multiply(index); TimeSpan tTo = timeFrom + step.Multiply(index + 1); var pos = positions.GetPositions(tFrom, tTo); byte value; if (isMin) { value = (byte)Math.Max(0, pos.Min(p => p.Position) - 5); } else { value = (byte)Math.Min(99, pos.Max(p => p.Position) + 5); } TimeSpan center = timeFrom + step.Multiply(index + 0.5); result.Add(new TimedPosition { Position = value, TimeStamp = center }); } result.Add(values.Last()); return(result); }
public static Brush Generate3(List <TimedPosition> beats, TimeSpan gapDuration, TimeSpan timeFrom, TimeSpan timeTo, double multiplier, out Geometry bounds) { PositionCollection pc = new PositionCollection(beats); List <TimedPosition> trimmedBeats = pc.GetPositions(timeFrom, timeTo).ToList(); List <HeatMapEntry> stops = new List <HeatMapEntry>(); List <List <TimedPosition> > segments = GetSegments(trimmedBeats, gapDuration, timeFrom, timeTo); TimeSpan fastest = TimeSpan.FromMilliseconds(200); TimeSpan duration = timeTo - timeFrom; stops.Add(new HeatMapEntry(Colors.Transparent, 0.0)); foreach (List <TimedPosition> segment in segments) { if (segment.Count == 1) { TimeSpan stamp = segment.Single().TimeStamp; TimeSpan span = TimeSpan.FromSeconds(2); TimeSpan beginSegment = stamp - span; if (beginSegment < timeFrom) { beginSegment = timeFrom; } TimeSpan endSegment = stamp + span; if (endSegment > timeTo) { endSegment = timeTo; } stops.Add(new HeatMapEntry(Colors.Transparent, beginSegment.Divide(duration))); stops.Add(new HeatMapEntry(Colors.DodgerBlue, beginSegment.Divide(duration))); stops.Add(new HeatMapEntry(Colors.DodgerBlue, endSegment.Divide(duration))); stops.Add(new HeatMapEntry(Colors.Transparent, endSegment.Divide(duration))); } else { TimeSpan span = segment.Last().TimeStamp - segment.First().TimeStamp; int segmentCount = (int)Math.Max(1, Math.Min((segment.Count - 1) / 12.0, span.Divide(duration.Divide(200)))); stops.Add(new HeatMapEntry(Colors.Transparent, (segment.First().TimeStamp - timeFrom).Divide(duration))); for (int i = 0; i < segmentCount; i++) { int startIndex = Math.Min(segment.Count - 1, (int)((i * (segment.Count - 1)) / (double)segmentCount)); int endIndex = Math.Min(segment.Count - 1, (int)(((i + 1) * (segment.Count - 1)) / (double)segmentCount)); int beatCount = endIndex - startIndex - 1; TimeSpan firstBeat = segment[startIndex].TimeStamp; TimeSpan lastBeat = segment[endIndex].TimeStamp; TimeSpan averageLength = (lastBeat - firstBeat).Divide(beatCount); double value = fastest.Divide(averageLength) * multiplier; value = Math.Min(1, Math.Max(0, value)); Color color = GetColorAtPosition(HeatMap, value); double positionStart = firstBeat.Divide(duration); double positionEnd = lastBeat.Divide(duration); if (i == 0) { stops.Add(new HeatMapEntry(color, positionStart)); } stops.Add(new HeatMapEntry(color, (positionEnd + positionStart) / 2.0)); if (i == segmentCount - 1) { stops.Add(new HeatMapEntry(color, positionEnd)); } } stops.Add(new HeatMapEntry(Colors.Transparent, (segment.Last().TimeStamp - timeFrom).Divide(duration))); } } stops.Add(new HeatMapEntry(Colors.Transparent, 1.0)); LinearGradientBrush brush = new LinearGradientBrush(FillGradients(stops), new Point(0, 0), new Point(1, 0)); brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; GetMinMaxPositions(trimmedBeats, out List <TimedPosition> min, out List <TimedPosition> max); bounds = BuildBoundsGeometry(timeFrom, timeTo, min, max); return(brush); }