private void Update(float timeInSeconds) { this.ElapsedTime += timeInSeconds; double[] sides = { 1, _viewResolution.Width - 1 }; double[] topBottom = { 1, _viewResolution.Height - 1 }; foreach (FluidSimParticle p in _particles) { p.Particle.Move(timeInSeconds); p.LifeTime += timeInSeconds; if (ShouldResetParticle(p)) { p.LifeTime = GetNewLifeTime(); if (this.SelectedVelocityField == CommonVelocityFields.UniformStream || this.SelectedVelocityField == CommonVelocityFields.ShearFlow || this.SelectedVelocityField == CommonVelocityFields.RotatingCylinder || this.SelectedVelocityField == CommonVelocityFields.FlowPast_Sphere) { // Rightward motion only so reset points on left p.Particle.Position = new Vector(0, this.Rand.Next(0, _viewResolution.Height)); } //else if (this.SelectedVelocityField == CommonVelocityFields.Vortex || this.SelectedVelocityField == CommonVelocityFields.RankineVortex) //{ // // Reset particles randomly on screen. // // Cannot reset to walls because it results in a 'square' coming into the centre as each wave of particles die. Doesn't look right. // p.Particle.Position = new Vector(this.Rand.Next(0, _viewResolution.Width), this.Rand.Next(0, _viewResolution.Height)); //} else { //Field requires particles to appear from all sides if (this.Rand.Next(0, 2) == 1) { // Place on top or bottom double topBottomPos = topBottom[this.Rand.Next(0, 2)]; // random of 0 or _viewRes.H p.Particle.Position = new Vector(this.Rand.Next(1, _viewResolution.Width - 1), topBottomPos); } else { // Place on left or right double sidePos = sides[this.Rand.Next(0, 2)]; // random of 0 or _viewRes.W p.Particle.Position = new Vector(sidePos, this.Rand.Next(1, _viewResolution.Height - 1)); } } } p.Node.Position = new CCPoint((float)p.Particle.Position.X, (float)p.Particle.Position.Y); } foreach (FluidSimParticle p in _touchParticles.Where(x => x.Node.Visible)) { p.Particle.Move(timeInSeconds); p.LifeTime += timeInSeconds; if (ShouldResetParticle(p)) { // Hide! p.Node.Visible = false; p.LifeTime = 0; } else { //Update node position p.Node.Position = new CCPoint((float)p.Particle.Position.X, (float)p.Particle.Position.Y); } } if (this.IsTouchingScreen && CanReleaseParticle()) { // Get next available touch particle // The next available is any particle that is currentlty not visible, OR if all particles are already visible, it instead uses the oldest one FluidSimParticle p = _touchParticles .OrderBy(x => x.Node.Visible) .ThenByDescending(x => x.LifeTime) .First(); p.LifeTime = 0; p.Particle.Position = new Vector(this.TouchLocation.X, this.TouchLocation.Y); p.Node.Position = this.TouchLocation; p.Node.Visible = true; } if (_spinningWheelNode.Visible) { float x = (float)(_centreWheelNode.Position.X + (RadiusSlider.Value * 0.9) * Math.Cos(this.ElapsedTime * RotationSlider.Value / 250)); float y = (float)(_centreWheelNode.Position.Y + (RadiusSlider.Value * 0.9) * Math.Sin(this.ElapsedTime * RotationSlider.Value / 250)); _spinningWheelNode.Position = new CCPoint(x, y); } UpdateLabels(); }
private bool ShouldResetParticle(FluidSimParticle p) { return(p.Particle.Position.X < 0 || p.Particle.Position.X > _viewResolution.Width || p.Particle.Position.Y < 0 || p.Particle.Position.Y > _viewResolution.Height || p.Particle.Position.X == double.NaN || p.Particle.Position.Y == double.NaN || p.LifeTime > _maxLifeTime); }