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 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; }
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); }