Added ascending/descending node readouts.
Added ascending/descending node readouts.

--- a/KerbalEngineer/Extensions/OrbitExtensions.cs
+++ b/KerbalEngineer/Extensions/OrbitExtensions.cs
@@ -17,9 +17,13 @@
 //     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 // 
 
+#region Using Directives
+
 using System;
 
 using UnityEngine;
+
+#endregion
 
 namespace KerbalEngineer.Extensions
 {
@@ -43,6 +47,16 @@
             return 180.0 - orbit.argumentOfPeriapsis;
         }
 
+        public static double GetAngleToAscendingNode(this Orbit orbit)
+        {
+            return GetAngleToTrueAnomaly(orbit, GetTrueAnomalyOfAscendingNode(orbit));
+        }
+
+        public static double GetAngleToDescendingNode(this Orbit orbit)
+        {
+            return GetAngleToTrueAnomaly(orbit, GetTrueAnomalyOfDescendingNode(orbit));
+        }
+
         public static double GetTimeToAscendingNode(this Orbit orbit)
         {
             return GetTimeToTrueAnomaly(orbit, GetTrueAnomalyOfAscendingNode(orbit));
@@ -55,25 +69,22 @@
 
         public static double GetTrueAnomalyFromVector(this Orbit orbit, Vector3d vector)
         {
-            var normal = SwappedOrbitNormal(orbit);
-            var projected = Vector3d.Exclude(normal, vector);
-
-            var vectorToAn = QuaternionD.AngleAxis(-orbit.LAN, Planetarium.up) * Planetarium.right;
-            var vectorToPe = orbit.PeR * (QuaternionD.AngleAxis(orbit.argumentOfPeriapsis, normal) * vectorToAn);
-            var angleFromPe = Vector3d.Angle(vectorToPe, projected);
-
-            if (Math.Abs(Vector3d.Angle(projected, Vector3d.Cross(normal, vectorToPe))) < 90.0)
-            {
-                return angleFromPe;
-            }
-
-            return GetTimeToTrueAnomaly(orbit, 360.0 - angleFromPe);
+            return orbit.GetTrueAnomalyOfZupVector(vector) * Mathf.Rad2Deg;
         }
 
-        public static Vector3d SwappedOrbitNormal(this Orbit orbit)
+        public static double GetAngleToTrueAnomaly(this Orbit orbit, double tA)
         {
-            var normal = orbit.GetOrbitNormal();
-            return -new Vector3d(normal.x, normal.z, normal.y).normalized;
+            return (tA - orbit.trueAnomaly).ClampTo(0.0, 360.0);
+        }
+
+        public static double GetTimeToVector(this Orbit orbit, Vector3d vector)
+        {
+            return GetTimeToTrueAnomaly(orbit, GetTrueAnomalyFromVector(orbit, vector));
+        }
+
+        public static double GetAngleToVector(this Orbit orbit, Vector3d vector)
+        {
+            return GetAngleToTrueAnomaly(orbit, GetTrueAnomalyFromVector(orbit, vector));
         }
     }
 }

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/AngleToAscendingNode.cs
@@ -1,1 +1,43 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2014 CYBUTEK
+// 
+//     This program is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+// 
+//     This program is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+// 
+//     You should have received a copy of the GNU General Public License
+//     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
 
+#region Using Directives
+
+using KerbalEngineer.Extensions;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Orbital
+{
+    public class AngleToAscendingNode : ReadoutModule
+    {
+        public AngleToAscendingNode()
+        {
+            this.Name = "Angle to AN";
+            this.Category = ReadoutCategory.GetCategory("Orbital");
+            this.HelpString = string.Empty;
+            this.IsDefault = true;
+        }
+
+        public override void Draw()
+        {
+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.GetAngleToAscendingNode().ToAngle());
+        }
+    }
+}

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Orbital/AngleToDescendingNode.cs
@@ -1,1 +1,43 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2014 CYBUTEK
+// 
+//     This program is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+// 
+//     This program is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+// 
+//     You should have received a copy of the GNU General Public License
+//     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
 
+#region Using Directives
+
+using KerbalEngineer.Extensions;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Orbital
+{
+    public class AngleToDescendingNode : ReadoutModule
+    {
+        public AngleToDescendingNode()
+        {
+            this.Name = "Angle to DN";
+            this.Category = ReadoutCategory.GetCategory("Orbital");
+            this.HelpString = string.Empty;
+            this.IsDefault = true;
+        }
+
+        public override void Draw()
+        {
+            this.DrawLine(FlightGlobals.ActiveVessel.orbit.GetAngleToDescendingNode().ToAngle());
+        }
+    }
+}

--- a/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
+++ b/KerbalEngineer/Flight/Readouts/ReadoutLibrary.cs
@@ -31,11 +31,14 @@
 using KerbalEngineer.Settings;
 
 using AltitudeSeaLevel = KerbalEngineer.Flight.Readouts.Surface.AltitudeSeaLevel;
+using AngleToAscendingNode = KerbalEngineer.Flight.Readouts.Orbital.AngleToAscendingNode;
+using AngleToDescendingNode = KerbalEngineer.Flight.Readouts.Orbital.AngleToDescendingNode;
 using ApoapsisHeight = KerbalEngineer.Flight.Readouts.Orbital.ApoapsisHeight;
 using OrbitalPeriod = KerbalEngineer.Flight.Readouts.Orbital.OrbitalPeriod;
 using PeriapsisHeight = KerbalEngineer.Flight.Readouts.Orbital.PeriapsisHeight;
 using TimeToApoapsis = KerbalEngineer.Flight.Readouts.Orbital.TimeToApoapsis;
 using TimeToAscendingNode = KerbalEngineer.Flight.Readouts.Orbital.TimeToAscendingNode;
+using TimeToDescendingNode = KerbalEngineer.Flight.Readouts.Orbital.TimeToDescendingNode;
 using TimeToPeriapsis = KerbalEngineer.Flight.Readouts.Orbital.TimeToPeriapsis;
 
 #endregion
@@ -73,6 +76,8 @@
                 readouts.Add(new Inclination());
                 readouts.Add(new TimeToAscendingNode());
                 readouts.Add(new TimeToDescendingNode());
+                readouts.Add(new AngleToAscendingNode());
+                readouts.Add(new AngleToDescendingNode());
                 readouts.Add(new Eccentricity());
                 readouts.Add(new OrbitalSpeed());
                 readouts.Add(new OrbitalPeriod());
@@ -116,8 +121,9 @@
                 readouts.Add(new InterceptAngle());
                 readouts.Add(new RelativeInclination());
                 readouts.Add(new Rendezvous.TimeToAscendingNode());
-                readouts.Add(new AngleToAscendingNode());
-                readouts.Add(new AngleToDescendingNode());
+                readouts.Add(new Rendezvous.TimeToDescendingNode());
+                readouts.Add(new Rendezvous.AngleToAscendingNode());
+                readouts.Add(new Rendezvous.AngleToDescendingNode());
                 readouts.Add(new Rendezvous.AltitudeSeaLevel());
                 readouts.Add(new Rendezvous.ApoapsisHeight());
                 readouts.Add(new Rendezvous.PeriapsisHeight());

--- a/KerbalEngineer/Flight/Readouts/Rendezvous/RendezvousProcessor.cs
+++ b/KerbalEngineer/Flight/Readouts/Rendezvous/RendezvousProcessor.cs
@@ -82,6 +82,11 @@
         public static double TimeToAscendingNode { get; private set; }
 
         /// <summary>
+        ///     Gets the time it will take to reach the descending node.
+        /// </summary>
+        public static double TimeToDescendingNode { get; private set; }
+
+        /// <summary>
         ///     Gets the angle from the origin position to the ascending node.
         /// </summary>
         public static double AngleToAscendingNode { get; private set; }
@@ -148,15 +153,13 @@
                 ? FlightGlobals.ship_orbit
                 : FlightGlobals.ship_orbit.referenceBody.orbit;
 
-            this.targetPosition = this.targetOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
-            this.originPosition = this.originOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime());
-
             PhaseAngle = this.CalcCurrentPhaseAngle();
             InterceptAngle = this.CalcInterceptAngle();
             RelativeInclination = Vector3d.Angle(this.originOrbit.GetOrbitNormal(), this.targetOrbit.GetOrbitNormal());
-            TimeToAscendingNode = this.originOrbit.GetTrueAnomalyFromVector(this.GetAscendingNode());
-            AngleToAscendingNode = this.CalcAngleToAscendingNode();
-            AngleToDescendingNode = this.CalcAngleToDescendingNode();
+            TimeToAscendingNode = this.originOrbit.GetTimeToVector(this.GetAscendingNode());
+            TimeToDescendingNode = this.originOrbit.GetTimeToVector(this.GetDescendingNode());
+            AngleToAscendingNode = this.originOrbit.GetAngleToVector(this.GetAscendingNode());
+            AngleToDescendingNode =this.originOrbit.GetAngleToVector(this.GetDescendingNode());
             AltitudeSeaLevel = this.targetOrbit.altitude;
             ApoapsisHeight = this.targetOrbit.ApA;
             PeriapsisHeight = this.targetOrbit.PeA;
@@ -190,17 +193,7 @@
 
         private double CalcCurrentPhaseAngle()
         {
-            return this.CalcPhaseAngle(this.originPosition, this.targetPosition);
-        }
-
-        private double CalcPhaseAngle(Vector3d originPos, Vector3d targetPos)
-        {
-            var phaseAngle = Vector3d.Angle(targetPos, originPos);
-            if (Vector3d.Angle(Quaternion.AngleAxis(90.0f, Vector3d.forward) * originPos, targetPos) > 90.0)
-            {
-                phaseAngle = 360 - phaseAngle;
-            }
-            return (phaseAngle + 360) % 360;
+            return this.originOrbit.GetAngleToTrueAnomaly(this.targetOrbit.trueAnomaly);
         }
 
         private double CalcInterceptAngle()
@@ -222,34 +215,6 @@
             return angle;
         }
 
-        private double CalcAngleToAscendingNode()
-        {
-            var angleToNode = 0.0;
-            if (this.originOrbit.inclination < 90.0)
-            {
-                angleToNode = this.CalcPhaseAngle(this.originPosition, this.GetAscendingNode());
-            }
-            else
-            {
-                angleToNode = 360 - this.CalcPhaseAngle(this.originPosition, this.GetAscendingNode());
-            }
-            return angleToNode;
-        }
-
-        private double CalcAngleToDescendingNode()
-        {
-            var angleToNode = 0.0;
-            if (this.originOrbit.inclination < 90.0)
-            {
-                angleToNode = this.CalcPhaseAngle(this.originPosition, this.GetDescendingNode());
-            }
-            else
-            {
-                angleToNode = 360 - this.CalcPhaseAngle(this.originPosition, this.GetDescendingNode());
-            }
-            return angleToNode;
-        }
-
         private Vector3d GetAscendingNode()
         {
             return Vector3d.Cross(this.targetOrbit.GetOrbitNormal(), this.originOrbit.GetOrbitNormal());
@@ -258,19 +223,6 @@
         private Vector3d GetDescendingNode()
         {
             return Vector3d.Cross(this.originOrbit.GetOrbitNormal(), this.targetOrbit.GetOrbitNormal());
-        }
-
-        private double GetAngle(Vector3d from, Vector3d to)
-        {
-            var angle = Vector3d.Angle(from, to);
-            var direction = Vector3d.Dot(from, to);
-
-            if (direction < 0.0)
-            {
-                angle += 180.0;
-            }
-
-            return angle;
         }
 
         #endregion

--- /dev/null
+++ b/KerbalEngineer/Flight/Readouts/Rendezvous/TimeToDescendingNode.cs
@@ -1,1 +1,58 @@
+// 
+//     Kerbal Engineer Redux
+// 
+//     Copyright (C) 2014 CYBUTEK
+// 
+//     This program is free software: you can redistribute it and/or modify
+//     it under the terms of the GNU General Public License as published by
+//     the Free Software Foundation, either version 3 of the License, or
+//     (at your option) any later version.
+// 
+//     This program is distributed in the hope that it will be useful,
+//     but WITHOUT ANY WARRANTY; without even the implied warranty of
+//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//     GNU General Public License for more details.
+// 
+//     You should have received a copy of the GNU General Public License
+//     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
 
+#region Using Directives
+
+using KerbalEngineer.Extensions;
+
+#endregion
+
+namespace KerbalEngineer.Flight.Readouts.Rendezvous
+{
+    public class TimeToDescendingNode : ReadoutModule
+    {
+        public TimeToDescendingNode()
+        {
+            this.Name = "Time to DN";
+            this.Category = ReadoutCategory.GetCategory("Rendezvous");
+            this.HelpString = string.Empty;
+            this.IsDefault = true;
+        }
+
+        public override void Update()
+        {
+            RendezvousProcessor.RequestUpdate();
+        }
+
+        public override void Draw()
+        {
+            if (!RendezvousProcessor.ShowDetails)
+            {
+                return;
+            }
+
+            this.DrawLine(RendezvousProcessor.TimeToDescendingNode.ToTime());
+        }
+
+        public override void Reset()
+        {
+            FlightEngineerCore.Instance.AddUpdatable(RendezvousProcessor.Instance);
+        }
+    }
+}

--- a/KerbalEngineer/KerbalEngineer.csproj
+++ b/KerbalEngineer/KerbalEngineer.csproj
@@ -65,9 +65,12 @@
     <Compile Include="Flight\FlightEngineerPartless.cs" />
     <Compile Include="Flight\Readouts\Miscellaneous\Separator.cs" />
     <Compile Include="Flight\Readouts\Miscellaneous\GuiSizeAdjustor.cs" />
+    <Compile Include="Flight\Readouts\Orbital\AngleToDescendingNode.cs" />
+    <Compile Include="Flight\Readouts\Orbital\AngleToAscendingNode.cs" />
     <Compile Include="Flight\Readouts\Orbital\TrueAnomaly.cs" />
     <Compile Include="Flight\Readouts\Orbital\TimeToAscendingNode.cs" />
     <Compile Include="Flight\Readouts\Orbital\TimeToDescendingNode.cs" />
+    <Compile Include="Flight\Readouts\Rendezvous\TimeToDescendingNode.cs" />
     <Compile Include="Flight\Readouts\Rendezvous\TimeToAscendingNode.cs" />
     <Compile Include="Flight\Readouts\Surface\ImpactBiome.cs" />
     <Compile Include="Flight\Readouts\Surface\Slope.cs" />

--- a/Output/CHANGES.txt
+++ b/Output/CHANGES.txt
@@ -1,5 +1,6 @@
 1.0.6.0
-    Added: Time to equatorial ascending & descending nodes in the orbital display.
+    Added: Time and Angle to equatorial ascending/descending nodes in the orbital display.
+    Added: Time and Angle to relative ascending/descending nodes in the rendezvous display.
     Fixed: Updated MiniAVC to v1.0.2.1 (fixes remote check as well as other minor bugs).
 
 1.0.5.0

 Binary files a/Output/KerbalEngineer/KerbalEngineer.dll and b/Output/KerbalEngineer/KerbalEngineer.dll differ