Esempio n. 1
0
        /// <summary>
        /// This function checks all requirements to build a tessellation, basically the number of independent nodes.
        /// If they are enough this method call to the buildTesellation method.
        /// </summary>
        private bool TryBuildTesellation(INuclei[] PointsToRemake, List <ISimplice> oldSimplices)
        {
            //check enough points
            if (PointsToRemake.Length >= dimensions + 1)
            {
                //Candidate simplices will contain some old simplices
                //and some new maked up simplices
                IEnumerable <IEnumerable <INuclei> > candidateSimplicesNucleis = Helpers.Combinations(PointsToRemake, dimensions + 1);

                //the only thing we need is a combinatory function about the exploited points
                //generateCombinatorySimplicies(0,0, dimensions + 1, PointsToRemake, null, oldSimplices, candidateSimplices);

                List <ISimplice> candidateSimplices = new List <ISimplice>();

                foreach (var nucSet in candidateSimplicesNucleis)
                {
                    ISimplice existingSimplice = oldSimplices.FirstOrDefault(s => nucSet.All(n => s.Nucleis.Contains(n)));
                    if (existingSimplice != null)
                    {
                        candidateSimplices.Add(existingSimplice);
                    }
                    else
                    {
                        INuclei[] nucs = nucSet.ToArray();
                        if (Nuclei.AssertRank(nucs, dimensions))
                        {
                            candidateSimplices.Add(new Simplice(nucs));
                        }
                    }
                }

                //check enough independent points
                if (candidateSimplices.Any())
                {
                    BuildTesellationAndSetNeiborghood(candidateSimplices, PointsToRemake, oldSimplices);
                    return(true);
                }
                else
                {
                    return(false); //not enough indepndent poitns to build a tessellation in this n-dimensional world
                }
            }
            else
            {
                return(false); //not enough points to build a teselation in this n-dimensional world
            }
        }
Esempio n. 2
0
 internal int CountSharedFaces(Nuclei oldNeighbourg)
 {
     return(this.simplices.Count(s => s.Nucleis.Contains(oldNeighbourg)));
 }
Esempio n. 3
0
        /// <summary>
        /// Adds a new point to the diagram and returns the generated region.
        /// </summary>
        /// <param name="newPoint">
        /// point coordinates. Dimensions must match.
        /// A <see cref="System.Double[]"/>
        /// </param>
        /// <returns>
        /// generated region that represent the set of pooints that has newPoint as the nearest neigbourgh.
        /// A <see cref="Region"/>
        /// </returns>
        public IVoronoiRegion AddNewPoint(object data, double[] newPoint)
        {
            if (newPoint == null || newPoint.Length != dimensions)
            {
                throw new ArgumentException("point added null or has invalid dimensionality");
            }

            HyperRegion containerRegion = (HyperRegion)this.GetMatchingRegion(newPoint);
            HyperRegion newRegion       = new HyperRegion(newPoint, data);

            this.regions.Add(newRegion);

            //the very first one region
            if (containerRegion == null)
            {
                ((Nuclei)newRegion.Nuclei).BelongConvexHull = true;
            }
            //the standard case
            else
            {
                //Get all the simplices of this region and neighbourgs
                //they are candidates to contains this new point
                //after this checks and select the simplicitis of these regions
                //that contains the new point
                //this simplicitis are selected, and latter will be removed since
                //their tesellation will be refactored
                List <ISimplice> affectedSimplicies = containerRegion.NeighbourgRegions
                                                      .Union(new IVoronoiRegion[] { containerRegion })
                                                      .SelectMany(r => r.Nuclei.Simplices as IEnumerable <ISimplice>)
                                                      .Distinct()
                                                      .Where(s => ((Simplice)s).CheckIsInsideCircumSphere(newPoint))
                                                      .ToList();



                //standard case
                if (affectedSimplicies.Any())
                {
                    //we have to regenerate a chunk of the delunai map. All the points to remake belongs
                    //to a simplice that match in his hyperSphere the new point.
                    INuclei[] PointsToRemake = affectedSimplicies.Select(s => s.Nucleis as IEnumerable <INuclei>)
                                               .Aggregate((acc, nucs) => acc.Union(nucs))
                                               .Union(new INuclei[] { newRegion.Nuclei })
                                               .Distinct()
                                               .ToArray();

                    if (!TryBuildTesellation(PointsToRemake, affectedSimplicies))
                    {
                        //theoretically if it's inside of a hypersphere, at least a set of points are rank==dimensions
                        //so this never should happen
                        throw new NotImplementedException("Unexpected Derivation");
                    }
                }
                //THIRD NOT USUAL CASE:
                //
                //It should be    1- an external point of the delunai convex tesellation.
                //                2- a new point in the beginnings and the number of points are not enough to build
                //                   a simplice
                //                      2.1 Enough point to build the very first simplice but they have not enough rank
                //                     rank(existingpoints)<dims
                //                      2.2 Otherwise everyvody is neighbour and bound

                else
                {
                    //CASE 1 - External point
                    //Then try to build a tesellation with bruteForce. This point, is owner region and all his the neighbourg.

                    /*var affectedPoints = containerRegion.NeighbourgRegions
                     *                  .Union(new HyperRegion[] { containerRegion, newRegion })
                     *                  .Select(r => r.Nuclei);*/

                    var affectedPoints = this.Simplices.SelectMany(s => s.Facets.Where(f => f.IsConvexHullFacet > 0))
                                         .SelectMany(f => f.Vertexes)
                                         .Union(containerRegion.NeighbourgRegions.Select(neigh => neigh.Nuclei))
                                         .Union(new INuclei[] { containerRegion.Nuclei, newRegion.Nuclei })
                                         .Distinct();



                    INuclei[] pointsToRemake;


                    //select all the simplices related with all nucleis of the current hyperregion
                    affectedSimplicies = affectedPoints
                                         .Select(n => n.Simplices as IEnumerable <ISimplice>)
                                         .Aggregate((acc, simps) => acc.Union(simps))
                                         .Distinct()
                                         .ToList();
                    pointsToRemake = affectedSimplicies.SelectMany(s => s.Nucleis)
                                     .Union(affectedPoints).Distinct().ToArray();



                    bool achievedTesellation = TryBuildTesellation(pointsToRemake, affectedSimplicies);
                    if (achievedTesellation)
                    {
                        Debug.Print("CASE STRANGE 1");
                    }

                    //THEN CASE 2 - Beginigs and noth enough to build a simplice
                    else
                    {
                        Debug.Print("CASE STRANGE 2");
                        //this case is only usefull for firsts points when no simplicie exists
                        //and all points can't build a simplicie

                        Debug.Print("We don't like this region. Maybe super-computer requirements?");

                        foreach (var n in containerRegion.NeighbourgRegions.Select(r => r.Nuclei))
                        {
                            if (!Nuclei.AssertCoLinear(new INuclei[] { n, newRegion.Nuclei, containerRegion.Nuclei }))
                            {
                                ((Nuclei)newRegion.Nuclei).nucleiNeigbourgs.Add(n);
                                ((Nuclei)n).nucleiNeigbourgs.Add(newRegion.Nuclei);
                            }
                        }

                        //of course the new point is neigbhour of the region where it fell
                        ((Nuclei)containerRegion.Nuclei).nucleiNeigbourgs.Add(newRegion.Nuclei);
                        ((Nuclei)newRegion.Nuclei).nucleiNeigbourgs.Add(containerRegion.Nuclei);
                        ((Nuclei)newRegion.Nuclei).BelongConvexHull = true;
                    }
                }
            }
            return(newRegion);
        }
 internal int CountSharedFaces(Nuclei oldNeighbourg)
 {
     return this.simplices.Count(s => s.Nucleis.Contains(oldNeighbourg));
 }