コード例 #1
0
        /// <summary>
        /// Look up the region that match point. It uses the Gradient Descendent Method.
        /// </summary>
        /// <param name="point">
        /// point that will be checked
        /// A <see cref="System.Double[]"/>
        /// </param>
        /// <returns>
        /// Region that contains point.
        /// A <see cref="Region"/>
        /// </returns>
        public IVoronoiRegion GetMatchingRegion(double[] point)
        {
            if (point == null || point.Length != ProblemDimensionality)
            {
                throw new ArgumentException("point added null or has invalid dimensionality");
            }

            /*This will be a very first approach as a not very efficent algorithm */
            if (!VoronoiRegions.Any())
            {
                return(null);
            }
            else
            {
                /*candidate region */
                IVoronoiRegion r = VoronoiRegions.First();

                bool matchAllConstraints = false;
                while (!matchAllConstraints)
                {
                    matchAllConstraints = true;
                    foreach (var regionFacet in r.Facets)
                    {
                        if (!regionFacet.semiHyperSpaceMatch(point))
                        {
                            r = regionFacet.External.VoronoiHyperRegion;
                            matchAllConstraints = false;
                            break;
                        }
                    }
                }

                return(r);
            }
        }
コード例 #2
0
        public void BasicVoronoiAddOne_RegionBasicFunctionality()
        {
            IVoronoiDelunayGraph gdv = createNewVoronoiDiagram(4);
            IVoronoiRegion       reg = gdv.AddNewPoint(new double[] { 10, 3, 45, 2 });

            Assert.IsTrue(reg.ContainsPoint(new double[] { 1, 2, 3, 4 }));
            CheckGeneralDiagramCoherence(gdv);
        }
コード例 #3
0
        public void BasicVoronoiAddTwo_BasicFunctionality()
        {
            IVoronoiDelunayGraph gdv  = createNewVoronoiDiagram(4);
            IVoronoiRegion       reg  = gdv.AddNewPoint(new double[] { 10, 3, 45, 2 });
            IVoronoiRegion       regB = gdv.AddNewPoint(new double[] { 10, 50, 45, 50 });

            double[] testingPoint = new double[] { 10, 4, 43, 0 };

            Assert.IsTrue(reg.ContainsPoint(testingPoint));
            Assert.IsFalse(regB.ContainsPoint(testingPoint));
            Assert.AreEqual(gdv.GetMatchingRegion(testingPoint), reg);
            CheckGeneralDiagramCoherence(gdv);
        }
コード例 #4
0
        public void BasicVoronoiAddOne()
        {
            IVoronoiDelunayGraph gdv = createNewVoronoiDiagram(4);
            IVoronoiRegion       reg = gdv.AddNewPoint(new double[] { 10, 3, 45, 2 });

            Assert.AreEqual(gdv.VoronoiRegions.Count(), 1);
            Assert.AreEqual(gdv.VoronoiRegions.Single(), reg);

            Assert.IsFalse(reg.NeighbourgRegions.Any());
            Assert.IsTrue(reg.Nuclei.BelongConvexHull);

            CheckGeneralDiagramCoherence(gdv);
        }
コード例 #5
0
        public void BasicVoronoiAddThree()
        {
            IVoronoiDelunayGraph gdv  = createNewVoronoiDiagram(4);
            IVoronoiRegion       reg  = gdv.AddNewPoint(new double[] { 10, 3, 45, 2 });
            IVoronoiRegion       regB = gdv.AddNewPoint(new double[] { 10, 50, 45, 50 });
            IVoronoiRegion       regC = gdv.AddNewPoint(new double[] { 10, 50, -45, -1 });

            Assert.AreEqual(gdv.VoronoiRegions.Count(), 3);

            Assert.AreEqual(gdv.Simplices.Count(s => s.Rank == 2), 1);
            Assert.IsTrue(gdv.Simplices.Single().Facets.All(f => f.semiHyperSpaceMatch(gdv.Simplices.Single().VoronoiVertex.Coordinates)));
            Assert.IsTrue(!gdv.Simplices.Any(s => s.Rank > 2));

            Assert.IsTrue(gdv.VoronoiRegions.Contains(reg));
            Assert.IsTrue(gdv.VoronoiRegions.Contains(regB));
            Assert.IsTrue(gdv.VoronoiRegions.Contains(regC));

            Assert.AreEqual(reg.NeighbourgRegions.Count(), 2);
            Assert.IsTrue(reg.IsInfiniteRegion);
            Assert.AreEqual(reg.Vertexes.Count(), 3);
            Assert.AreEqual(reg.Vertexes.Count(v => v.Infinity), 2);
            Assert.AreEqual(reg.Facets.Count(), 2);
            Assert.IsTrue(reg.Facets.All(f => f.semiHyperSpaceMatch(reg.Nuclei.Coordinates)));

            Assert.AreEqual(regB.NeighbourgRegions.Count(), 2);
            Assert.IsTrue(regB.IsInfiniteRegion);
            Assert.AreEqual(regB.Vertexes.Count(), 3);
            Assert.AreEqual(regB.Vertexes.Count(v => v.Infinity), 2);
            Assert.AreEqual(regB.Facets.Count(), 2);
            Assert.IsTrue(regB.Facets.All(f => f.semiHyperSpaceMatch(regB.Nuclei.Coordinates)));

            Assert.AreEqual(regC.NeighbourgRegions.Count(), 2);
            Assert.IsTrue(regC.IsInfiniteRegion);
            Assert.AreEqual(regC.Vertexes.Count(), 3);
            Assert.AreEqual(regC.Vertexes.Count(v => v.Infinity), 2);
            Assert.AreEqual(regC.Facets.Count(), 2);
            Assert.IsTrue(regC.Facets.All(f => f.semiHyperSpaceMatch(regC.Nuclei.Coordinates)));

            CheckGeneralDiagramCoherence(gdv);
        }
コード例 #6
0
        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);
            }
        }