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(); }
internal void Dispose() { this.external = null; this.Owner = null; this.constraint = null; }