Пример #1
0
 private static void drawVesselLabel(Rect maprect, SCANmap map, int num, Vessel vessel)
 {
     double lon = (vessel.longitude + 360 + 180) % 360;
     double lat = (vessel.latitude + 180 + 90) % 180;
     if(map != null) {
         lat = (map.projectLatitude(vessel.longitude, vessel.latitude) + 90) % 180;
         lon = (map.projectLongitude(vessel.longitude, vessel.latitude) + 180) % 360;
         lat = map.scaleLatitude(lat);
         lon = map.scaleLongitude(lon);
         if(lat < 0 || lon < 0 || lat > 180 || lon > 360) return;
     }
     lon = lon * maprect.width / 360f;
     lat = maprect.height - lat * maprect.height / 180f;
     string txt = num.ToString();
     if(num == 0) txt = vessel.vesselName;
     else if(num < 0) txt = "";
     Rect r = new Rect(maprect.x + (float)lon, maprect.y + (float)lat, 250f, 25f);
     Color col = Color.white;
     if(SCANcontroller.controller.colours == 1 && vessel != FlightGlobals.ActiveVessel) col = cb_skyBlue;
     if(vessel == FlightGlobals.ActiveVessel && (int)(Time.realtimeSinceStartup % 2) == 0) {
         col = cb_yellow;
     }
     int sz = 16;
     if(vessel.vesselType == VesselType.Flag) sz = 24;
     drawOrbitIcon((int)r.x, (int)r.y, orbitIconForVesselType(vessel.vesselType), col, sz, true);
     if(maprect.width < 360) return;
     r.x += 12;
     drawLabel(r, col, txt, true, true);
 }
Пример #2
0
        private static void drawOrbit(Rect maprect, SCANmap map, Vessel vessel)
        {
            if(vessel.LandedOrSplashed) return;
            bool lite = maprect.width < 400;
            Orbit o = vessel.orbit;
            startUT = Planetarium.GetUniversalTime();
            double UT = startUT;
            int steps = 100; // increase for neater lines, decrease for better speed indication
            bool ath = false;
            if(vessel.mainBody.atmosphere) {
                if(vessel.mainBody.maxAtmosphereAltitude >= vessel.altitude) {
                    ath = true;
                }
            }
            Rect r = new Rect(0, 0, 50f, 50f);
            Color col;
            // project the last and the current orbital period onto the map
            for(int i=-steps; i<steps; ++i) {
                if(i < 0) UT = startUT - (steps + i) * (o.period / steps);
                else UT = startUT + i * o.period * 1f / steps;
                if(double.IsNaN(UT)) continue;
                if(UT < o.StartUT && o.StartUT != startUT) continue;
                if(UT > o.EndUT) continue;
                if(double.IsNaN(o.getObtAtUT(UT))) continue;
                Vector3d pos = o.getPositionAtUT(UT);
                double rotation = 0;
                if(vessel.mainBody.rotates) {
                    rotation = (360 * ((UT - startUT) / vessel.mainBody.rotationPeriod)) % 360;
                }
                double alt = (vessel.mainBody.GetAltitude(pos));
                if(alt < 0) {
                    if(i < 0) {
                        i = 0;
                        continue;
                    }
                    break;
                }
                double lo = (vessel.mainBody.GetLongitude(pos) - rotation);
                double la = (vessel.mainBody.GetLatitude(pos));
                double lon = (map.projectLongitude(lo, la) + 180) % 360;
                double lat = (map.projectLatitude(lo, la) + 90) % 180;
                lat = map.scaleLatitude(lat);
                lon = map.scaleLongitude(lon);
                if(lat < 0 || lon < 0 || lat > 180 || lon > 360) continue;
                lon = lon * maprect.width / 360f;
                lat = maprect.height - lat * maprect.height / 180f;
                r.x = maprect.x + (float)lon;
                r.y = maprect.y + (float)lat;
                col = cb_skyBlue;
                if(i < 0) {
                    col = cb_orange;
                } else {
                    if(vessel.mainBody.atmosphere) {
                        if(vessel.mainBody.maxAtmosphereAltitude >= alt) {
                            if(!ath) {
                                ath = true;
                                // do something when it flips?
                            }
                            col = cb_reddishPurple;
                        }
                    }
                }
                drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.Planet, col, 8, false);
            }

            // show apoapsis and periapsis
            if(o.ApA > 0 && mapPosAtT(maprect, map, ref r, vessel, o, o.timeToAp)) {
                drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.Ap, cb_skyBlue, 32, true);
                r.x += 24;
                r.y -= 12;
                if(!lite) drawLabel(r, cb_skyBlue, o.ApA.ToString("N1"), true, true);
            }
            if(o.PeA > 0 && mapPosAtT(maprect, map, ref r, vessel, o, o.timeToPe)) {
                drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.Pe, cb_skyBlue, 32, true);
                r.x += 24;
                r.y -= 12;
                if(!lite) drawLabel(r, cb_skyBlue, o.PeA.ToString("N1"), true, true);
            }

            if(lite) return;

            // show first maneuver node
            if(vessel.patchedConicSolver.maneuverNodes.Count > 0) {
                ManeuverNode n = vessel.patchedConicSolver.maneuverNodes[0];
                if(n.patch == vessel.orbit && n.nextPatch != null && n.nextPatch.activePatch && n.UT > startUT - o.period && mapPosAtT(maprect, map, ref r, vessel, o, n.UT - startUT)) {
                    col = cb_reddishPurple;
                    if(SCANcontroller.controller.colours != 1) col = XKCDColors.PurplyPink;
                    drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.ManeuverNode, col, 32, true);
                    Orbit nuo = n.nextPatch;
                    for(int i=0; i<steps; ++i) {
                        double T = n.UT - startUT + i * nuo.period / steps;
                        if(T + startUT > nuo.EndUT) break;
                        if(mapPosAtT(maprect, map, ref r, vessel, nuo, T)) {
                            drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.Planet, col, 8, false);
                        }
                    }
                    if(nuo.patchEndTransition == Orbit.PatchTransitionType.ESCAPE) {
                        drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.Exit, col, 32, true);
                    } else if(nuo.patchEndTransition == Orbit.PatchTransitionType.ENCOUNTER) {
                        drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.Encounter, col, 32, true);
                    }
                    if(nuo.timeToAp > 0 && n.UT + nuo.timeToAp < nuo.EndUT && mapPosAtT(maprect, map, ref r, vessel, nuo, n.UT - startUT + nuo.timeToAp)) {
                        drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.Ap, col, 32, true);
                    }
                    if(nuo.timeToPe > 0 && n.UT + nuo.timeToPe < nuo.EndUT && mapPosAtT(maprect, map, ref r, vessel, nuo, n.UT - startUT + nuo.timeToPe)) {
                        drawOrbitIcon((int)r.x, (int)r.y, OrbitIcon.Pe, col, 32, true);
                    }
                }
            }

            if(o.PeA < 0) return;
            if(overlay_static == null) return;
            if(map.projection == SCANmap.MapProjection.Polar) return;

            if(eq_frame <= 0) {
                // predict equatorial crossings for the next 100 loops
                double TAAN = 360f - o.argumentOfPeriapsis;	// true anomaly at ascending node
                double TADN = (TAAN + 180) % 360;			// true anomaly at descending node
                double MAAN = meanForTrue(TAAN, o.eccentricity);
                double MADN = meanForTrue(TADN, o.eccentricity);
                double tAN = (((MAAN - o.meanAnomaly * Mathf.Rad2Deg + 360) % 360) / 360f * o.period + startUT);
                double tDN = (((MADN - o.meanAnomaly * Mathf.Rad2Deg + 360) % 360) / 360f * o.period + startUT);

                int eqh = 16;
                if(eq_an_map == null || eq_dn_map == null || eq_an_map.Length != overlay_static.width) {
                    eq_an_map = new int[overlay_static.width];
                    eq_dn_map = new int[overlay_static.width];
                }
                if(eq_map == null || eq_map.width != eq_an_map.Length) {
                    eq_map = new Texture2D(eq_an_map.Length, eqh, TextureFormat.ARGB32, false);
                }
                for(int i=0; i<eq_an_map.Length; ++i) {
                    eq_an_map[i] = 0;
                    eq_dn_map[i] = 0;
                }
                for(int i=0; i<100; ++i) {
                    double UTAN = tAN + o.period * i;
                    double UTDN = tDN + o.period * i;
                    if(double.IsNaN(UTAN) || double.IsNaN(UTDN)) continue;
                    Vector3d pAN = o.getPositionAtUT(UTAN);
                    Vector3d pDN = o.getPositionAtUT(UTDN);
                    double rotAN = 0, rotDN = 0;
                    if(vessel.mainBody.rotates) {
                        rotAN = ((360 * ((UTAN - startUT) / vessel.mainBody.rotationPeriod)) % 360);
                        rotDN = ((360 * ((UTDN - startUT) / vessel.mainBody.rotationPeriod)) % 360);
                    }
                    double loAN = vessel.mainBody.GetLongitude(pAN) - rotAN;
                    double loDN = vessel.mainBody.GetLongitude(pDN) - rotDN;
                    int lonAN = (int)(((map.projectLongitude(loAN, 0) + 180) % 360) * eq_an_map.Length / 360f);
                    int lonDN = (int)(((map.projectLongitude(loDN, 0) + 180) % 360) * eq_dn_map.Length / 360f);
                    if(lonAN >= 0 && lonAN < eq_an_map.Length) eq_an_map[lonAN] += 1;
                    if(lonDN >= 0 && lonDN < eq_dn_map.Length) eq_dn_map[lonDN] += 1;
                }
                Color[] pix = eq_map.GetPixels(0, 0, eq_an_map.Length, eqh);
                Color cAN = cb_skyBlue, cDN = cb_orange;
                for(int y = 0; y < eqh; ++y) {
                    Color lc = Color.clear;
                    for(int x = 0; x < eq_an_map.Length; ++x) {
                        Color c = Color.clear;
                        float scale = 0;
                        if(y < eqh / 2) {
                            c = cDN;
                            scale = eq_dn_map[x];
                        } else {
                            c = cAN;
                            scale = eq_an_map[x];
                        }
                        if(scale >= 1) {
                            if(y == 0 || y == eqh - 1) {
                                c = Color.black;
                            } else {
                                if(lc == Color.clear) pix[y * eq_an_map.Length + x - 1] = Color.black;
                                scale = Mathf.Clamp(scale - 1, 0, 10) / 10f;
                                c = Color.Lerp(c, Color.white, scale);
                            }
                        } else {
                            c = Color.clear;
                            if(lc != Color.clear && lc != Color.black) c = Color.black;
                        }
                        pix[y * eq_an_map.Length + x] = c;
                        lc = c;
                    }
                }
                eq_map.SetPixels(0, 0, eq_an_map.Length, eqh, pix);
                eq_map.Apply();
                eq_frame = 4;
            } else {
                eq_frame -= 1;
            }

            if(eq_map != null) {
                r.x = maprect.x;
                r.y = maprect.y + maprect.height / 2 + - eq_map.height / 2;
                r.width = eq_map.width;
                r.height = eq_map.height;
                GUI.DrawTexture(r, eq_map);
            }
        }
Пример #3
0
 private static void drawAnomalyLabel(Rect maprect, SCANmap map, SCANdata.SCANanomaly anomaly)
 {
     if(!anomaly.known) return;
     double lon = (anomaly.longitude + 360 + 180) % 360;
     double lat = (anomaly.latitude + 180 + 90) % 180;
     if(map != null) {
         lat = (map.projectLatitude(anomaly.longitude, anomaly.latitude) + 90) % 180;
         lon = (map.projectLongitude(anomaly.longitude, anomaly.latitude) + 180) % 360;
         lat = map.scaleLatitude(lat);
         lon = map.scaleLongitude(lon);
         if(lat < 0 || lon < 0 || lat > 180 || lon > 360) return;
     }
     lon = lon * maprect.width / 360f;
     lat = maprect.height - lat * maprect.height / 180f;
     string txt = SCANcontroller.controller.anomalyMarker + " " + anomaly.name;
     if(!anomaly.detail) txt = SCANcontroller.controller.anomalyMarker + " Anomaly";
     Rect r = new Rect(maprect.x + (float)lon, maprect.y + (float)lat, 250f, 25f);
     drawLabel(r, cb_yellow, txt, true, true);
 }
Пример #4
0
 private static void drawGrid(Rect maprect, SCANmap map)
 {
     int x, y;
     for(double lat=-90; lat<90; lat += 2) {
         for(double lon=-180; lon<180; lon += 2) {
             if(lat % 30 == 0 || lon % 30 == 0) {
                 x = (int)(map.mapscale * ((map.projectLongitude(lon, lat) + 180) % 360));
                 y = (int)(map.mapscale * ((map.projectLatitude(lon, lat) + 90) % 180));
                 drawDot(x, y, Color.white, overlay_static);
             }
         }
     }
 }
Пример #5
0
 private static bool mapPosAtT(Rect maprect, SCANmap map, ref Rect r, Vessel vessel, Orbit o, double dT)
 {
     double UT = startUT + dT;
     if(double.IsNaN(UT)) return false;
     try {
         if(double.IsNaN(o.getObtAtUT(UT))) return false;
         Vector3d pos = o.getPositionAtUT(UT);
         double rotation = 0;
         if(vessel.mainBody.rotates) {
             rotation = (360 * (dT / vessel.mainBody.rotationPeriod)) % 360;
         }
         double lo = (vessel.mainBody.GetLongitude(pos) - rotation);
         double la = (vessel.mainBody.GetLatitude(pos));
         double lon = (map.projectLongitude(lo, la) + 180) % 360;
         double lat = (map.projectLatitude(lo, la) + 90) % 180;
         lat = map.scaleLatitude(lat);
         lon = map.scaleLongitude(lon);
         if(lat < 0 || lon < 0 || lat > 180 || lon > 360) return false;
         lon = lon * maprect.width / 360f;
         lat = maprect.height - lat * maprect.height / 180f;
         r.x = maprect.x + (float)lon;
         r.y = maprect.y + (float)lat;
         return true;
     } catch(Exception) {
         return false;
     }
 }