// dists is an array of reference objects (properties x, y, z, distance) // returns an object containing the best candidate found (properties x, y, z, totalSqErr, i1, i2, i3) // i1, i2, i3 are the indexes into dists[] that were reference points for the candidate // totalSqErr is the total of the squares of the difference between the supplied distance and the calculated distance to each system in dists[] private Candidate getBestCandidate(Entry[] dists) { int i1 = 0, i2 = 1, i3 = 2, i4; Candidate bestCandidate = null; // run the trilateration for each combination of 3 reference systems in the set of systems we have distance data for // we look for the best candidate over all trilaterations based on the lowest total (squared) error in the calculated // distances to all the reference systems for (i1 = 0; i1 < dists.Length; i1++) { for (i2 = i1 + 1; i2 < dists.Length; i2++) { for (i3 = i2 + 1; i3 < dists.Length; i3++) { var candidates = getCandidates(dists, i1, i2, i3); if (candidates.Length == 2) { candidates[0].totalSqErr = 0; candidates[1].totalSqErr = 0; for (i4 = 0; i4 < dists.Length; i4++) { DistanceTest err = checkDist((Coordinate)candidates[0], dists[i4].Coordinate, dists[i4].Distance); candidates[0].totalSqErr += err.error * err.error; err = checkDist((Coordinate)candidates[1], dists[i4].Coordinate, dists[i4].Distance); candidates[1].totalSqErr += err.error * err.error; } if (bestCandidate == null || bestCandidate.totalSqErr > candidates[0].totalSqErr) { bestCandidate = candidates[0]; bestCandidate.i1 = i1; bestCandidate.i2 = i2; bestCandidate.i3 = i3; //console.log("best candidate so far: (1st) "+JSON.stringify(bestCandidate,2)); } if (bestCandidate.totalSqErr > candidates[1].totalSqErr) { bestCandidate = candidates[1]; bestCandidate.i1 = i1; bestCandidate.i2 = i2; bestCandidate.i3 = i3; //console.log("best candidate so far: (2nd) "+JSON.stringify(bestCandidate,2)); } } } } } return(bestCandidate); }
// calculates the distance between p1 and p2 and then calculates the error between the calculated distance and the supplied distance. // if dist has 3dp of precision then the calculated distance is also calculated with 3dp, otherwise 2dp are assumed // returns and object with properties (distance, error, dp) private DistanceTest checkDist(Coordinate p1, Coordinate p2, double dist) { DistanceTest ret = new DistanceTest(); ret.dp = 2; /* * if (dist.toFixed(3) === dist.toString()) { * // assume it's 3 dp if its 3 dp rounded string matches the string version * ret.dp = 3; * }*/ ret.distance = eddist(p1, p2, ret.dp); ret.error = Math.Abs(ret.distance - dist); return(ret); }
// calculates the distance between p1 and p2 and then calculates the error between the calculated distance and the supplied distance. // if dist has 3dp of precision then the calculated distance is also calculated with 3dp, otherwise 2dp are assumed // returns and object with properties (distance, error, dp) private DistanceTest checkDist(Coordinate p1, Coordinate p2, double dist) { DistanceTest ret = new DistanceTest(); ret.dp = 2; /* if (dist.toFixed(3) === dist.toString()) { // assume it's 3 dp if its 3 dp rounded string matches the string version ret.dp = 3; }*/ ret.distance = eddist(p1, p2, ret.dp); ret.error = Math.Abs(ret.distance - dist); return ret; }