private static string Description(FrameType type,
                                              CelestialBody selected)
            {
                switch (type)
                {
                case FrameType.BODY_CENTRED_NON_ROTATING:
                    return(L10N.CelestialString(
                               "#Principia_ReferenceFrameSelector_Description_BodyCentredNonRotating",
                               new[] { selected }));

                case FrameType.BARYCENTRIC_ROTATING:
                    return("DEPRECATED");

                case FrameType.BODY_CENTRED_PARENT_DIRECTION:
                    if (selected.is_root())
                    {
                        throw Log.Fatal(
                                  "Describing parent-direction rotating frame of root body");
                    }
                    else
                    {
                        return(L10N.CelestialString(
                                   "#Principia_ReferenceFrameSelector_Description_BodyCentredParentDirection",
                                   new[] { selected, selected.referenceBody }));
                    }

                case FrameType.BODY_SURFACE:
                    return(L10N.CelestialString(
                               "#Principia_ReferenceFrameSelector_Description_BodySurface",
                               new[] { selected }));

                default:
                    throw Log.Fatal("Unexpected type " + type.ToString());
                }
            }
示例#2
0
            private void RenderOrbitalElements(OrbitalElements?elements,
                                               CelestialBody primary)
            {
                LabeledField(
                    L10N.CacheFormat("#Principia_OrbitAnalyser_Elements_SiderealPeriod"),
                    elements?.sidereal_period.FormatDuration());
                LabeledField(
                    L10N.CacheFormat("#Principia_OrbitAnalyser_Elements_NodalPeriod"),
                    elements?.nodal_period.FormatDuration());
                LabeledField(
                    L10N.CacheFormat("#Principia_OrbitAnalyser_Elements_AnomalisticPeriod"),
                    elements?.anomalistic_period.FormatDuration());
                LabeledField(
                    L10N.CacheFormat("#Principia_OrbitAnalyser_Elements_SemimajorAxis"),
                    elements?.mean_semimajor_axis.FormatLengthInterval());
                LabeledField(
                    L10N.CacheFormat("#Principia_OrbitAnalyser_Elements_Eccentricity"),
                    elements?.mean_eccentricity.FormatInterval());
                LabeledField(
                    L10N.CacheFormat("#Principia_OrbitAnalyser_Elements_Inclination"),
                    elements?.mean_inclination.FormatAngleInterval());
                LabeledField(
                    L10N.CacheFormat(
                        "#Principia_OrbitAnalyser_Elements_LongitudeOfAscendingNode"),
                    elements?.mean_longitude_of_ascending_nodes.FormatAngleInterval());
                LabeledField(
                    L10N.CacheFormat("#Principia_OrbitAnalyser_Elements_NodalPrecession"),
                    elements?.nodal_precession.FormatAngularFrequency());
                string periapsis = L10N.CelestialString(
                    "#Principia_OrbitAnalyser_Elements_Periapsis",
                    new[] { primary });
                string apoapsis = L10N.CelestialString(
                    "#Principia_OrbitAnalyser_Elements_Apoapsis",
                    new[] { primary });

                LabeledField(
                    L10N.CacheFormat(
                        "#Principia_OrbitAnalyser_Elements_ArgumentOfPeriapsis",
                        periapsis),
                    elements?.mean_argument_of_periapsis.FormatAngleInterval());
                LabeledField(
                    L10N.CacheFormat(
                        "#Principia_OrbitAnalyser_Elements_MeanPeriapsisAltitude",
                        periapsis),
                    elements?.mean_periapsis_distance.FormatLengthInterval(primary.Radius));
                LabeledField(
                    L10N.CacheFormat(
                        "#Principia_OrbitAnalyser_Elements_MeanApoapsisAltitude",
                        apoapsis),
                    elements?.mean_apoapsis_distance.FormatLengthInterval(primary.Radius));
            }
 private static string TargetFrameName(Vessel target)
 {
     return(L10N.CelestialString(
                "#Principia_ReferenceFrameSelector_Name_Target",
                new [] { target.orbit.referenceBody }));
 }
示例#4
0
            private KSP.UI.Screens.Mapview.MapNode MakePoolNode()
            {
                var new_node = KSP.UI.Screens.Mapview.MapNode.Create(
                    "apsis",
                    // If we see this colour, something has gone wrong.
                    XKCDColors.Pale,
                    pixelSize: 32,
                    hoverable: true,
                    pinnable: true,
                    blocksInput: true);

                new_node.OnClick +=
                    (KSP.UI.Screens.Mapview.MapNode node, Mouse.Buttons buttons) => {
                    if (buttons == Mouse.Buttons.Left)
                    {
                        MapNodeProperties properties = properties_[node];
                        if (PlanetariumCamera.fetch.target !=
                            properties.associated_map_object)
                        {
                            PlanetariumCamera.fetch.SetTarget(
                                properties.associated_map_object);
                        }
                    }
                };
                new_node.OnUpdateVisible += (KSP.UI.Screens.Mapview.MapNode node,
                                             KSP.UI.Screens.Mapview.MapNode.IconData
                                             icon) => {
                    icon.visible = properties_[node].visible;
                    icon.color   = properties_[node].colour;
                };
                new_node.OnUpdateType += (KSP.UI.Screens.Mapview.MapNode node,
                                          KSP.UI.Screens.Mapview.MapNode.TypeData type) => {
                    MapNodeProperties properties = properties_[node];
                    type.oType = properties.object_type;
                    switch (properties.object_type)
                    {
                    case MapObject.ObjectType.PatchTransition:
                        type.pType = KSP.UI.Screens.Mapview.MapNode.PatchTransitionNodeType.
                                     Impact;
                        break;

                    case MapObject.ObjectType.ApproachIntersect:
                        type.aType = KSP.UI.Screens.Mapview.MapNode.ApproachNodeType.
                                     CloseApproachOwn;
                        break;
                    }
                };
                new_node.OnUpdateCaption += (KSP.UI.Screens.Mapview.MapNode node,
                                             KSP.UI.Screens.Mapview.MapNode.CaptionData
                                             caption) => {
                    var    properties = properties_[node];
                    string source;
                    switch (properties.source)
                    {
                    case NodeSource.FlightPlan:
                        source = L10N.CacheFormat("#Principia_MapNode_Planned");
                        break;

                    case NodeSource.Prediction:
                        source = L10N.CacheFormat("#Principia_MapNode_Predicted");
                        break;

                    default:
                        throw Log.Fatal($"Unexpected node source {properties.source}");
                    }
                    switch (properties.object_type)
                    {
                    case MapObject.ObjectType.Periapsis:
                    case MapObject.ObjectType.Apoapsis: {
                        CelestialBody celestial = properties.reference_frame.Centre();
                        Vector3d      position  = properties.world_position;
                        double        speed     = properties.velocity.magnitude;
                        caption.Header = L10N.CelestialString(
                            properties.object_type == MapObject.ObjectType.Periapsis
                  ? "#Principia_MapNode_PeriapsisHeader"
                  : "#Principia_MapNode_ApoapsisHeader",
                            new[] { celestial },
                            source,
                            celestial.GetAltitude(position).FormatN(0));
                        caption.captionLine2 =
                            L10N.CacheFormat("#Principia_MapNode_ApsisCaptionLine2",
                                             speed.FormatN(0));
                        break;
                    }

                    case MapObject.ObjectType.AscendingNode:
                    case MapObject.ObjectType.DescendingNode: {
                        string node_name =
                            properties.object_type == MapObject.ObjectType.AscendingNode
                  ? L10N.CacheFormat("#Principia_MapNode_AscendingNode")
                  : L10N.CacheFormat("#Principia_MapNode_DescendingNode");
                        string plane = properties.reference_frame.ReferencePlaneDescription();
                        caption.Header = L10N.CacheFormat("#Principia_MapNode_NodeHeader",
                                                          source,
                                                          node_name,
                                                          plane);
                        caption.captionLine2 = L10N.CacheFormat(
                            "#Principia_MapNode_NodeCaptionLine2",
                            properties.velocity.z.FormatN(0));
                        break;
                    }

                    case MapObject.ObjectType.ApproachIntersect: {
                        double separation =
                            (properties.reference_frame.target.GetWorldPos3D() -
                             properties.world_position).magnitude;
                        double speed = properties.velocity.magnitude;
                        caption.Header = L10N.CacheFormat("#Principia_MapNode_ApproachHeader",
                                                          source,
                                                          separation.FormatN(0));
                        caption.captionLine2 = L10N.CacheFormat(
                            "#Principia_MapNode_ApproachCaptionLine2",
                            speed.FormatN(0));
                        break;
                    }

                    case MapObject.ObjectType.PatchTransition: {
                        CelestialBody celestial = properties.reference_frame.Centre();
                        caption.Header = L10N.CacheFormat("#Principia_MapNode_ImpactHeader",
                                                          source,
                                                          celestial.Name());
                        caption.captionLine1 = "";
                        caption.captionLine2 = "";
                        break;
                    }
                    }
                    if (properties.object_type != MapObject.ObjectType.PatchTransition)
                    {
                        caption.captionLine1 =
                            "T" + new PrincipiaTimeSpan(
                                Planetarium.GetUniversalTime() - properties.time).
                            Format(with_leading_zeroes: false, with_seconds: true);
                    }
                };
                new_node.OnUpdatePosition += (KSP.UI.Screens.Mapview.MapNode node) =>
                                             ScaledSpace.LocalToScaledSpace(properties_[node].world_position);
                return(new_node);
            }
示例#5
0
            public static string OrbitDescription(CelestialBody primary,
                                                  OrbitalElements?elements,
                                                  OrbitRecurrence?recurrence,
                                                  OrbitGroundTrack?ground_track,
                                                  int?nodal_revolutions)
            {
                if (!elements.HasValue)
                {
                    return(null);
                }
                string properties = "";
                bool   circular   = false;
                bool   equatorial = false;

                if (elements.Value.mean_eccentricity.max < 0.01)
                {
                    circular    = true;
                    properties +=
                        L10N.CacheFormat(
                            "#Principia_OrbitAnalyser_OrbitDescription_Circular");
                }
                else if (elements.Value.mean_eccentricity.min > 0.5)
                {
                    circular    = true;
                    properties +=
                        L10N.CacheFormat(
                            "#Principia_OrbitAnalyser_OrbitDescription_HighlyElliptical");
                }
                const double degree = Math.PI / 180;

                if (elements.Value.mean_inclination.max < 5 * degree ||
                    elements.Value.mean_inclination.min > 175 * degree)
                {
                    equatorial  = true;
                    properties +=
                        L10N.CacheFormat(
                            "#Principia_OrbitAnalyser_OrbitDescription_Equatorial");
                }
                else if (elements.Value.mean_inclination.min > 80 * degree &&
                         elements.Value.mean_inclination.max < 100 * degree)
                {
                    properties +=
                        L10N.CacheFormat("#Principia_OrbitAnalyser_OrbitDescription_Polar");
                }
                else if (elements.Value.mean_inclination.min > 90 * degree)
                {
                    properties +=
                        L10N.CacheFormat(
                            "#Principia_OrbitAnalyser_OrbitDescription_Retrograde");
                }
                if (recurrence.HasValue && ground_track.HasValue)
                {
                    Interval ascending_longitudes = ground_track.Value.equatorial_crossings.
                                                    longitudes_reduced_to_ascending_pass;
                    Interval descending_longitudes = ground_track.Value.equatorial_crossings.
                                                     longitudes_reduced_to_descending_pass;
                    double drift = Math.Max(
                        ascending_longitudes.max - ascending_longitudes.min,
                        descending_longitudes.max - descending_longitudes.min);
                    double revolutions_per_day =
                        (double)recurrence.Value.number_of_revolutions / recurrence.Value.cto;
                    double days = nodal_revolutions.Value / revolutions_per_day;
                    // We ignore 0 drift as it means that there was only one pass, which is
                    // insufficient to assess synchronicity.
                    if (drift > 0 && drift / days < 0.1 * degree)
                    {
                        if (recurrence.Value.cto == 1)
                        {
                            switch (recurrence.Value.nuo)
                            {
                            case 1:
                                if (circular && equatorial)
                                {
                                    var stationary_string = L10N.CelestialStringOrNull(
                                        "#Principia_OrbitAnalyser_OrbitDescription_Stationary",
                                        new[] { primary });
                                    if (stationary_string != null)
                                    {
                                        return(stationary_string);
                                    }
                                    properties = L10N.CacheFormat(
                                        "#Principia_OrbitAnalyser_OrbitDescription_Stationary");
                                }
                                else
                                {
                                    var synchronous_string = L10N.CelestialStringOrNull(
                                        "#Principia_OrbitAnalyser_OrbitDescription_Synchronous",
                                        new[] { primary },
                                        properties);
                                    if (synchronous_string != null)
                                    {
                                        return(synchronous_string);
                                    }
                                    properties += L10N.CacheFormat(
                                        "#Principia_OrbitAnalyser_OrbitDescription_Synchronous");
                                }
                                break;

                            case 2:
                                properties += L10N.CacheFormat(
                                    "#Principia_OrbitAnalyser_OrbitDescription_Semisynchronous");
                                break;

                            default:
                                break;
                            }
                        }
                    }
                }
                return(L10N.CelestialString("#Principia_OrbitAnalyser_OrbitDescription",
                                            new[] { primary },
                                            properties));
            }