예제 #1
0
            public InverseDefaultVoronoiFacet(IVoronoiFacet constraint)
            {
                if (constraint == null || !(constraint is DefaultVoronoiFacet))
                {
                    throw new ArgumentException("invalid constraint.");
                }

                decorated = constraint as DefaultVoronoiFacet;
            }
예제 #2
0
        private void CalculateConstraint()
        {
            //three possible cases, both finites, owner finite/external infnite and viceversa

            if (!Owner.Infinity && !external.Infinity)
            {
                double[] ownerPoint   = Owner.Coordinates;
                double[] foreignPoint = external.Coordinates;

                double[] coefficents = new Vector(ownerPoint.Length + 1);
                coefficents[coefficents.Length - 1] = 0;

                //calculating coefficents except the independent coefficent
                for (int i = 0; i < ownerPoint.Length; i++)
                {
                    coefficents[i] = ownerPoint[i] - foreignPoint[i];
                    //calculating the independent coefficent
                    coefficents[coefficents.Length - 1] -= coefficents[i] * ((foreignPoint[i] + ownerPoint[i]) / 2f);
                }
                this.constraint = new HyperPlaneConstraint(coefficents);
            }
            else if (External.Infinity && Owner.Infinity)
            {
                INuclei[] n = External.Simplice.Nucleis.Intersect(Owner.Simplice.Nucleis).ToArray();
                if (n.Length != 2)
                {
                    throw new NotSupportedException();
                }

                IVoronoiFacet vf          = n[0].VoronoiHyperRegion.Facets.Single(f => f.External == n[1]);
                double[]      coefficents = new Vector(Owner.Coordinates.Length + 1);
                for (int i = 0; i < Owner.Coordinates.Length; i++)
                {
                    coefficents[i] = vf[i];
                }
                this.constraint = new HyperPlaneConstraint(coefficents);
            }
            else if (External.Infinity)
            {
                if (Owner.Simplice.Nucleis.Length > 2)
                {
                    double[] middlePoint = new double[Nucleis[0].Coordinates.Length];
                    Helpers.CalculateSimpliceCentroidFromFacets(this.Nucleis, this.Rank, ref middlePoint);

                    Vector normal          = new Vector(Nucleis[0].Coordinates.Length + 1);
                    double independentTerm = 0;
                    for (int i = 0; i < Nucleis[0].Coordinates.Length; i++)
                    {
                        normal[i]        = Owner.Coordinates[i] - middlePoint[i];
                        independentTerm -= normal[i] * middlePoint[i];
                    }
                    normal[normal.Length - 1] = independentTerm;
                    this.constraint           = new HyperPlaneConstraint(normal.ToArray());
                }
                else
                {
                    //only two nucleis...is this enough general for n-dimensions?
                    //hope this is only the case base, where a voronoiVertex overlaps a voronoiFacet
                    INuclei n = External.Simplice.Nucleis.Intersect(Owner.Simplice.Nucleis).Single();

                    Vector normal          = new Vector(Nucleis[0].Coordinates.Length + 1);
                    double independentTerm = 0;
                    for (int i = 0; i < Nucleis[0].Coordinates.Length; i++)
                    {
                        normal[i]        = Owner.Coordinates[i] - n.Coordinates[i];
                        independentTerm -= normal[i] * n.Coordinates[i];
                    }
                    normal[normal.Length - 1] = independentTerm;
                    this.constraint           = new HyperPlaneConstraint(normal.ToArray());
                }
            }
            else if (Owner.Infinity)
            {
                if (External.Simplice.Nucleis.Length > 2)
                {
                    double[] middlePoint = new double[Nucleis[0].Coordinates.Length];
                    Helpers.CalculateSimpliceCentroidFromFacets(Nucleis, this.Rank, ref middlePoint);

                    Vector normal          = new Vector(Nucleis[0].Coordinates.Length + 1);
                    double independentTerm = 0;
                    for (int i = 0; i < Nucleis[0].Coordinates.Length; i++)
                    {
                        normal[i]        = middlePoint[i] - External.Coordinates[i];
                        independentTerm -= normal[i] * middlePoint[i];
                    }
                    normal[normal.Length - 1] = independentTerm;
                    this.constraint           = new HyperPlaneConstraint(normal.ToArray());
                }
                else
                {
                    //only two nucleis...is this enough general for n-dimensions?
                    //hope this is only the case base, where a voronoiVertex overlaps a voronoiFacet
                    INuclei n = External.Simplice.Nucleis.Intersect(Owner.Simplice.Nucleis).Single();

                    Vector normal          = new Vector(Nucleis[0].Coordinates.Length + 1);
                    double independentTerm = 0;
                    for (int i = 0; i < Nucleis[0].Coordinates.Length; i++)
                    {
                        normal[i]        = n.Coordinates[i] - External.Coordinates[i];
                        independentTerm -= normal[i] * n.Coordinates[i];
                    }
                    normal[normal.Length - 1] = independentTerm;
                    this.constraint           = new HyperPlaneConstraint(normal.ToArray());
                }
            }
            else //both infinities
            {
                throw new NotFiniteNumberException();
            }
        }
예제 #3
0
        /// <summary>
        /// This is a lazy calculation of the voronoi Vertex, its not calculated if it isn't required.
        /// </summary>
        internal static void CalculateSimpliceCentroidFromFacets(IEnumerable <INuclei> Nucleis, int simpliceDimensions, ref double[] vectorOut)
        {
            INuclei firstNuclei = Nucleis.First();


            int problemDimensionality = Nucleis.First().Coordinates.Length;

            IVoronoiFacet[] voronoiFacets = firstNuclei.VoronoiHyperRegion.Facets.Where(f => Nucleis.Contains(f.External)).ToArray();

            int Dof = problemDimensionality - simpliceDimensions;

            //we have facets.Length restrictions, and we have to create Dof new restrictions.
            if (simpliceDimensions == problemDimensionality)
            {
                CalculateSimpliceCentroid(Nucleis.Select(n => n.Coordinates), ref vectorOut);
            }
            else
            //we have to solve a facets.Length problem, to get the parameters of the problem.
            //ie: two facets, two ecuations. constraint with the current space formed by nucleiVectors with 2 parameters (unknowns)
            //this is a two ecuations/two unknowns problem.
            if (simpliceDimensions == 1)
            {
                IVoronoiFacet hpConstraint    = voronoiFacets[0];
                double        tCoeff          = 0;
                double        independentTerm = hpConstraint[problemDimensionality];
                Vector[]      vectors         = VectorsFromPoints(Nucleis, simpliceDimensions + 1);
                for (int i = 0; i < problemDimensionality; i++)
                {
                    tCoeff          += hpConstraint[i] * vectors[0][i];
                    independentTerm += hpConstraint[i] * firstNuclei.Coordinates[i];
                }
                double t = (-independentTerm) / tCoeff;

                //solve the system
                for (int i = 0; i < problemDimensionality; i++)
                {
                    vectorOut[i] = firstNuclei.Coordinates[i] + t * vectors[0][i];
                }
            }
            else
            {
                //parameters matrix
                Matrix   mA      = new Matrix(voronoiFacets.Length, voronoiFacets.Length);
                Vector[] vectors = VectorsFromPoints(Nucleis, simpliceDimensions + 1);
                Matrix   mb      = new Matrix(voronoiFacets.Length, 1);

                //mounting parameters matrix
                for (int row = 0; row < voronoiFacets.Length; row++)
                {
                    IVoronoiFacet hpConstraint    = voronoiFacets[row];
                    double        independentTerm = hpConstraint[problemDimensionality];
                    for (int col = 0; col < voronoiFacets.Length; col++)
                    {
                        double tCoeff_col = 0;
                        for (int j = 0; j < problemDimensionality; j++)
                        {
                            tCoeff_col      += hpConstraint[j] * vectors[col][j];
                            independentTerm += hpConstraint[j] * firstNuclei.Coordinates[j];
                        }
                        mA[row, col] = tCoeff_col;
                    }
                    mb[row, 0] = independentTerm;
                }

                //solving parameters matrix
                Matrix parametersRes = mA.Solve(mb);
                for (int i = 0; i < vectorOut.Length; i++)
                {
                    double increment = 0;
                    for (int j = 0; j < voronoiFacets.Length; j++)
                    {
                        increment = parametersRes[j, 0] * vectors[j][i];
                    }

                    vectorOut[i] = firstNuclei.Coordinates[i] + increment;
                }
            }
        }
            public InverseDefaultVoronoiFacet(IVoronoiFacet constraint)
            {
                if (constraint == null || !(constraint is DefaultVoronoiFacet))
                    throw new ArgumentException ("invalid constraint.");

                decorated = constraint as DefaultVoronoiFacet;
            }