public SimulationAnimation(IInstanceInfo instance, Dispatcher uiDispatcher, SimulationAnimationConfig config, Func <BotColorMode> botColorModeGetter, Func <bool> heatModeEnabled) { _config = config; _dispatcher = uiDispatcher; _heatModeEnabled = heatModeEnabled; _botColorModeGetter = botColorModeGetter; _instance = instance; // Init colors for current bots List <IBotInfo> bots = instance.GetInfoBots().ToList(); for (int i = 0; i < bots.Count; i++) { _rainbowBotColors[bots[i]] = new SolidColorBrush(HeatVisualizer.GenerateBiChromaticHeatColor(Colors.Purple, Colors.Red, ((double)i / (bots.Count - 1)))); } }
public override void UpdateMetaInfo() { if (_heatModeEnabled()) { Brush heatBrush = HeatVisualizer.GenerateHeatBrush(_pod.GetInfoHeatValue()); if (Fill != heatBrush) { Fill = heatBrush; } } else { if (Fill != VisualizationConstants.BrushPodVisual) { Fill = VisualizationConstants.BrushPodVisual; } } }
public Brush GetBotColor(IBotInfo bot, string state) { // Check whether we already generated a color for the bot if (!_rainbowBotColors.ContainsKey(bot)) { Random randomizer = new Random(); _rainbowBotColors[bot] = new SolidColorBrush(HeatVisualizer.GenerateBiChromaticHeatColor(Colors.Purple, Colors.Red, randomizer.NextDouble())); } // Return color BotColorMode colorMode = _botColorModeGetter(); switch (colorMode) { case BotColorMode.DefaultBotDefaultState: return(VisualizationConstants.StateBrushes[state]); case BotColorMode.RainbowBotSingleState: return(state == "Move" ? _rainbowBotColors[bot] : VisualizationConstants.StateBrushHidden); case BotColorMode.RainbowBotDefaultState: return(state == "Move" ? _rainbowBotColors[bot] : VisualizationConstants.StateBrushes[state]); default: throw new ArgumentException("Unknown bot coloring mode: " + colorMode.ToString()); } }
public override void UpdateMetaInfo() { if (_heatModeEnabled()) { Brush heatBrush = HeatVisualizer.GenerateHeatBrush(Pod.GetInfoHeatValue()); foreach (var child in this.Children.OfType <BoxVisual3D>().ToArray()) { if (child.Fill != heatBrush) { child.Fill = heatBrush; } } } else { foreach (var child in this.Children.OfType <BoxVisual3D>().ToArray()) { if (child.Fill != VisualizationConstants.BrushPodVisual) { child.Fill = VisualizationConstants.BrushPodVisual; } } } }
/// <summary> /// Builds and renders the heatmap. /// </summary> private void BuildHeatmap() { // Prepare datapoints for a bit more efficient calculation _logger("Preparing dataset ..."); HashSet <HeatDatapoint>[,] datapointMap = new HashSet <HeatDatapoint> [_heatmap.GetLength(0), _heatmap.GetLength(1)]; foreach (var datapoint in _dataPoints) { int xIndex = (int)(datapoint.X / _tier.GetInfoLength() * _heatmap.GetLength(0)); int yIndex = (int)(datapoint.Y / _tier.GetInfoWidth() * _heatmap.GetLength(1)); if (datapointMap[xIndex, yIndex] == null) { datapointMap[xIndex, yIndex] = new HashSet <HeatDatapoint>(); } datapointMap[xIndex, yIndex].Add(datapoint); } // Actually calculate all the heat information _logger("Calculating heatmap ..."); DateTime lastLog = DateTime.MinValue; TimeSpan minLogInterval = TimeSpan.FromSeconds(3); int counter = 0; int overallCount = _heatmap.GetLength(0) * _heatmap.GetLength(1); Parallel.For(0, _heatmap.GetLength(0), (int x) => // Calculate heat values in parallel across the rows { for (int y = 0; y < _heatmap.GetLength(1); y++) { _heatmap[x, y] = GetHeatValue(datapointMap, x, y); counter++; if (DateTime.Now - lastLog > minLogInterval) { _logger(counter + " / " + overallCount); lastLog = DateTime.Now; } } }); _logger(overallCount + " / " + overallCount); // Handle logarithmic transformation, if desired if (_config.Logarithmic) { // If logarithmic values are desired, shift all values to numbers greater or equal to 1 first double minValue = _heatmap.Cast <double>().Min(v => v); double offsetForLog = minValue < 1 ? 1 - minValue : 0; if (_config.Logarithmic && offsetForLog > 0) { for (int x = 0; x < _heatmap.GetLength(0); x++) { for (int y = 0; y < _heatmap.GetLength(1); y++) { _heatmap[x, y] += offsetForLog; } } } // Transform to logarithmic values if desired for (int x = 0; x < _heatmap.GetLength(0); x++) { for (int y = 0; y < _heatmap.GetLength(1); y++) { _heatmap[x, y] = _heatmap[x, y] <= 0 ? 0 : Math.Log10(_heatmap[x, y]); } } } // Normalize the heat to [0,1] _logger("Normalizing heatmap ..."); double maxHeat = double.MinValue; for (int x = 0; x < _heatmap.GetLength(0); x++) { for (int y = 0; y < _heatmap.GetLength(1); y++) { maxHeat = Math.Max(maxHeat, _heatmap[x, y]); } } for (int x = 0; x < _heatmap.GetLength(0); x++) { for (int y = 0; y < _heatmap.GetLength(1); y++) { _heatmap[x, y] /= maxHeat; } } // Render the heat overlay _logger("Rendering heatmap ..."); _contentControl.Dispatcher.Invoke(() => { // Init image Image image = new Image(); RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor); image.Opacity = 0.7; int bitmapWidth = (int)_transformer.ProjectXLength(_heatmap.GetLength(0)); int bitmapHeight = (int)_transformer.ProjectYLength(_heatmap.GetLength(1)); WriteableBitmap writeableBitmap = BitmapFactory.New(bitmapWidth + 1, bitmapHeight + 1); // TODO hotfixing the missing 1-pixel column and row by increasing the size of the bitmap by 1 in each direction // Draw all tiles for (int x = 0; x < _heatmap.GetLength(0); x++) { for (int y = 0; y < _heatmap.GetLength(1); y++) { int x1 = (int)_transformer.ProjectX(x); int y1 = (int)_transformer.ProjectY(y + 1.0); int x2 = (int)_transformer.ProjectX(x + 1.0); int y2 = (int)_transformer.ProjectY(y); Color color = _config.BichromaticColoring ? HeatVisualizer.GenerateBiChromaticHeatColor(_config.BichromaticColorOne, _config.BichromaticColorTwo, _heatmap[x, y]) : HeatVisualizer.GenerateHeatColor(_heatmap[x, y]); writeableBitmap.FillRectangle(x1, y1, x2, y2, color); } } image.Source = writeableBitmap; ResultImage = image; // Add the image to the canvas (in background, if desired) if (_config.DrawInBackground) { _contentControl.Children.Insert(0, image); } else { _contentControl.Children.Add(image); } }); // Finished _logger("Heatmap done!"); }