示例#1
0
        /// <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);
        }
示例#2
0
 /// <summary>
 /// Since there is a nearby primary particle, check if the position is valid:
 /// (1) there is at least 1 contact with other primary particles
 /// (2) there are no overlaps.
 /// </summary>
 /// <param name="particle"></param>
 /// <param name="primaryParticles"></param>
 /// <param name="config"></param>
 /// <param name="neighbors"></param>
 /// <returns></returns>
 private static bool IsAnyNeighborPositionValid(
     PrimaryParticle particle,
     Vector3 setToPosition,
     IAggregateFormationConfig config,
     IEnumerable <Tuple <PrimaryParticle, double> > neighborsWithDistance)
 {
     var(isInContact, hasNoOverlap) = ParticleFormationUtil.IsAnyNeighborInContactOrOverlapping(particle, setToPosition, config, neighborsWithDistance);
     return(isInContact && hasNoOverlap);
 }
示例#3
0
        /// <summary>
        /// (1) Check for the specific primary particles if the position is valid: no overlap
        /// (2) Check if any other primary particle is in contact
        /// </summary>
        /// <param name="tree">neighborListTree</param>
        /// <param name="primaryParticle">primary particle of interest</param>
        /// <param name="otherPrimaryParticles">all other fixed primary particles</param>
        /// <param name="config"></param>
        /// <returns></returns>
        public (bool isInContact, bool hasNoOverlap) IsPrimaryParticlePositionValid(
            INeighborslist neighborslist,
            PrimaryParticle primaryParticle,
            IEnumerable <PrimaryParticle> otherPrimaryParticles)
        {
            //var neighbors = ParticleFormationUtil.GetPossibleNeighbors(primaryParticle, primaryParticle.Position, tree, otherPrimaryParticles, config);
            var searchRadius          = (primaryParticle.Radius + otherPrimaryParticles.GetMaxRadius()) * _config.Delta;
            var neighborsWithDistance = neighborslist.GetPrimaryParticlesAndDistanceWithinRadius(primaryParticle.Position, searchRadius);

            if (!neighborsWithDistance.Any())
            {
                return(isInContact : false, hasNoOverlap : true);
            }

            return(ParticleFormationUtil.IsAnyNeighborInContactOrOverlapping(primaryParticle, primaryParticle.Position, _config, neighborsWithDistance));
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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);
        }