public void updateGraph(int[] data) { lock (_syncRoot) { Parallel.For(0, dataNumber, j => { try { actualData[i][j] = data[j]; } catch (IndexOutOfRangeException e) { } }); //suspending updates for full update when all data are set using (dataSeries.SuspendUpdates()) { dataSeries.CopyFrom(actualData); } if (i < (dataNumber - 1)) { i++; } else { int[][] tmp = new int[dataNumber][]; Array.Copy(actualData, 1, tmp, 0, actualData.Length - 1); actualData = tmp; actualData[dataNumber - 1] = new int[dataNumber]; } }; }
private void OnStart() { if (!IsLoaded) { return; } string whatData = (string)DataCombo.SelectedItem; int w = 0, h = 0; if (whatData == "3D Sinc 10 x 10") { w = h = 10; } if (whatData == "3D Sinc 50 x 50") { w = h = 50; } if (whatData == "3D Sinc 100 x 100") { w = h = 100; } if (whatData == "3D Sinc 500 x 500") { w = h = 500; } if (whatData == "3D Sinc 1k x 1k") { w = h = 1000; } lock (_syncRoot) { OnStop(); } var dataSeries = new UniformGridDataSeries3D <double>(w, h) { StartX = 0, StartZ = 0, StepX = 10 / (w - 1d), StepZ = 10 / (h - 1d), SeriesName = "Realtime Surface Mesh", }; var frontBuffer = dataSeries.InternalArray; var backBuffer = new GridData <double>(w, h).InternalArray; int frames = 0; _timer = new Timer(); _timer.Interval = 20; _timer.Elapsed += (s, arg) => { lock (_syncRoot) { double wc = w * 0.5, hc = h * 0.5; double freq = Math.Sin(frames++ *0.1) * 0.1 + 0.1; // Each set of dataSeries[i,j] schedules a redraw when the next Render event fires. Therefore, we suspend updates so that we can update the chart once // Data generation (Sin, Sqrt below) is expensive. We parallelize it by using Parallel.For for the outer loop // Equivalent of "for (int j = 0; j < h; j++)" // This will result in more CPU usage, but we wish to demo the performance of the actual rendering, not the slowness of generating test data! :) Parallel.For(0, h, i => { var buf = frontBuffer; for (int j = 0; j < w; j++) { // 3D Sinc function from http://www.mathworks.com/matlabcentral/cody/problems/1305-creation-of-2d-sinc-surface // sin(pi*R*freq)/(pi*R*freq) // R is distance from centre double radius = Math.Sqrt((wc - i) * (wc - i) + (hc - j) * (hc - j)); var d = Math.PI * radius * freq; var value = Math.Sin(d) / d; buf[i][j] = double.IsNaN(value) ? 1.0 : value; } }); using (dataSeries.SuspendUpdates()) { dataSeries.CopyFrom(frontBuffer); var temp = backBuffer; backBuffer = frontBuffer; frontBuffer = temp; } } }; SurfaceMesh.DataSeries = dataSeries; _timer.Start(); StartButton.IsEnabled = false; PauseButton.IsEnabled = true; }