protected override void AdjustNode(
            ManeuverNode originalNode, Maneuver original, double originalPeriod, double originalMagnitude, ManeuverNode node, double value, double splitDv)
        {
            double fraction;
            double minFraction = 0;
            double maxFraction = 1;

            double targetPeriod = value * 60;

            for(int iteration = 0; iteration < MNSSettings.Instance.splitByPeriodIterations; iteration += 1)
            {
                fraction = (minFraction + maxFraction) / 2;
                Vector3d dv = original.DeltaV * fraction;
                if(node != originalNode)
                {
                    RotateDeltaV(originalNode, node, ref dv);
                }
                node.DeltaV = dv;
                node.solver.UpdateFlightPlan();

                if(node.nextPatch.ApA > 0 && node.nextPatch.period < targetPeriod)
                    minFraction = fraction;
                else
                    maxFraction = fraction;
            }
        }
 protected override void AdjustNode(
     ManeuverNode originalNode, Maneuver original, double originalPeriod, double originalMagnitude, ManeuverNode node, double value, double splitDv)
 {
     Vector3d dv = original.DeltaV * (value / originalMagnitude);
     if(node != originalNode)
     {
         RotateDeltaV(originalNode, node, ref dv);
     }
     node.DeltaV = dv;
     node.solver.UpdateFlightPlan();
 }
        private void SplitNode(List<double> list, bool fix)
        {
            if(IsSolverAvailable() && Solver.maneuverNodes.Count > 0)
            {
                ManeuverNode originalNode = Solver.maneuverNodes[0];
                Maneuver original = new Maneuver(originalNode);
                double originalPeriod = originalNode.patch.period;
                double originalMagnitude = original.DeltaV.magnitude;

                int nodeCount = list.Count;
                double splitDv = 0;
                ManeuverNode node = originalNode;
                for(int index = 0; index < list.Count; index += 1)
                {
                    LogNode("Before " + index, node);

                    AdjustNode(originalNode, original, originalPeriod, originalMagnitude, node, list[index], splitDv);

                    LogNode("After " + index, node);

                    if(node.nextPatch.patchEndTransition == Orbit.PatchTransitionType.ESCAPE)
                    {
                        ScreenMessages.PostScreenMessage("Input values cause ejection in fewer burns than specified!", 8f, ScreenMessageStyle.UPPER_CENTER);
                        Debug.Log(string.Format("Early ejection at index {0}", index));
                        break;
                    }
                    else if(node.nextPatch.patchEndTransition == Orbit.PatchTransitionType.ENCOUNTER)
                    {
                        ScreenMessages.PostScreenMessage("Encounter detected! Unable to split the maneuver as specified!", 8f, ScreenMessageStyle.UPPER_CENTER);
                        Debug.Log(string.Format("Encounter at index {0}", index));
                        break;
                    }

                    splitDv += node.DeltaV.magnitude;
                    node = Solver.AddManeuverNode(node.UT + node.nextPatch.period);
                }
                if(supportsRepeat && repeat)
                {
                    double limit = double.Parse(repeatLimit) * 1000;
                    double value = list[list.Count - 1];
                    while(node.nextPatch.ApA < limit)
                    {
                        LogNode("Before", node);

                        AdjustNode(originalNode, original, originalPeriod, originalMagnitude, node, value, splitDv);

                        LogNode("After", node);
                        if(node.nextPatch.ApA < limit)
                        {
                            nodeCount += 1;
                            splitDv += node.DeltaV.magnitude;
                            node = Solver.AddManeuverNode(node.UT + node.nextPatch.period);
                        }
                    }
                }
                if(fix)
                {
                    // TBD
                }
                else
                {
                    Vector3d dv = original.DeltaV * ((originalMagnitude - splitDv) / originalMagnitude);
                    RotateDeltaV(originalNode, node, ref dv);
                    node.DeltaV = dv;
                    node.solver.UpdateFlightPlan();
                    LogNode("Final", node);
                    double timeDifference = node.UT - original.UT;
                    double orbitsToReverse = Math.Ceiling(timeDifference / originalPeriod);

                    DebugLog("UT: {0} time diff: {1} orbits to reverse: {2}", Planetarium.GetUniversalTime(), timeDifference, orbitsToReverse);
                    while(orbitsToReverse > 0 && original.UT - orbitsToReverse * originalPeriod < Planetarium.GetUniversalTime())
                    {
                        orbitsToReverse -= 1;
                    }
                    DebugLog("Reversing {0} orbits", orbitsToReverse);
                    if(orbitsToReverse > 0)
                    {
                        double timeToReverse = orbitsToReverse * originalPeriod;
                        for(int index = 0; index <= nodeCount; index += 1)
                        {
                            ManeuverNode mn = Solver.maneuverNodes[index];
                            Debug.Log(string.Format("Moving node {0} ({1}) back {2} from {3}", index, mn.DeltaV.magnitude, timeToReverse, mn.UT));
                            mn.UT -= timeToReverse;
                            mn.solver.UpdateFlightPlan();
                        }
                    }
                    double dt = original.UT - node.UT;
                    if(dt < 0)
                    {
                        dt = dt * -1;
                        ScreenMessages.PostScreenMessage(
                            string.Format("Final ejection will happen {0} later than originally planned", DurationToDisplayString(dt)),
                            8f, ScreenMessageStyle.UPPER_CENTER);
                    }
                    else
                    {
                        ScreenMessages.PostScreenMessage(
                            string.Format("Final ejection will happen {0} earlier than originally planned", DurationToDisplayString(dt)),
                            8f, ScreenMessageStyle.UPPER_CENTER);
                    }
                }
                Debug.Log("Done!");
            }
        }
 protected abstract void AdjustNode(
     ManeuverNode originalNode, Maneuver original, double originalPeriod, double originalMagnitude, ManeuverNode node, double value, double splitDv);
        protected override void AdjustNode(
            ManeuverNode originalNode, Maneuver original, double originalPeriod, double originalMagnitude, ManeuverNode node, double value, double splitDv)
        {
            double fraction;
            double minFraction = 0;
            double maxFraction = 1;

            IBurnCalculator calculator = GetAvailableCalculator();

            for(int iteration = 0; iteration < MNSSettings.Instance.splitByBurnTimeIterations; iteration += 1)
            {
                fraction = (minFraction + maxFraction) / 2;
                Vector3d dv = original.DeltaV * fraction;
                if(node != originalNode)
                {
                    RotateDeltaV(originalNode, node, ref dv);
                }
                node.DeltaV = dv;
                node.solver.UpdateFlightPlan();

                double burnTime = calculator.CalculateBurnTime(dv.magnitude, splitDv);

                if(node.nextPatch.ApA > 0 && burnTime < value)
                    minFraction = fraction;
                else
                    maxFraction = fraction;
            }
        }