/// <summary> /// Updates a 2D aggregate based on current contents of dla_2d batch_queue - processes this /// batch_queue and adds its contents to the simulation view. /// </summary> /// <param name="source"></param> /// <param name="e"></param> private void Aggregate2DUpdateOnTimedEvent(object source, ElapsedEventArgs e) { // lock around aggregate updating and batch queue processing to prevent // non-dereferencable std::deque iterator run-time errors lock (locker) { // get and process the batch_queue from the DLA handle BlockingCollection <KeyValuePair <int, int> > blocking_queue = dla_2d.ProcessBatchQueue(); // loop over blocking_queue adding contents to interface and dequeueing on each iteration while (blocking_queue.Count != 0) { KeyValuePair <int, int> agg_kvp = blocking_queue.Take(); Point3D pos = new Point3D(agg_kvp.Key, agg_kvp.Value, 0); aggregate_manager.AddParticle(pos, colour_list[(int)current_particles], 1.0); ++current_particles; // dispatch GUI updates to UI thread Dispatcher.Invoke(() => { aggregate_manager.Update(); DynamicParticleLabel.Content = "Particles: " + current_particles; }); } } }
/// <summary> /// Render the points of the attractor type used. /// </summary> private void RenderAttractorGeometry() { if (!showAttractor || aggregate_manager == null) { return; } switch (attractor_type) { case ManagedAttractorType.Point: // render single point at origin aggregate_manager.AddParticle(new Point3D(0.0, 0.0, 0.0), Colors.White, 1.0); aggregate_manager.Update(); break; case ManagedAttractorType.Line: // render line of length attractorsize_slider.Value symmetrical about origin for (int i = -(int)attractorsize_slider.Value / 2; i < (int)attractorsize_slider.Value / 2; ++i) { aggregate_manager.AddParticle(new Point3D(i, 0.0, 0.0), Colors.White, 1.0); aggregate_manager.Update(); } break; case ManagedAttractorType.Plane: // render plane of length, width attractorsize_slider.Value symmetrical about origin for (int i = -(int)attractorsize_slider.Value / 2; i < (int)attractorsize_slider.Value / 2; ++i) { for (int j = -(int)attractorsize_slider.Value / 2; j < (int)attractorsize_slider.Value / 2; ++j) { aggregate_manager.AddParticle(new Point3D(i, j, 0.0), Colors.White, 1.0); aggregate_manager.Update(); } } break; case ManagedAttractorType.Circle: // render circle of radius attractorsize_slider.Value with centre at origin for (double theta = 0.0; theta <= 2 * Math.PI; theta += Math.PI / 180.0) { double x = attractorsize_slider.Value * Math.Cos(theta); double y = attractorsize_slider.Value * Math.Sin(theta); aggregate_manager.AddParticle(new Point3D(x, y, 0.0), Colors.White, 1.0); aggregate_manager.Update(); } break; } }