static bool SetTargets(string key, string value, ref Vector3d r0, ref Vector3d v0, ref Vector3d rf, ref Vector3d vf, ref int rfaxes, ref int vfaxes, ref List <SolveTarget> targets, ref bool correct)
        {
            float t = -1;

            if (key == "--correct")
            {
                correct = true;
            }
            else if (key == "r0")
            {
                r0 = HGUtils.ToVector3d(value);
            }
            else if (key == "v0")
            {
                v0 = HGUtils.ToVector3d(value);
            }
            else if (key == "rf")
            {
                rf     = HGUtils.ToVector3d(value);
                rfaxes = SolveTarget.X | SolveTarget.Y | SolveTarget.Z;
            }
            else if (key == "vf")
            {
                vf     = HGUtils.ToVector3d(value);
                vfaxes = SolveTarget.X | SolveTarget.Y | SolveTarget.Z;
            }
            // TODO: Handle : to specify time
            else if (key == "target")
            {
                SolveTarget tgt = new SolveTarget();
                tgt.r     = HGUtils.ToVector3d(value);
                tgt.raxes = SolveTarget.X | SolveTarget.Y | SolveTarget.Z;
                tgt.vaxes = 0;
                tgt.t     = t;
                targets.Add(tgt);
            }
            else
            {
                return(false);
            }
            return(true);
        }
 static bool Set(string k, string v, ref double dt, ref double maxT, ref Vector3d r0offset, ref Vector3d v0offset)
 {
     if (k == "dt")
     {
         dt = Convert.ToDouble(v);
     }
     else if (k == "maxT")
     {
         maxT = Convert.ToDouble(v);
     }
     else if (k == "r0offset")
     {
         r0offset = HGUtils.ToVector3d(v);
     }
     else if (k == "v0offset")
     {
         v0offset = HGUtils.ToVector3d(v);
     }
     else
     {
         return(false);
     }
     return(true);
 }
        static int Main(string[] mainargs)
        {
            if (mainargs.Length == 0)
            {
                System.Console.Error.WriteLine("usage: VesselSim.exe  - computes a solution given initial conditions like SolveText.exe but also simulates a vessel like running inside KSP");
                System.Console.Error.WriteLine("vessel options:  r0offset=<float>");
                System.Console.Error.WriteLine("                 v0offset=<float>");
                System.Console.Error.WriteLine("                 maxT=<float>");
                return(1);
            }
            var                solver     = new Solve();
            var                result     = new SolveResult();
            var                traj       = new Trajectory();
            var                controller = new PDController();
            bool               correct    = false;
            Vector3d           r0         = Vector3d.zero;
            Vector3d           v0         = Vector3d.zero;
            Vector3d           rf         = Vector3d.zero;
            Vector3d           vf         = Vector3d.zero;
            Vector3d           r0offset   = Vector3d.zero; // move away from compute solution at start
            Vector3d           v0offset   = Vector3d.zero;
            int                rfaxes     = 0;
            int                vfaxes     = 0;
            double             dt         = 0.1;
            double             maxT       = 0;
            List <SolveTarget> targets    = new List <SolveTarget>();

            foreach (var arg in HGUtils.ToKeyValuePairs(mainargs))
            {
                bool used = solver.Set(arg.Item1, arg.Item2);
                if (controller.Set(arg.Item1, arg.Item2))
                {
                    used = true;
                }
                if (SetTargets(arg.Item1, arg.Item2, ref r0, ref v0, ref rf, ref vf, ref rfaxes, ref vfaxes, ref targets, ref correct))
                {
                    used = true;
                }
                if (Set(arg.Item1, arg.Item2, ref dt, ref maxT, ref r0offset, ref v0offset))
                {
                    used = true;
                }
                if (!used)
                {
                    throw new System.ArgumentException("Unexpected argument: " + arg.Item1 + "=" + arg.Item2);
                    return(1);
                }
            }
            SetFinalTarget(rf, vf, rfaxes, vfaxes, ref targets);

            if (targets.Count == 0)
            {
                System.Console.Error.WriteLine("Error! You must specify targets with either target=[x,y,z], rf=[x,y,z] or vf=[x,y,z]");
                return(1);
            }

            result = MainProg.MultiPartSolve(ref solver, ref traj, r0, v0, ref targets, (float)solver.g, solver.extendTime, correct);
            if (result.isSolved())
            {
                List <string> comments = new List <string>();
                System.Console.Error.WriteLine("Writing solution to: solution.dat");
                traj.Write("solution.dat", comments);
                if (traj.T > maxT)
                {
                    maxT = traj.T;
                }
                r0 = r0 + r0offset;
                v0 = v0 + v0offset;
                Simulate(controller, ref traj, r0, v0, new Vector3d(0, -solver.g, 0), dt, maxT);
            }
            return(0);
        }