/// <summary> /// The position of the third (and follwing) primary particle is determined by the PCA: /// The radius determined by the geometrical properties is computed and the /// primary particle is positioned in that distance to the existing ones. /// If that primary particle is in contact with another one but not /// overlapping with any other, it may reside there. /// </summary> /// <param name="primaryParticles"></param> /// <param name="count"></param> /// <returns></returns> public bool AddNextPrimaryParticle(List <PrimaryParticle> primaryParticles, int count, INeighborslist neighborslist) { var com = primaryParticles.GetCenterOfMass(); // compute the distance for the next primary particle to fulfill fractal dimension var ppDistance = GetNextPrimaryParticleDistance(primaryParticles); // get a new primary particle without any position yet. var particle = InitializeNewPrimaryParticle(_psd.GetRandomSize()); var found = false; var rndPosition = new Vector3(); while (!found) { // get a new random position on the sphere of allowed positions rndPosition = ParticleFormationUtil.GetRandomPosition(_rndGen, ppDistance) + com; // check if that position is valid found = IsPrimaryParticlePositionValid(particle, rndPosition, neighborslist, primaryParticles, _config); if (count > _config.MaxAttemptsPerCluster) { _logger.Debug("Resetting cluster generation. Time limit exceeded."); return(false); } count++; } particle.MoveTo(rndPosition); primaryParticles.Add(particle); neighborslist.AddParticlesToNeighborsList(particle); return(true); }
/// <summary> /// The second primary particle position is determined by its and the radius of the initial primary particle /// </summary> /// <param name="primaryParticles"></param> public void SetSecondPrimaryParticle(List <PrimaryParticle> primaryParticles) { var radius = _psd.GetRandomSize(); // Distance of the CenterOfMass (com) of the second pp from the com // of the first pp var particle = new PrimaryParticle(0, radius); // Position the second primary particle directly in contact with the first var ppDistance = _config.Epsilon * (primaryParticles[0].Radius + particle.Radius); // Get any random position withon that distance var rndPosition = ParticleFormationUtil.GetRandomPosition(_rndGen, ppDistance); particle.MoveTo(rndPosition); primaryParticles.Add(particle); }
private bool IsRandomPositionValid( Cluster nextCluster, List <Cluster> depositedCluster, Random rndGen, double distance, INeighborslist neighborslist) { bool found; // Get a new random position for the COM on the sphere around the deposited cluster var rndPosition = ParticleFormationUtil.GetRandomPosition(rndGen, distance); // Move the cluster to that position on the sphere nextCluster.MoveTo(rndPosition); // Check if that random position is valid (no overlap, but connection between nextCluster an the deposited cluster) found = IsClusterPositionValid(nextCluster, neighborslist, depositedCluster); return(found); }