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);
        }
Example #2
0
        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);
            }
        }