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); } }
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); } } }
internal void GenerateInfiniteNeighbousr() { #if DEBUG int expectedNeighbours = (simplice.Rank + 1); int toCreate = expectedNeighbours - this.simplice.facets.Length; #endif //this.simplice.CreateFacetsToCompleteDimension(); foreach (var fn in this.simplice.facets.Where(f => !f.FullyInitialized)) { //why infinite neibhours only one facet? //I think it's true for 1,2 and 3D var newInfiniteVornoiNeigbour = new BowyerVoronoiVertex(this.dimensionality, fn.nucleis, null); //initialize this facet fn.External = newInfiniteVornoiNeigbour; //initialize the other facet newInfiniteVornoiNeigbour.simplice.UpdateFace(fn); /*if (fac.IsConvexHullFacet >= 1) * this.AddNeighbour(new BowyerVoronoiVertex(this.dimensionality, fac.Vertexes.Cast<BowyerNuclei>().ToArray())); * else if(fac.IsConvexHullFacet==2) * { * this.AddNeighbour(new BowyerVoronoiVertex(this.dimensionality, fac.Vertexes.Cast<BowyerNuclei>().ToArray())); * }*/ } }
public IVoronoiRegion AddNewPoint(object data, double[] newPoint) { if (newPoint == null || newPoint.Length != ProblemDimensionality) { throw new ArgumentException("point added null or has invalid dimensionality"); } BowyerNuclei newNuclei = new BowyerNuclei(newPoint); newNuclei.Data = data; //SPECIAL CASE FOR FIRST ADD if (!voronoiVertexes.Any()) { //no voronoiVertexes //no simplices //no regions BowyerNuclei[] nucleis = new BowyerNuclei[1]; newNuclei = nucleis[0] = new BowyerNuclei(newPoint); newNuclei.Data = data; //create a VoronoiVertex in the infinite var voronoiVertex = new BowyerVoronoiVertex(0, nucleis, new HyperSphereConstraint(newNuclei.Coordinates, double.PositiveInfinity)); this.voronoiVertexes.Add(voronoiVertex); this.nucleis.Add(newNuclei); //create a not formed Simplice return(voronoiVertexes.First().Simplice.Nucleis.First().VoronoiHyperRegion); } else { //--------------- SITUATION ANALYSIS - READ ONLY-------------- #warning optimizable: not variable list without cast, external auxiliar attribute List <BowyerVoronoiVertex> affectedVertexes = new List <BowyerVoronoiVertex>(); #warning optimizable: not variable list without cast, external auxiliar attribute List <BowyerNuclei> affectedNucleis = new List <BowyerNuclei>(); IEnumerable <INuclei> newpointSet = new INuclei[] { newNuclei }; #warning optimizable: cant be this an auxiliar attribute? var secondaryAffecteVertexes = new List <BowyerSimpliceFacet>(); if (nucleisRank < ProblemDimensionality && Helpers.CalculatePointsRank(Simplices.First().Nucleis.Union(newpointSet)) > nucleisRank) { affectedVertexes = this.voronoiVertexes; nucleisRank++; foreach (var v in affectedVertexes) { v.IsTrash = true; } #warning optimize, eliminate the cast and create a nuclei List affectedNucleis.AddRange(this.Nucleis.Cast <BowyerNuclei>()); } else { IVoronoiRegion r = GetMatchingRegion(newPoint); // and use r.Vertexes foreach (BowyerVoronoiVertex v in r.Vertexes) { if (v.Simplice.CircumsphereContains(newPoint)) { if (!affectedVertexes.Contains(v)) { affectedVertexes.Add(v); v.IsTrash = true; foreach (var affectedNuclei in v.simplice.nucleis) { if (!affectedNucleis.Contains(affectedNuclei)) { affectedNucleis.Add(affectedNuclei); } } } foreach (var vaffected in v.simplice.facets.Where(f => f.External.Infinity).Select(f => (BowyerVoronoiVertex)f.External)) { if (!affectedVertexes.Contains(vaffected)) { affectedVertexes.Add(vaffected); vaffected.IsTrash = true; } } foreach (var otherAffectedFace in v.simplice.facets.Where(f => !f.External.Infinity)) { if (!affectedVertexes.Contains((BowyerVoronoiVertex)otherAffectedFace.External) && !secondaryAffecteVertexes.Contains(otherAffectedFace)) { secondaryAffecteVertexes.Add(otherAffectedFace); } } //add also all the infinite vertexes if it or neighbours who contains it //foreach (var vneigh2 in v.simplice.facets // .Where(f => !affectedVertexes.Contains((BowyerVoronoiVertex)f.External) // && (f.External.Infinity // || f.External.Simplice.CircumsphereContains(newPoint))) // .Select(f => (BowyerVoronoiVertex)f.External)) //{ // vneigh2.IsTrash = true; // affectedVertexes.Add(vneigh2); //} } } } //if (!affectedVertexes.Any()) //{ // //if no normal simplices contains the new point // //we will to try it in infinite vertexs of this region // foreach (BowyerVoronoiVertex v in r.Vertexes.Where(v => v.Infinity)) // if (v.Simplice.CircumsphereContains(newPoint)) // { // affectedVertexes.Add(v); // v.IsTrash = true; // affectedNucleis.AddRange(v.simplice.nucleis); // //add to affected vertexes also the only neighbour vertex of // //the current infinite vertex // BowyerVoronoiVertex vnormal = (BowyerVoronoiVertex)v.simplice.facets.Single().External; // secondaryAffecteVertexes.Add(vnormal); // //vnormal.IsTrash = true; // //affectedVertexes.Add(vnormal); // ////add also all the infinite vertexes if it or neighbours who contains it // //foreach (var vneigh2 in vnormal.simplice.facets.Select(f => (BowyerVoronoiVertex)f.External) // // .Where(v2 => v2 != v && !affectedVertexes.Contains(v2) // // && (v2.Infinity || v2.simplice.CircumsphereContains(newPoint)))) // //{ // // vneigh2.IsTrash = true; // // affectedVertexes.Add(vneigh2); // //} // } // } // } #if DEBUG Debug.Print(string.Format("{0} ||| adding new point. Affected vertexes: {1}. Secondary Affected vertexes: {2}", this.ToString(), affectedVertexes.Count, secondaryAffecteVertexes.Count)); if (!affectedVertexes.Any()) { throw new ArgumentException("this case is not possible and has not been contemplated"); } if (affectedVertexes.Distinct().Count() != affectedVertexes.Count) { throw new ArgumentException("Incoherence in the algorithm"); } if (affectedNucleis.Distinct().Count() != affectedNucleis.Count) { throw new ArgumentException("Incoherence in the algorithm"); } if (secondaryAffecteVertexes.Distinct().Count() != secondaryAffecteVertexes.Count) { throw new ArgumentException("Incoherence in the algorithm"); } #endif //if any candidate vertex sismplice has the maxium dimensionality, the postgenerated tesellation will also have this maxium dimensionality //if (affectedVertexes.First().Simplice.Dimensionality == ProblemDimensionality) // nucleisRank = ProblemDimensionality; //else // nucleisRank = Helpers.CalculatePointsRank(affectedNucleisArray); //--------------------- CLEARING EXISTING DATA -------------------------------------- foreach (var f in secondaryAffecteVertexes) { ((BowyerVoronoiVertex)f.Owner).RemoveNeighbour(f); } //Removing affected voronoi vertexes //Removing affected voronoi facets in nucleis foreach (var v in affectedVertexes) { v.Dispose(); } //Removing affected simplices voronoiVertexes.RemoveAll(v => v.IsTrash); #if DEBUG if (secondaryAffecteVertexes.Any(f => f.FullyInitialized)) { throw new NotSupportedException("Incoherence in the problem"); } #endif affectedNucleis.Add(newNuclei); //--------------------- BUILDING NEW MESH -------------------------------------- //build tesellation and check some neighbourhood with secondary var generatedVertexes = BuildTesellation(affectedNucleis, secondaryAffecteVertexes, nucleisRank); this.nucleis.Add(newNuclei); return(newNuclei.VoronoiHyperRegion); } }
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 GenerateInfiniteNeighbousr() { #if DEBUG int expectedNeighbours = (simplice.Rank + 1); int toCreate = expectedNeighbours - this.simplice.facets.Length; #endif //this.simplice.CreateFacetsToCompleteDimension(); foreach (var fn in this.simplice.facets.Where(f => !f.FullyInitialized)) { //why infinite neibhours only one facet? //I think it's true for 1,2 and 3D var newInfiniteVornoiNeigbour = new BowyerVoronoiVertex(this.dimensionality, fn.nucleis,null); //initialize this facet fn.External = newInfiniteVornoiNeigbour; //initialize the other facet newInfiniteVornoiNeigbour.simplice.UpdateFace(fn); /*if (fac.IsConvexHullFacet >= 1) this.AddNeighbour(new BowyerVoronoiVertex(this.dimensionality, fac.Vertexes.Cast<BowyerNuclei>().ToArray())); else if(fac.IsConvexHullFacet==2) { this.AddNeighbour(new BowyerVoronoiVertex(this.dimensionality, fac.Vertexes.Cast<BowyerNuclei>().ToArray())); }*/ } }
public IVoronoiRegion AddNewPoint(object data, double[] newPoint) { if (newPoint == null || newPoint.Length != ProblemDimensionality) throw new ArgumentException("point added null or has invalid dimensionality"); BowyerNuclei newNuclei = new BowyerNuclei(newPoint); newNuclei.Data = data; //SPECIAL CASE FOR FIRST ADD if (!voronoiVertexes.Any()) { //no voronoiVertexes //no simplices //no regions BowyerNuclei[] nucleis = new BowyerNuclei[1]; newNuclei = nucleis[0] = new BowyerNuclei(newPoint); newNuclei.Data = data; //create a VoronoiVertex in the infinite var voronoiVertex = new BowyerVoronoiVertex(0, nucleis, new HyperSphereConstraint(newNuclei.Coordinates, double.PositiveInfinity)); this.voronoiVertexes.Add(voronoiVertex); this.nucleis.Add(newNuclei); //create a not formed Simplice return voronoiVertexes.First().Simplice.Nucleis.First().VoronoiHyperRegion; } else { //--------------- SITUATION ANALYSIS - READ ONLY-------------- #warning optimizable: not variable list without cast, external auxiliar attribute List<BowyerVoronoiVertex> affectedVertexes = new List<BowyerVoronoiVertex>(); #warning optimizable: not variable list without cast, external auxiliar attribute List<BowyerNuclei> affectedNucleis = new List<BowyerNuclei>(); IEnumerable<INuclei> newpointSet = new INuclei[] { newNuclei }; #warning optimizable: cant be this an auxiliar attribute? var secondaryAffecteVertexes = new List<BowyerSimpliceFacet>(); if (nucleisRank < ProblemDimensionality && Helpers.CalculatePointsRank(Simplices.First().Nucleis.Union(newpointSet)) > nucleisRank) { affectedVertexes = this.voronoiVertexes; nucleisRank++; foreach (var v in affectedVertexes) v.IsTrash = true; #warning optimize, eliminate the cast and create a nuclei List affectedNucleis.AddRange(this.Nucleis.Cast<BowyerNuclei>()); } else { IVoronoiRegion r = GetMatchingRegion(newPoint); // and use r.Vertexes foreach (BowyerVoronoiVertex v in r.Vertexes) if (v.Simplice.CircumsphereContains(newPoint)) { if (!affectedVertexes.Contains(v)) { affectedVertexes.Add(v); v.IsTrash = true; foreach (var affectedNuclei in v.simplice.nucleis) if (!affectedNucleis.Contains(affectedNuclei)) affectedNucleis.Add(affectedNuclei); } foreach (var vaffected in v.simplice.facets.Where(f => f.External.Infinity).Select(f => (BowyerVoronoiVertex)f.External)) { if (!affectedVertexes.Contains(vaffected)) { affectedVertexes.Add(vaffected); vaffected.IsTrash = true; } } foreach (var otherAffectedFace in v.simplice.facets.Where(f => !f.External.Infinity)) { if (!affectedVertexes.Contains((BowyerVoronoiVertex)otherAffectedFace.External) && !secondaryAffecteVertexes.Contains(otherAffectedFace)) secondaryAffecteVertexes.Add(otherAffectedFace); } //add also all the infinite vertexes if it or neighbours who contains it //foreach (var vneigh2 in v.simplice.facets // .Where(f => !affectedVertexes.Contains((BowyerVoronoiVertex)f.External) // && (f.External.Infinity // || f.External.Simplice.CircumsphereContains(newPoint))) // .Select(f => (BowyerVoronoiVertex)f.External)) //{ // vneigh2.IsTrash = true; // affectedVertexes.Add(vneigh2); //} } } //if (!affectedVertexes.Any()) //{ // //if no normal simplices contains the new point // //we will to try it in infinite vertexs of this region // foreach (BowyerVoronoiVertex v in r.Vertexes.Where(v => v.Infinity)) // if (v.Simplice.CircumsphereContains(newPoint)) // { // affectedVertexes.Add(v); // v.IsTrash = true; // affectedNucleis.AddRange(v.simplice.nucleis); // //add to affected vertexes also the only neighbour vertex of // //the current infinite vertex // BowyerVoronoiVertex vnormal = (BowyerVoronoiVertex)v.simplice.facets.Single().External; // secondaryAffecteVertexes.Add(vnormal); // //vnormal.IsTrash = true; // //affectedVertexes.Add(vnormal); // ////add also all the infinite vertexes if it or neighbours who contains it // //foreach (var vneigh2 in vnormal.simplice.facets.Select(f => (BowyerVoronoiVertex)f.External) // // .Where(v2 => v2 != v && !affectedVertexes.Contains(v2) // // && (v2.Infinity || v2.simplice.CircumsphereContains(newPoint)))) // //{ // // vneigh2.IsTrash = true; // // affectedVertexes.Add(vneigh2); // //} // } // } // } #if DEBUG Debug.Print(string.Format("{0} ||| adding new point. Affected vertexes: {1}. Secondary Affected vertexes: {2}", this.ToString(), affectedVertexes.Count, secondaryAffecteVertexes.Count)); if (!affectedVertexes.Any()) throw new ArgumentException("this case is not possible and has not been contemplated"); if (affectedVertexes.Distinct().Count() != affectedVertexes.Count) throw new ArgumentException("Incoherence in the algorithm"); if (affectedNucleis.Distinct().Count() != affectedNucleis.Count) throw new ArgumentException("Incoherence in the algorithm"); if (secondaryAffecteVertexes.Distinct().Count() != secondaryAffecteVertexes.Count) throw new ArgumentException("Incoherence in the algorithm"); #endif //if any candidate vertex sismplice has the maxium dimensionality, the postgenerated tesellation will also have this maxium dimensionality //if (affectedVertexes.First().Simplice.Dimensionality == ProblemDimensionality) // nucleisRank = ProblemDimensionality; //else // nucleisRank = Helpers.CalculatePointsRank(affectedNucleisArray); //--------------------- CLEARING EXISTING DATA -------------------------------------- foreach (var f in secondaryAffecteVertexes) ((BowyerVoronoiVertex)f.Owner).RemoveNeighbour(f); //Removing affected voronoi vertexes //Removing affected voronoi facets in nucleis foreach (var v in affectedVertexes) v.Dispose(); //Removing affected simplices voronoiVertexes.RemoveAll(v => v.IsTrash); #if DEBUG if (secondaryAffecteVertexes.Any(f => f.FullyInitialized)) throw new NotSupportedException("Incoherence in the problem"); #endif affectedNucleis.Add(newNuclei); //--------------------- BUILDING NEW MESH -------------------------------------- //build tesellation and check some neighbourhood with secondary var generatedVertexes = BuildTesellation(affectedNucleis, secondaryAffecteVertexes, nucleisRank); this.nucleis.Add(newNuclei); return newNuclei.VoronoiHyperRegion; } }
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; }