private int BestDirection(KMeansSection section, int i, bool[] jset, bool ownHigh)
        {
            var ownDistance = Vector3.DistanceSquared(section.CurrentParticles[i].Position, section.CurrentPosition) *
                              (1f + GrowParameter * section.CurrentParticles.Count);

            var minDistance = ownDistance;

            if (ownHigh)
            {
                minDistance = 100;
            }
            var bestDirection = -1;

            for (var j = 0; j < 6; j++)
            {
                if (!jset[j])
                {
                    continue;
                }
                var localDistance =
                    Vector3.DistanceSquared(section.CurrentParticles[i].Position, section.NeighbourPositions[j]) *
                    (1f + GrowParameter * section.neighbourSizes[j]);
                if (!(localDistance < minDistance))
                {
                    continue;
                }
                bestDirection = j;
                minDistance   = localDistance;
            }
            return(bestDirection);
        }
        private bool[] GetOpenNeighbours(KMeansSection section)
        {
            var jset = new bool[6];

            for (var j = 0; j < 6; j++)
            {
                if (section.neighbourSizes[j] < maxParticles || section.neighbourSizes[j] < 2 * section.CurrentParticles.Count)
                {
                    jset[j] = true;
                }
            }
            return(jset);
        }
        private void PrepareSectionTransmission(KMeansSection section)
        {
            var jset = GetOpenNeighbours(section);
            //First keep the normal algorithm
            var i    = 0;
            var kept = 0;

            while (i < section.CurrentParticles.Count && kept < maxParticles)
            {
                kept += 1;
                var bestDirection = BestDirection(section, i, jset, false);
                if (bestDirection == -1)
                {
                    i++; continue;
                }
                kept -= 1;
                section.ToTransmit[bestDirection].Add(section.CurrentParticles[i]);
                section.CurrentParticles[i] = Particle.Null;
                i++;
            }
            //Until we have the maximum limit of particles. Now give all rest to neighbours.
            while (i < section.CurrentParticles.Count)
            {
                kept += 1;
                var bestDirection = BestDirection(section, i, jset, true);
                if (bestDirection == -1)
                {
                    i++; continue;
                }
                kept -= 1;
                section.ToTransmit[bestDirection].Add(section.CurrentParticles[i]);
                section.CurrentParticles[i] = Particle.Null;
                i++;
            }


            section.CurrentParticles = section.CurrentParticles.Where(o => !o.IsNull).ToList();
        }
Example #4
0
 private bool CalculationParticleMovementSingleDimension(float particleX, float currentX, KMeansSection section,
                                                         int dimensionIndex, float mySize, Particle currentParticle,
                                                         int i, float neighbourX, float nextNeighbourX, float growFactor, out float transScore, out int toNeighbour)
 {
     if (particleX < currentX)
     {
         if ((particleX < neighbourX) ||
             ((1f + growFactor * mySize) * (currentX - particleX) > (particleX - neighbourX) * (1f + growFactor * section.neighbourSizes[dimensionIndex])))
         {
             transScore = (1f + growFactor * mySize) * (currentX - particleX) -
                          (particleX - neighbourX) * (1f + growFactor * section.neighbourSizes[dimensionIndex]);
             toNeighbour = dimensionIndex;
             return(true);
         }
     }
     else
     {
         if ((particleX > nextNeighbourX) ||
             ((1f + growFactor * mySize) * (particleX - currentX) > (nextNeighbourX - particleX) * (1f + growFactor * section.neighbourSizes[dimensionIndex + 1])))
         {
             transScore  = ((1f + growFactor * mySize) * (particleX - currentX) - (nextNeighbourX - particleX) * (1f + growFactor * section.neighbourSizes[dimensionIndex + 1]));
             toNeighbour = dimensionIndex + 1;
             return(true);
         }
     }
     toNeighbour = -1;
     transScore  = float.MinValue;
     return(false);
 }
        private float[] calculatedSingleDimDif(Vector3 particlePosition, Vector3 sectionPosition, KMeansSection section)
        {
            var dDif = new float[6];

            dDif[0] = Math.Abs(particlePosition.X - sectionPosition.X) * (1f + GrowParameter * section.CurrentParticles.Count()) -
                      Math.Abs(particlePosition.X - section.NeighbourPositions[0].X) *
                      (1f + GrowParameter * section.neighbourSizes[0]);
            dDif[1] = Math.Abs(particlePosition.X - sectionPosition.X) * (1f + GrowParameter * section.CurrentParticles.Count()) -
                      Math.Abs(particlePosition.X - section.NeighbourPositions[1].X) *
                      (1f + GrowParameter * section.neighbourSizes[1]);

            dDif[2] = Math.Abs(particlePosition.Y - sectionPosition.Y) * (1f + GrowParameter * section.CurrentParticles.Count()) -
                      Math.Abs(particlePosition.Y - section.NeighbourPositions[2].Y) *
                      (1f + GrowParameter * section.neighbourSizes[2]);
            dDif[3] = Math.Abs(particlePosition.Y - sectionPosition.Y) * (1f + GrowParameter * section.CurrentParticles.Count()) -
                      Math.Abs(particlePosition.Y - section.NeighbourPositions[3].Y) *
                      (1f + GrowParameter * section.neighbourSizes[3]);

            dDif[4] = Math.Abs(particlePosition.Z - sectionPosition.Z) * (1f + GrowParameter * section.CurrentParticles.Count()) -
                      Math.Abs(particlePosition.Z - section.NeighbourPositions[4].Z) *
                      (1f + GrowParameter * section.neighbourSizes[4]);
            dDif[5] = Math.Abs(particlePosition.Z - sectionPosition.Z) * (1f + GrowParameter * section.CurrentParticles.Count()) -
                      Math.Abs(particlePosition.Z - section.NeighbourPositions[5].Z) *
                      (1f + GrowParameter * section.neighbourSizes[5]);
            return(dDif);
        }