internal static ISystem GetSystemNearestTo(IEnumerable <ISystem> systems, // non database helper function Point3D currentpos, Point3D wantedpos, double maxfromcurpos, double maxfromwanted, SystemsNearestMetric routemethod) { double bestmindistance = double.MaxValue; ISystem nearestsystem = null; foreach (var s in systems) { Point3D syspos = new Point3D(s.X, s.Y, s.Z); double distancefromwantedx2 = Point3D.DistanceBetweenX2(wantedpos, syspos); // range between the wanted point and this, ^2 double distancefromcurposx2 = Point3D.DistanceBetweenX2(currentpos, syspos); // range between the wanted point and this, ^2 // ENSURE its withing the circles now if (distancefromcurposx2 <= (maxfromcurpos * maxfromcurpos) && distancefromwantedx2 <= (maxfromwanted * maxfromwanted)) { if (routemethod == SystemsNearestMetric.IterativeNearestWaypoint) { if (distancefromwantedx2 < bestmindistance) { nearestsystem = s; bestmindistance = distancefromwantedx2; } } else { Point3D interceptpoint = currentpos.InterceptPoint(wantedpos, syspos); // work out where the perp. intercept point is.. double deviation = Point3D.DistanceBetween(interceptpoint, syspos); double metric = 1E39; if (routemethod == SystemsNearestMetric.IterativeMinDevFromPath) { metric = deviation; } else if (routemethod == SystemsNearestMetric.IterativeMaximumDev100Ly) { metric = (deviation <= 100) ? distancefromwantedx2 : metric; // no need to sqrt it.. } else if (routemethod == SystemsNearestMetric.IterativeMaximumDev250Ly) { metric = (deviation <= 250) ? distancefromwantedx2 : metric; } else if (routemethod == SystemsNearestMetric.IterativeMaximumDev500Ly) { metric = (deviation <= 500) ? distancefromwantedx2 : metric; } else if (routemethod == SystemsNearestMetric.IterativeWaypointDevHalf) { metric = Math.Sqrt(distancefromwantedx2) + deviation / 2; } else { throw new ArgumentOutOfRangeException(nameof(routemethod)); } if (metric < bestmindistance) { nearestsystem = s; bestmindistance = metric; } } } } return(nearestsystem); }
private void FindBestSystem(Point3D curpos, Point3D wantedpos, double maxfromcurpos, double maxfromwanted, int routemethod, out SystemClass system, out Point3D position) { List <SystemClass> systems = SystemData.SystemList; double maxfromcurposx2 = maxfromcurpos * maxfromcurpos; double maxfromwantedx2 = maxfromwanted * maxfromwanted; SystemClass nearestsystem = null; double bestmindistance = 1E39; for (int ii = 0; ii < systems.Count; ii++) { SystemClass syscheck = systems[ii]; Point3D syspos = new Point3D(syscheck.x, syscheck.y, syscheck.z); double distancefromwantedx2 = Point3D.DistanceBetweenX2(wantedpos, syspos); // range between the wanted point and this, ^2 double distancefromcurposx2 = Point3D.DistanceBetweenX2(curpos, syspos); // range between the wanted point and this, ^2 if (distancefromwantedx2 <= maxfromwantedx2 && // if within the radius of wanted distancefromcurposx2 <= maxfromcurposx2) // and within the jump range of current { if (routemethod == metric_nearestwaypoint) { if (distancefromwantedx2 < bestmindistance) { nearestsystem = syscheck; bestmindistance = distancefromwantedx2; } } else { Point3D interceptpoint = curpos.InterceptPoint(wantedpos, syspos); // work out where the perp. intercept point is.. double deviation = Point3D.DistanceBetween(interceptpoint, syspos); double metric = 1E39; if (routemethod == metric_mindevfrompath) { metric = deviation; } else if (routemethod == metric_maximum100ly) { metric = (deviation <= 100) ? distancefromwantedx2 : metric; // no need to sqrt it.. } else if (routemethod == metric_maximum250ly) { metric = (deviation <= 250) ? distancefromwantedx2 : metric; } else if (routemethod == metric_maximum500ly) { metric = (deviation <= 500) ? distancefromwantedx2 : metric; } else { metric = Math.Sqrt(distancefromwantedx2) + deviation / 2; } if (metric < bestmindistance) { nearestsystem = syscheck; bestmindistance = metric; //Console.WriteLine("System " + syscheck.name + " way " + deviation.ToString("0.0") + " metric " + metric.ToString("0.0") + " *"); } else { //Console.WriteLine("System " + syscheck.name + " way " + deviation.ToString("0.0") + " metric " + metric.ToString("0.0")); } } } } system = nearestsystem; position = null; if (system != null) { #if DEBUG Console.WriteLine("Best System " + nearestsystem.name); #endif position = new Point3D(system.x, system.y, system.z); } }
internal static ISystem GetSystemNearestTo(Point3D currentpos, Point3D wantedpos, double maxfromcurpos, double maxfromwanted, int routemethod, SQLiteConnectionSystem cn, Action <ISystem> LookedUp = null, int limitto = 1000) { using (DbCommand cmd = cn.CreateSelect("Systems s", MakeSystemQueryEDDB, where : "x >= @xc - @maxfromcurpos " + "AND x <= @xc + @maxfromcurpos " + "AND z >= @zc - @maxfromcurpos " + "AND z <= @zc + @maxfromcurpos " + "AND x >= @xw - @maxfromwanted " + "AND x <= @xw + @maxfromwanted " + "AND z >= @zw - @maxfromwanted " + "AND z <= @zw + @maxfromwanted " + "AND y >= @yc - @maxfromcurpos " + "AND y <= @yc + @maxfromcurpos " + "AND y >= @yw - @maxfromwanted " + "AND y <= @yw + @maxfromwanted ", orderby: "(s.x-@xw)*(s.x-@xw)+(s.y-@yw)*(s.y-@yw)+(s.z-@zw)*(s.z-@zw)", // orderby distance from wanted limit: limitto, joinlist: MakeSystemQueryEDDBJoinList)) { cmd.AddParameterWithValue("@xw", SystemClass.DoubleToInt(wantedpos.X)); // easier to manage with named paras cmd.AddParameterWithValue("@yw", SystemClass.DoubleToInt(wantedpos.Y)); cmd.AddParameterWithValue("@zw", SystemClass.DoubleToInt(wantedpos.Z)); cmd.AddParameterWithValue("@maxfromwanted", SystemClass.DoubleToInt(maxfromwanted)); cmd.AddParameterWithValue("@xc", SystemClass.DoubleToInt(currentpos.X)); cmd.AddParameterWithValue("@yc", SystemClass.DoubleToInt(currentpos.Y)); cmd.AddParameterWithValue("@zc", SystemClass.DoubleToInt(currentpos.Z)); cmd.AddParameterWithValue("@maxfromcurpos", SystemClass.DoubleToInt(maxfromcurpos)); //System.Diagnostics.Debug.WriteLine(cn.ExplainQueryPlanString(cmd)); double bestmindistance = double.MaxValue; SystemClass nearestsystem = null; using (DbDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { SystemClass s = MakeSystem(reader); LookedUp?.Invoke(s); // callback to say looked up Point3D syspos = new Point3D(s.X, s.Y, s.Z); double distancefromwantedx2 = Point3D.DistanceBetweenX2(wantedpos, syspos); // range between the wanted point and this, ^2 double distancefromcurposx2 = Point3D.DistanceBetweenX2(currentpos, syspos); // range between the wanted point and this, ^2 // ENSURE its withing the circles now if (distancefromcurposx2 <= (maxfromcurpos * maxfromcurpos) && distancefromwantedx2 <= (maxfromwanted * maxfromwanted)) { if (routemethod == metric_nearestwaypoint) { if (distancefromwantedx2 < bestmindistance) { nearestsystem = s; bestmindistance = distancefromwantedx2; } } else { Point3D interceptpoint = currentpos.InterceptPoint(wantedpos, syspos); // work out where the perp. intercept point is.. double deviation = Point3D.DistanceBetween(interceptpoint, syspos); double metric = 1E39; if (routemethod == metric_mindevfrompath) { metric = deviation; } else if (routemethod == metric_maximum100ly) { metric = (deviation <= 100) ? distancefromwantedx2 : metric; // no need to sqrt it.. } else if (routemethod == metric_maximum250ly) { metric = (deviation <= 250) ? distancefromwantedx2 : metric; } else if (routemethod == metric_maximum500ly) { metric = (deviation <= 500) ? distancefromwantedx2 : metric; } else if (routemethod == metric_waypointdev2) { metric = Math.Sqrt(distancefromwantedx2) + deviation / 2; } if (metric < bestmindistance) { nearestsystem = s; bestmindistance = metric; } } } } } return(nearestsystem); } }