public BowyerSimplice(HyperSphereConstraint containConstraint, int rank, BowyerVoronoiVertex voronoiVertex, BowyerNuclei[] nucleis)
        {
            this.Rank = rank;
            this.nucleis = nucleis;
            this.voronoiVertex = voronoiVertex;
            this.containConstraint = containConstraint;
            infiniteSimplice = this.Rank == nucleis.Length;

            //if(!this.InfiniteSimplice)
            foreach (var n in nucleis)
                n.AddSimplice(this);

            if (InfiniteSimplice || rank == 0)
            {
                facets = new BowyerSimpliceFacet[] { new BowyerSimpliceFacet(this.voronoiVertex, null, nucleis) };
            }
            else
            {
                facets = new BowyerSimpliceFacet[Rank + 1];
                IEnumerable<IEnumerable<BowyerNuclei>> fs = Helpers.Combinations(nucleis, rank);
                int i = 0;

                foreach (var f in fs)
                    facets[i++] = new BowyerSimpliceFacet(this.voronoiVertex, null, f);
            }
        }
Beispiel #2
0
        public BowyerSimplice(HyperSphereConstraint containConstraint, int rank, BowyerVoronoiVertex voronoiVertex, BowyerNuclei[] nucleis)
        {
            this.Rank              = rank;
            this.nucleis           = nucleis;
            this.voronoiVertex     = voronoiVertex;
            this.containConstraint = containConstraint;
            infiniteSimplice       = this.Rank == nucleis.Length;

            //if(!this.InfiniteSimplice)
            foreach (var n in nucleis)
            {
                n.AddSimplice(this);
            }

            if (InfiniteSimplice || rank == 0)
            {
                facets = new BowyerSimpliceFacet[] { new BowyerSimpliceFacet(this.voronoiVertex, null, nucleis) };
            }
            else
            {
                facets = new BowyerSimpliceFacet[Rank + 1];
                IEnumerable <IEnumerable <BowyerNuclei> > fs = Helpers.Combinations(nucleis, rank);
                int i = 0;

                foreach (var f in fs)
                {
                    facets[i++] = new BowyerSimpliceFacet(this.voronoiVertex, null, f);
                }
            }
        }
Beispiel #3
0
        /*
         * internal void CalculateVoronoiVertexCoordinates()
         * {
         *  int problemDimensionality = this.nucleis.First().Coordinates.Length;
         *  double[] voronoiVertexCoordinates = new double[problemDimensionality];
         *  if (!InfiniteSimplice && nucleis.Length >= 2)
         *  {
         *      //if (nucleis.Length == 1)
         *      //{
         *      //    voronoiVertexCoordinates = nucleis.First().Coordinates;
         *      //    this.Radious = double.PositiveInfinity;
         *      //}
         *      //else
         *      containConstraint.CalculateCentroid(nucleis.Select(n => n.Coordinates));
         *  }
         *  //in other case it is supposed that the coordinates has been precalculated
         *
         *  //else
         *  //    voronoiVertexCoordinates = Enumerable.Repeat(double.PositiveInfinity, voronoiVertexCoordinates.Length).ToArray();
         *
         *  //return voronoiVertexCoordinates;
         * }*/



        ///// <summary>
        ///// this is not symetrical. you must add in both sides individually
        ///// </summary>
        ///// <param name="s"></param>
        //private void AddNeigbourSimpliceForFacets(BowyerSimplice s)
        //{
        //    BowyerNuclei[] facetNucleis = this.nucleis.Intersect(s.nucleis).ToArray();

        //    int index = Array.IndexOf(facets, null);
        //    facets[index] = new BowyerSimpliceFacet(this.voronoiVertex, s.voronoiVertex, facetNucleis);
        //}

        //private void RemoveNeigbourSimpliceForFacets(BowyerSimplice s)
        //{
        //    bool found = false;
        //    for (int i = 0; i < facets.Length && !found; i++)
        //    {
        //        if (facets[i].External.Simplice == s)
        //        {
        //            facets[i] = null;
        //            found = true;
        //        }
        //    }
        //    if (!found)
        //        throw new ArgumentException("Invalid Simplice");
        //}

        /// <summary>
        /// returns false if it was not contained
        /// </summary>
        /// <param name="bowyerSimplice"></param>
        /// <returns></returns>
        internal bool UpdateFace(BowyerSimpliceFacet externalFacet)
        {
            BowyerSimpliceFacet facet = this.facets.SingleOrDefault(f => f.nucleis.Intersect(externalFacet.nucleis).Count() == this.Rank);

            if (facet != null)
            {
                facet.External = externalFacet.Owner;
            }

            return(facet != null);
        }
Beispiel #4
0
        /// <summary>
        /// the face can be local or external
        /// </summary>
        /// <param name="face"></param>
        internal void RemoveFacet(BowyerSimpliceFacet face)
        {
            BowyerSimpliceFacet facet;

            if (face.Owner == this.voronoiVertex)
            {
                facet = face;
            }
            else
            {
                facet = facets.Single(f => f.External == face.Owner);
            }

            facet.External = null;
        }
Beispiel #5
0
        private IEnumerable <BowyerVoronoiVertex> BuildTesellation(IEnumerable <BowyerNuclei> affectedNucleis, IEnumerable <BowyerSimpliceFacet> aloneOldFacets, int groupRank)
        {
            int previousVoronoiVertexSize = voronoiVertexes.Count;
            var newVoronoiVertexes        = Helpers.Combinations(affectedNucleis, groupRank + 1);

#warning optimizable: cant this be an reusable attribute?
            foreach (var nucleiGroup in newVoronoiVertexes)
            {
                BowyerNuclei[] nucleiGroupArray = nucleiGroup.ToArray();

                bool validSimplice = false;

                BowyerVoronoiVertex v = null;
                //if (groupRank == ProblemDimensionality)
                //{ //this is the usual case
                //    HyperSphereConstraint hyperSphereConstraint = new HyperSphereConstraint(this.ProblemDimensionality);
                //    hyperSphereConstraint.Calculate(nucleiGroupArray, ProblemDimensionality, groupRank+1);
                //    if (affectedNucleis.Except(nucleiGroupArray)
                //    .All(nuc => !hyperSphereConstraint.CircumsphereContains(nuc.Coordinates)))
                //    {
                //        validSimplice = true;
                //        v = new BowyerVoronoiVertex(groupRank, nucleiGroupArray, hyperSphereConstraint);

                //    }
                //}
                //else
                //{
                HyperSphereConstraint hyperSphereConstraint = new HyperSphereConstraint(this.ProblemDimensionality);
                v = new BowyerVoronoiVertex(groupRank, nucleiGroupArray, hyperSphereConstraint);
                hyperSphereConstraint.Calculate(nucleiGroupArray, ProblemDimensionality, groupRank + 1);

#warning this is very little optime!!!
                if (//nucleis.Except(nucleiGroupArray)
                    affectedNucleis.Except(nucleiGroupArray)
                    .All(nuc => !v.simplice.CircumsphereContains(nuc.Coordinates)))
                {
                    validSimplice = true;
                }
                else
                {
                    v.Dispose();
                }
                //}

                if (validSimplice)
                {
                    this.voronoiVertexes.Add(v);

                    //select those who share a face with the new voronoiVertex



                    //foreach (var s in stableNeighbours)
                    //{
                    //    foreach (var f in s.simplice.facets.Where(f => !f.FullyInitialized))
                    //    {
                    //        if (v.simplice.nucleis.All(n => f.nucleis.Contains(n)))
                    //        {
                    //            v.AddNeighbour(s);
                    //            s.AddNeighbour(v);
                    //        }
                    //    }
                    //}
                }
            }


            //all generated vertexes are neighbour
            IEnumerable <BowyerVoronoiVertex> generatedVertexes = voronoiVertexes.Skip(previousVoronoiVertexSize);

            IEnumerable <BowyerVoronoiVertex> createdInfiniteVoronoiVertexes = Enumerable.Empty <BowyerVoronoiVertex>();


            foreach (BowyerVoronoiVertex v in generatedVertexes)
            {
                foreach (var v2 in generatedVertexes)
                {
                    if (v != v2)
                    {
#warning 3level loop ... this shouldn't be to optime
                        foreach (var externalFacet in v2.simplice.facets.Where(f => !f.FullyInitialized))
                        {
                            BowyerSimpliceFacet thisFacet = v.simplice.facets.SingleOrDefault(f => externalFacet.nucleis.All(n => f.nucleis.Contains(n)));
                            if (thisFacet != null)
                            {
                                externalFacet.External = v;
                                v.AddNeighbour(thisFacet);
                            }
                        }
                    }
                }

                foreach (BowyerSimpliceFacet externalFacet in aloneOldFacets.Where(f => !f.FullyInitialized))
                {
                    BowyerSimpliceFacet thisFacet = v.simplice.facets.SingleOrDefault(f => externalFacet.nucleis.All(n => f.nucleis.Contains(n)));
                    if (thisFacet != null)
                    {
                        externalFacet.External = v;
                        v.AddNeighbour(thisFacet);
                    }
                }

                //this vertex need nucleisRank+1 neighbours
                if (v.simplice.facets.Count(f => f.FullyInitialized) <= groupRank)
                {
                    v.GenerateInfiniteNeighbousr();
                    //add the new created voronoi vertex neighbours
                    createdInfiniteVoronoiVertexes = createdInfiniteVoronoiVertexes.Union(v.simplice.facets.Where(f => f.External.Infinity).Select(f => (BowyerVoronoiVertex)f.External));
                }

#if DEBUG
                else if (v.simplice.facets.Any(f => !f.FullyInitialized))
                {
                    throw new NotSupportedException("This case has not been contemplated");
                }
#endif
            }

#if DEBUG
            if (aloneOldFacets.Any(f => !f.FullyInitialized))
            {
                throw new NotSupportedException("Incoherence in the problem. All old facets should be filled.");
            }
#endif

            voronoiVertexes.AddRange(createdInfiniteVoronoiVertexes);

            return(generatedVertexes);
        }
        /*
        internal void CalculateVoronoiVertexCoordinates()
        {
            int problemDimensionality = this.nucleis.First().Coordinates.Length;
            double[] voronoiVertexCoordinates = new double[problemDimensionality];
            if (!InfiniteSimplice && nucleis.Length >= 2)
            {
                //if (nucleis.Length == 1)
                //{
                //    voronoiVertexCoordinates = nucleis.First().Coordinates;
                //    this.Radious = double.PositiveInfinity;
                //}
                //else
                containConstraint.CalculateCentroid(nucleis.Select(n => n.Coordinates));
            }
            //in other case it is supposed that the coordinates has been precalculated

            //else
            //    voronoiVertexCoordinates = Enumerable.Repeat(double.PositiveInfinity, voronoiVertexCoordinates.Length).ToArray();

            //return voronoiVertexCoordinates;
        }*/
        ///// <summary>
        ///// this is not symetrical. you must add in both sides individually
        ///// </summary>
        ///// <param name="s"></param>
        //private void AddNeigbourSimpliceForFacets(BowyerSimplice s)
        //{
        //    BowyerNuclei[] facetNucleis = this.nucleis.Intersect(s.nucleis).ToArray();
        //    int index = Array.IndexOf(facets, null);
        //    facets[index] = new BowyerSimpliceFacet(this.voronoiVertex, s.voronoiVertex, facetNucleis);
        //}
        //private void RemoveNeigbourSimpliceForFacets(BowyerSimplice s)
        //{
        //    bool found = false;
        //    for (int i = 0; i < facets.Length && !found; i++)
        //    {
        //        if (facets[i].External.Simplice == s)
        //        {
        //            facets[i] = null;
        //            found = true;
        //        }
        //    }
        //    if (!found)
        //        throw new ArgumentException("Invalid Simplice");
        //}
        /// <summary>
        /// returns false if it was not contained
        /// </summary>
        /// <param name="bowyerSimplice"></param>
        /// <returns></returns>
        internal bool UpdateFace(BowyerSimpliceFacet externalFacet)
        {
            BowyerSimpliceFacet facet = this.facets.SingleOrDefault(f => f.nucleis.Intersect(externalFacet.nucleis).Count() == this.Rank);
            if(facet!=null)
                facet.External = externalFacet.Owner;

            return facet != null;
        }
        /// <summary>
        /// the face can be local or external
        /// </summary>
        /// <param name="face"></param>
        internal void RemoveFacet(BowyerSimpliceFacet face)
        {
            BowyerSimpliceFacet facet;
            if (face.Owner == this.voronoiVertex)
                facet=face;
            else
                facet= facets.Single(f => f.External == face.Owner);

            facet.External = null;
        }
 /// <summary>
 /// This is not bidirectional. You must do explicitly the two symetrics adds
 /// </summary>
 /// <param name="neighbourg"></param>
 internal void AddNeighbour(BowyerSimpliceFacet neighbourg)
 {
     this.simplice.UpdateFace(neighbourg);
 }
 /// <summary>
 /// This is not bidirectional. You must do explicitly the two symetrics removes
 /// </summary>
 internal void RemoveNeighbour(BowyerSimpliceFacet neighbourg)
 {
     this.simplice.RemoveFacet(neighbourg);
 }
Beispiel #10
0
 /// <summary>
 /// This is not bidirectional. You must do explicitly the two symetrics removes
 /// </summary>
 internal void RemoveNeighbour(BowyerSimpliceFacet neighbourg)
 {
     this.simplice.RemoveFacet(neighbourg);
 }
Beispiel #11
0
 /// <summary>
 /// This is not bidirectional. You must do explicitly the two symetrics adds
 /// </summary>
 /// <param name="neighbourg"></param>
 internal void AddNeighbour(BowyerSimpliceFacet neighbourg)
 {
     this.simplice.UpdateFace(neighbourg);
 }