Example #1
0
        public void set_data(ref BodyData data)
        {
            this.data.name = data.name;
            this.data.id = data.id;
            this.data.refBody = data.refBody;
            this.data.mass = data.mass;
            this.data.radius = data.radius;
            this.data.gravParameter = data.gravParameter;
            this.data.refGravParameter = data.refGravParameter;
            this.data.rotationPeriod = data.rotationPeriod;
            this.data.sphereOfInfluence = data.sphereOfInfluence;
            this.data.initialRotation = data.initialRotation;

            this.data.orbit.a = data.orbit.a;
            this.data.orbit.e = data.orbit.e;
            this.data.orbit.M0 = data.orbit.M0;
            this.data.orbit.period = data.orbit.period;
            this.data.orbit.t0 = data.orbit.t0;
            this.data.orbit.RefRadius = data.orbit.RefRadius;
            this.data.orbit.omega = data.orbit.omega;
            this.data.orbit.Omega = data.orbit.Omega;
            this.data.orbit.i = data.orbit.i;
        }
Example #2
0
        //---------------------------------------------------------------------
        //      Transfer dV calculation
        //---------------------------------------------------------------------
        public static void get_depatrure_manuever(CelestialBody depBody,                                                 
                                               CelestialBody craft,
                                               double t1,                                               
                                               ref DepManuever manuever)
        {
            OrbitPos depPos = new OrbitPos();

            depBody.get_position(t1, ref depPos);

            // Calculation SOI departure velocity
            Vector3D Vd = depBody.get_velocity(depPos.theta);

            Vector3D Vc = craft.get_velocity(0);

            Vector3D Vro = Vc - Vd;

            double v_ro = Vro.lenght();

            // Depatrure hyperbolic orbit calculation
            Vector3D x1 = depBody.get_cartesian_pos(depPos.theta);

            double u = 0;

            get_transfer_orientation(x1, Vro, ref manuever.orbit.i, ref manuever.orbit.Omega, ref u);

            if (manuever.orbit.i > 90.0)
            {
                manuever.orbit.i = 180.0 - manuever.orbit.i;
                manuever.orbit.Omega += 180.0;

                if (manuever.orbit.Omega > 360)
                    manuever.orbit.Omega -= 360;
            }

            // Eject dV calculation
            BodyData depData = new BodyData();

            depBody.get_data(ref depData);

            double ro = depData.sphereOfInfluence;
            double R = depData.radius;
            double mu = depData.gravParameter;
            double h = manuever.h;

            double v0 = Math.Sqrt(2 * mu * (1 / (R + h) - 1 / ro) + v_ro * v_ro);
            manuever.dv = v0 - Math.Sqrt(mu / (R + h));

            // Time of hyperbolic departure calculation
            double vk = Math.Sqrt(mu / (R + h));
            manuever.orbit.e = (v0 * v0 / vk / vk - 1);
            double p = (R + h) * (1 + manuever.orbit.e);
            double cos_theta = (p / ro - 1) / manuever.orbit.e;
            double theta = Math.Acos(cos_theta);
            manuever.orbit.a = p / (manuever.orbit.e * manuever.orbit.e - 1);
            double n = Math.Sqrt(mu / manuever.orbit.a) / manuever.orbit.a;
            double thH2 = Math.Sqrt((manuever.orbit.e - 1) / (manuever.orbit.e + 1)) * Math.Tan(theta / 2);
            double H = Math.Log((1 + thH2) / (1 - thH2));
            double M = manuever.orbit.e * Math.Sinh(H) - H;
            double dT = M / n;

            manuever.orbit.omega = (Math.Acos(1/manuever.orbit.e) - Math.PI/2) / math.RAD;

            // Low orbit wait time calculation
            double waitTime = manuever.turns * 2 * Math.PI * (R + h) / vk;

            manuever.ejectTime = t1 - dT;
            manuever.startTime = t1 - dT - waitTime;

            KCalendar.sec_to_date(manuever.ejectTime, ref manuever.ejectDate);
            KCalendar.sec_to_date(manuever.startTime, ref manuever.startDate);
        }
Example #3
0
        public void get_data(ref BodyData data)
        {
            data.name = this.data.name;
            data.id = this.data.id;
            data.refBody = this.data.refBody;
            data.mass = this.data.mass;
            data.radius = this.data.radius;
            data.gravParameter = this.data.gravParameter;
            data.refGravParameter = this.data.refGravParameter;
            data.rotationPeriod = this.data.rotationPeriod;
            data.sphereOfInfluence = this.data.sphereOfInfluence;
            data.initialRotation = this.data.initialRotation;

            data.orbit.a = this.data.orbit.a;
            data.orbit.e = this.data.orbit.e;
            data.orbit.M0 = this.data.orbit.M0;
            data.orbit.period = this.data.orbit.period;
            data.orbit.t0 = this.data.orbit.t0;
            data.orbit.RefRadius = this.data.orbit.RefRadius;
            data.orbit.omega = this.data.orbit.omega;
            data.orbit.Omega = this.data.orbit.Omega;
            data.orbit.i = this.data.orbit.i;
        }
Example #4
0
        //---------------------------------------------------------------------
        //
        //---------------------------------------------------------------------
        public static bool get_launch_params(CelestialBody depBody,
                                             ref DepManuever manuever)
        {
            BodyData depData = new BodyData();
            depBody.get_data(ref depData);
            double mu = depData.gravParameter;
            double R = depData.radius;
            double r0 = R + manuever.h;

            double vk = Math.Sqrt(mu / r0);

            double i = manuever.orbit.i * math.RAD;
            double Omega = manuever.orbit.Omega * math.RAD;

            if (i < Math.Abs(manuever.launchLat))
                return false;

            double sin_A = Math.Cos(i)/Math.Cos(manuever.launchLat);
            double A = Math.Asin(sin_A);

            double ny = -Math.Cos(A);
            double nz = sin_A;

            double D = ny * ny + nz * nz * Math.Pow(Math.Sin(manuever.launchLat), 2);
            double sin_d = -(nz * Math.Cos(Omega) * Math.Sin(manuever.launchLat) + ny * Math.Sin(Omega)) * Math.Sin(i) / D;
            double cos_d = (nz * Math.Sin(Omega) * Math.Sin(manuever.launchLat) - ny * Math.Cos(Omega)) * Math.Sin(i) / D;

            double d = math.arg(sin_d, cos_d);
            double rotAngle_ref = d - manuever.launchLon;

            double omega = 2 * Math.PI / depData.rotationPeriod;
            double rotAngle = depBody.get_rotation_angle(manuever.startTime)*math.RAD;

            double dT = 0;

            if (rotAngle >= rotAngle_ref)
            {
                dT = (rotAngle - rotAngle_ref) / omega;
            }
            else
            {
                dT = 21600 - (rotAngle_ref - rotAngle) / omega;
            }

            manuever.launchTime = manuever.startTime - dT;
            KCalendar.sec_to_date(manuever.launchTime, ref manuever.launchDate);

            // Debug
            rotAngle = depBody.get_rotation_angle(manuever.launchTime)*math.RAD;

            // Relative azimuth calculation
            double vs = omega*R*Math.Cos(manuever.launchLat);
            double sin_Ar = (vk * sin_A - vs) / Math.Sqrt(vk * vk + vs * vs - 2 * vk * vs * sin_A);

            manuever.azimuth = Math.Asin(sin_Ar) / math.RAD;

            return true;
        }
Example #5
0
        //---------------------------------------------------------------------
        //      Get transfer orbit
        //---------------------------------------------------------------------
        public static double get_transfer_orbit(double t,
                                                CelestialBody depBody,
                                                CelestialBody arrivBody,
                                                double phi, 
                                                ref Orbit orbit,
                                                ref double destLambda)
        {
            // Is bodies has same reference body
            if (depBody.get_ref_body() != arrivBody.get_ref_body())
                return -1;

            OrbitPos pos = new OrbitPos();
            EclipticPos epos = new EclipticPos();

            depBody.get_position(t, ref pos);
            depBody.get_ecliptic_coords(pos.theta, ref epos);
            destLambda = epos.lambda + Math.PI - phi;

            destLambda = math.Trunc2PiN(destLambda);

            double destTheta = get_dest_theta(arrivBody, destLambda);

            Vector3D x1 = depBody.get_cartesian_pos(pos.theta);
            Vector3D x2 = arrivBody.get_cartesian_pos(destTheta);

            double u = 0;
            get_transfer_orientation(x1, x2, ref orbit.i, ref orbit.Omega, ref u);

            double r1 = x1.lenght();
            double r2 = x2.lenght();

            orbit.omega = u / math.RAD;

            BodyData data = new BodyData();

            arrivBody.get_data(ref data);

            double transTime = 0;
            double mu = depBody.get_refGravParameter();
            double E = 0;
            double theta = 0;

            theta = x1.angle(x2);
            orbit.e = (r2 - r1) / (r1 - r2 * Math.Cos(theta));

            if ( (orbit.e > - 1) && (orbit.e < 1) )
            {
                orbit.a = r1 / (1 - orbit.e);

                double n = Math.Sqrt(mu / orbit.a) / orbit.a;
                double tgE2 = Math.Sqrt((1 - orbit.e) / (1 + orbit.e)) * Math.Tan(theta / 2);
                E = 2 * Math.Atan(tgE2);
                double M = E - orbit.e * Math.Sin(E);
                transTime = M / n;
            }

            if (orbit.e == 1)
            {
                orbit.a = 2*r1;
                transTime = r1*Math.Sqrt(2*r1/mu)*(Math.Tan(theta/2) + Math.Pow(Math.Tan(theta/2), 3)/3);
            }

            if (orbit.e > 1)
            {
                orbit.a = r1 / (orbit.e - 1);

                double n = Math.Sqrt(mu / orbit.a) / orbit.a;
                double thE2 = Math.Sqrt((orbit.e - 1) / (orbit.e + 1)) * Math.Tan(theta / 2);
                double H = Math.Log((1 + thE2) / (1 - thE2));
                double M = orbit.e * Math.Sinh(H) - H;
                transTime = M / n;
            }

            return transTime;
        }
Example #6
0
        //---------------------------------------------------------------
        //
        //---------------------------------------------------------------
        private void ReadSystemConfig(string cfg)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(cfg);

            var nodes = doc.GetElementsByTagName("Body");

            foreach (XmlNode node in nodes)
            {
                // Body data structure
                BodyData data = new BodyData();

                // Read all "Body" nodes
                foreach (XmlNode subnode in node.ChildNodes)
                {
                    // Read body parameters
                    if (subnode.Name == "name")
                    {
                        data.name = subnode.InnerText;
                    }

                    if (subnode.Name == "id")
                    {
                        data.id = int.Parse(subnode.InnerText);
                    }

                    if (subnode.Name == "RefBody")
                    {
                        data.refBody = subnode.InnerText;
                    }

                    if (subnode.Name == "mass")
                    {
                        data.mass = double.Parse(subnode.InnerText, CultureInfo.InvariantCulture);
                    }

                    if (subnode.Name == "radius")
                    {
                        data.radius = double.Parse(subnode.InnerText, CultureInfo.InvariantCulture);
                    }

                    if (subnode.Name == "gravParameter")
                    {
                        data.gravParameter = double.Parse(subnode.InnerText, CultureInfo.InvariantCulture);
                    }

                    if (subnode.Name == "rotationPeriod")
                    {
                        data.rotationPeriod = double.Parse(subnode.InnerText, CultureInfo.InvariantCulture);
                    }

                    if (subnode.Name == "sphereOfInfluence")
                    {
                        if (subnode.InnerText != "Infinity")
                            data.sphereOfInfluence = double.Parse(subnode.InnerText, CultureInfo.InvariantCulture);
                        else
                            data.sphereOfInfluence = 1e50;
                    }

                    if (subnode.Name == "initialRotation")
                    {
                        data.initialRotation = double.Parse(subnode.InnerText, CultureInfo.InvariantCulture);
                    }

                    if (subnode.Name == "Orbit")
                    {
                        data.orbit = new Orbit();

                        // Read body orbit parameters
                        foreach (XmlNode orb_param in subnode.ChildNodes)
                        {
                            if (orb_param.Name == "semiMajorAxis")
                            {
                                data.orbit.a = double.Parse(orb_param.InnerText, CultureInfo.InvariantCulture);
                            }

                            if (orb_param.Name == "eccentricity")
                            {
                                data.orbit.e = double.Parse(orb_param.InnerText, CultureInfo.InvariantCulture);
                            }

                            if (orb_param.Name == "epoch")
                            {
                                data.orbit.t0 = double.Parse(orb_param.InnerText, CultureInfo.InvariantCulture);
                            }

                            if (orb_param.Name == "meanAnomalyAtEpoch")
                            {
                                data.orbit.M0 = double.Parse(orb_param.InnerText, CultureInfo.InvariantCulture);
                            }

                            if (orb_param.Name == "period")
                            {
                                data.orbit.period = double.Parse(orb_param.InnerText, CultureInfo.InvariantCulture);
                            }

                            if (orb_param.Name == "argPe")
                            {
                                data.orbit.omega = double.Parse(orb_param.InnerText, CultureInfo.InvariantCulture);
                            }

                            if (orb_param.Name == "LAN")
                            {
                                data.orbit.Omega = double.Parse(orb_param.InnerText, CultureInfo.InvariantCulture);
                            }

                            if (orb_param.Name == "inclination")
                            {
                                data.orbit.i = double.Parse(orb_param.InnerText, CultureInfo.InvariantCulture);
                            }
                        }
                    }
                }

                CelestialBody Body = new CelestialBody();
                Body.set_data(ref data);
                Bodies.Add(Body);
            }

            // Init reference IDs and radiuses
            for (int i = 0; i < Bodies.Count; i++)
            {
                string refBody = Bodies[i].get_ref_body();
                int refId = get_body_index(refBody);

                if (refId != -1)
                {
                    Bodies[i].set_refId(refId);
                    Bodies[i].set_refRadius(Bodies[refId].get_radius());
                    Bodies[i].set_refGravParameter(Bodies[refId].get_gravParameter());
                }
            }
        }
Example #7
0
        //----------------------------------------------------------------------
        //      Get true anomaly from ecliptic position
        //      (code generated by Maple 18)
        //----------------------------------------------------------------------
        public static double get_dest_theta(CelestialBody body, double lambda)
        {
            BodyData data = new BodyData();

            body.get_data(ref data);

            double i = data.orbit.i * math.RAD;
            double Omega = data.orbit.Omega * math.RAD;

            double cos_u = sqrt(pow(cos(i), 0.2e1) * (0.2e1 * pow(cos(lambda), 0.2e1) * pow(cos(Omega), 0.2e1) -
                 0.2e1 * cos(Omega) * cos(lambda) * sin(lambda) * sin(Omega) -
                 pow(cos(lambda), 0.2e1) - pow(cos(Omega), 0.2e1) + 0.1e1) / (pow(cos(lambda), 0.4e1) * pow(cos(i), 0.2e1) +
                 0.2e1 * pow(cos(lambda), 0.2e1) * pow(cos(i), 0.2e1) * pow(cos(Omega), 0.2e1) +
                 pow(cos(i), 0.2e1) * pow(cos(Omega), 0.4e1) - pow(cos(lambda), 0.4e1) -
                 0.2e1 * pow(cos(lambda), 0.2e1) * pow(cos(i), 0.2e1) - 0.2e1 * cos(Omega) * cos(lambda) * sin(lambda) * sin(Omega) -
                 0.2e1 * pow(cos(i), 0.2e1) * pow(cos(Omega), 0.2e1) - pow(cos(Omega), 0.4e1) + pow(cos(lambda), 0.2e1) + pow(cos(i), 0.2e1) +
                 pow(cos(Omega), 0.2e1))) * (cos(lambda) * cos(Omega) + sin(lambda) * sin(Omega));

            double sin_u = -sqrt(pow(cos(i), 0.2e1) * (0.2e1 * pow(cos(lambda), 0.2e1) * pow(cos(Omega), 0.2e1) -
                   0.2e1 * cos(Omega) * cos(lambda) * sin(lambda) * sin(Omega) - pow(cos(lambda), 0.2e1) -
                   pow(cos(Omega), 0.2e1) + 0.1e1) / (pow(cos(lambda), 0.4e1) * pow(cos(i), 0.2e1) +
                   0.2e1 * pow(cos(lambda), 0.2e1) * pow(cos(i), 0.2e1) * pow(cos(Omega), 0.2e1) +
                   pow(cos(i), 0.2e1) * pow(cos(Omega), 0.4e1) - pow(cos(lambda), 0.4e1) -
                   0.2e1 * pow(cos(lambda), 0.2e1) * pow(cos(i), 0.2e1) - 0.2e1 * cos(Omega) * cos(lambda) * sin(lambda) * sin(Omega) -
                   0.2e1 * pow(cos(i), 0.2e1) * pow(cos(Omega), 0.2e1) - pow(cos(Omega), 0.4e1) +
                   pow(cos(lambda), 0.2e1) + pow(cos(i), 0.2e1) +
                   pow(cos(Omega), 0.2e1))) * (cos(lambda) * sin(Omega) - cos(Omega) * sin(lambda)) / cos(i);

            double u = math.arg(sin_u, cos_u);

            return u - data.orbit.omega*math.RAD;
        }
Example #8
0
        //------------------------------------------------------------
        //
        //------------------------------------------------------------
        private int get_body_index(string name)
        {
            int idx = 0;
            BodyData data = new BodyData();

            do
            {
                Bodies.ElementAt(idx).get_data(ref data);
                idx++;

            } while ((idx-1 <= Bodies.Count) && (data.name != name));

            if (idx-1 > Bodies.Count)
                return -1;

            return idx - 1;
        }
Example #9
0
        //---------------------------------------------------------------------
        //
        //---------------------------------------------------------------------
        void DrawTransOrbit(Panel panel, Transfer trans, 
                            CelestialBody arivBody, 
                            CelestialBody destBody, 
                            CelestialBody craft)
        {
            Graphics graph = panel.CreateGraphics();

            graph.Clear(Color.Black);

            Pen pen = new Pen(Color.LightGray, 2.0F);

            int width = panel.Width;
            int height = panel.Height;

            float x0 = width / 2;
            float y0 = height / 2;

            float x = 0;
            float y = 0;

            float x1 = 0;
            float y1 = 0;

            float x2 = 0;
            float y2 = 0;

            double scale = 0;
            int Delta = 25;

            BodyData ariv_data = new BodyData();
            BodyData dest_data = new BodyData();

            arivBody.get_data(ref ariv_data);
            destBody.get_data(ref dest_data);

            double ariv_ra = ariv_data.orbit.a / (1 - ariv_data.orbit.e);
            double dest_ra = dest_data.orbit.a / (1 - dest_data.orbit.e);

            double r_max = 0;

            if (ariv_ra > dest_ra)
                r_max = ariv_ra;
            else
                r_max = dest_ra;

            if (width > height)
            {
                scale = (height / 2 - Delta) / r_max;
            }
            else
            {
                scale = (width / 2 - Delta) / r_max;
            }

            // Arrive Body orbit
            Vector3D pos;
            OrbitPos orbit_pos = new OrbitPos();

            double V0 = 0;
            double V = V0;
            double V1 = 360.0;
            double dV = 5.0;

            while (V <= V1)
            {
                pos = arivBody.get_cartesian_pos(V * RAD);

                x1 = x0 + Convert.ToSingle(scale * pos.x);
                y1 = y0 - Convert.ToSingle(scale * pos.y);

                V += dV;

                pos = arivBody.get_cartesian_pos(V * RAD);

                x2 = x0 + Convert.ToSingle(scale * pos.x);
                y2 = y0 - Convert.ToSingle(scale * pos.y);

                if (pos.z >= 0)
                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                else
                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

                graph.DrawLine(pen, x1, y1, x2, y2);
            }

            // Departure Body orbit
            V0 = 0;
            V = V0;
            V1 = 360.0;
            dV = 5.0;

            while (V <= V1)
            {
                pos = destBody.get_cartesian_pos(V * RAD);

                x1 = x0 + Convert.ToSingle(scale * pos.x);
                y1 = y0 - Convert.ToSingle(scale * pos.y);

                V += dV;

                pos = destBody.get_cartesian_pos(V * RAD);

                x2 = x0 + Convert.ToSingle(scale * pos.x);
                y2 = y0 - Convert.ToSingle(scale * pos.y);

                if (pos.z >= 0)
                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                else
                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

                graph.DrawLine(pen, x1, y1, x2, y2);
            }

            V0 = 0;
            V = V0;
            V1 = Lambert.get_dest_theta(craft, trans.destLambda) / RAD;
            dV = 5.0;

            pen.Color = Color.Red;

            do
            {
                pos = craft.get_cartesian_pos(V * RAD);

                x1 = x0 + Convert.ToSingle(scale * pos.x);
                y1 = y0 - Convert.ToSingle(scale * pos.y);

                V += dV;

                pos = craft.get_cartesian_pos(V * RAD);

                x2 = x0 + Convert.ToSingle(scale * pos.x);
                y2 = y0 - Convert.ToSingle(scale * pos.y);

                if (pos.z >= 0)
                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                else
                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

                graph.DrawLine(pen, x1, y1, x2, y2);

            } while (V <= V1);

            // Destination body position
            SolidBrush brush = new SolidBrush(Color.Blue);

            // Draw Planets at departure date
            float radius = 5.0F;

            destBody.get_position(trans.arrivTime, ref orbit_pos);
            pos = destBody.get_cartesian_pos(orbit_pos.theta);

            x = x0 + Convert.ToSingle(scale * pos.x);
            y = y0 - Convert.ToSingle(scale * pos.y);

            float x5 = x;
            float y5 = y;

            graph.FillEllipse(brush, x - radius, y - radius, 2 * radius, 2 * radius);

            arivBody.get_position(trans.arrivTime, ref orbit_pos);
            pos = arivBody.get_cartesian_pos(orbit_pos.theta);

            x = x0 + Convert.ToSingle(scale * pos.x);
            y = y0 - Convert.ToSingle(scale * pos.y);

            graph.FillEllipse(brush, x - radius, y - radius, 2 * radius, 2 * radius);

            brush.Color = Color.Red;

            // Draw Planets at arrival date
            destBody.get_position(trans.depTime, ref orbit_pos);
            pos = destBody.get_cartesian_pos(orbit_pos.theta);

            x = x0 + Convert.ToSingle(scale * pos.x);
            y = y0 - Convert.ToSingle(scale * pos.y);

            graph.FillEllipse(brush, x - radius, y - radius, 2 * radius, 2 * radius);

            arivBody.get_position(trans.depTime, ref orbit_pos);
            pos = arivBody.get_cartesian_pos(orbit_pos.theta);

            x = x0 + Convert.ToSingle(scale * pos.x);
            y = y0 - Convert.ToSingle(scale * pos.y);

            float x3 = x;
            float y3 = y;

            EclipticPos epos = new EclipticPos();
            arivBody.get_ecliptic_coords(orbit_pos.theta, ref epos);
            epos.lambda += Math.PI;
            double opos_theta = Lambert.get_dest_theta(destBody, epos.lambda);
            pos = destBody.get_cartesian_pos(opos_theta);

            float x4 = x0 + Convert.ToSingle(scale * pos.x);
            float y4 = y0 - Convert.ToSingle(scale * pos.y);

            graph.FillEllipse(brush, x - radius, y - radius, 2 * radius, 2 * radius);

            // Draw Psi angle
            pen.Color = Color.LightGray;
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
            pen.Width = 1.0F;
            graph.DrawLine(pen, x3, y3, x4, y4);
            graph.DrawLine(pen, x0, y0, x5, y5);

            //
            float sunRadius = 10.0F;

            if (ariv_data.refBody == "Sun")
                brush.Color = Color.Yellow;
            else
                brush.Color = Color.Blue;

            graph.FillEllipse(brush, x0 - sunRadius, y0 - sunRadius, 2 * sunRadius, 2 * sunRadius);
        }
Example #10
0
        //-----------------------------------------------------------
        //
        //-----------------------------------------------------------
        private void DrawPlanet(Panel panel, double theta, int body_idx)
        {
            int width = panel.Width;
            int height = panel.Height;

            float x0 = width / 2;
            float y0 = height / 2;

            float x = 0;
            float y = 0;

            Graphics graph = panel.CreateGraphics();

            graph.Clear(Color.Black);

            Pen myPen = new Pen(Color.LightGray, 2.0F);

            // Draw trajectory
            double  scale = 0;
            int Delta = 25;
            float delta = 5.0F;

            BodyData data = new BodyData();

            Bodies[body_idx].get_data(ref data);

            int kerbin_idx = get_body_index("Kerbin");
            OrbitPos kerbin_pos = new OrbitPos();

            double  t = KCalendar.date_to_sec(int.Parse(textYear.Text.ToString()),
                                            int.Parse(comboDay.Text.ToString()),
                                            int.Parse(comboHour.Text.ToString()),
                                            int.Parse(comboMin.Text.ToString()),
                                            int.Parse(comboSec.Text.ToString()));

            Bodies[kerbin_idx].get_position(t, ref kerbin_pos);

            EclipticPos kerbin_epos = new EclipticPos();

            Bodies[kerbin_idx].get_ecliptic_coords(kerbin_pos.theta, ref kerbin_epos);

            double  ra = data.orbit.a / (1 - data.orbit.e);
            double r_max = ra;

            float r0 = 0;

            if (width > height)
            {
                scale = (height / 2 - Delta) / r_max;
                r0 = height / 2 - Delta;
            }
            else
            {
                scale = (width / 2 - Delta) / r_max;
                r0 = width / 2 - Delta;
            }

            double  V = 0;
            double  dV = 5.0;

            Vector3D pos;

            // Draw planet orbit
            while (V <= 360.0)
            {
                pos = Bodies[body_idx].get_cartesian_pos(V * RAD);

                float x1 = x0 + Convert.ToSingle(scale * pos.x);
                float y1 = y0 - Convert.ToSingle(scale * pos.y);

                V += dV;

                pos = Bodies[body_idx].get_cartesian_pos(V * RAD);

                float x2 = x0 + Convert.ToSingle(scale * pos.x);
                float y2 = y0 - Convert.ToSingle(scale * pos.y);

                if (pos.z >= 0)
                    myPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                else
                    myPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

                graph.DrawLine(myPen, x1, y1, x2, y2);
            }

            // Draw planet position
            pos = Bodies[body_idx].get_cartesian_pos(theta);

            EclipticPos epos = new EclipticPos();

            Bodies[body_idx].get_ecliptic_coords(theta, ref epos);

            double phi = Lambert.get_phase(epos.lambda - kerbin_epos.lambda) / RAD;

            x = x0 + Convert.ToSingle(scale * pos.x);
            y = y0 - Convert.ToSingle(scale * pos.y);

            myPen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;

            graph.DrawLine(myPen, x0, y0, x, y);

            // Title
            SolidBrush brush = new SolidBrush(Color.LightGray);
            Font font = new Font("Courier New", 10);
            string title = data.name + " position UT: " +
                           textYear.Text + "y " +
                           comboDay.Text + "d " +
                           comboHour.Text + "h " +
                           comboMin.Text + "m " +
                           comboSec.Text + "s";

            graph.DrawString(title, font, brush, delta, delta);

            graph.DrawString("\u03b2 = " + Math.Round(epos.beta / RAD, 4).ToString(), font, brush, delta, delta + font.Height);
            graph.DrawString("\u03bb = " + Math.Round(epos.lambda / RAD, 4).ToString(), font, brush, delta, delta + 2*font.Height);
            graph.DrawString("Kerbin phase: " + Math.Round(phi, 4).ToString(), font, brush, delta, height - delta - font.Height);
            graph.DrawString("\u03b8 = " + Math.Round(Bodies[body_idx].get_rotation_angle(t), 4).ToString(), font, brush, delta, delta + 3 * font.Height);

            // Draw Ref Body
            myPen.Color = Color.Yellow;

            float sunRadius = 10.0F;

            if (data.refBody == "Sun")
                brush.Color = Color.Yellow;
            else
                brush.Color = Color.Blue;

            graph.FillEllipse(brush, x0 - sunRadius, y0 - sunRadius, 2*sunRadius, 2*sunRadius);

            // Draw Planet
            float radius = 5.0F;

            brush.Color = Color.Green;

            graph.FillEllipse(brush, x - radius, y - radius, 2 * radius, 2 * radius);

            // Draw Kerbin direction
            myPen.Color = Color.Red;
            myPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;

            x = x0 + r0 * Convert.ToSingle(Math.Cos(kerbin_epos.lambda));
            y = y0 - r0 * Convert.ToSingle(Math.Sin(kerbin_epos.lambda));

            graph.DrawLine(myPen, x0, y0, x, y);
        }
Example #11
0
        public MainForm()
        {
            InitializeComponent();

            Bodies = new List<CelestialBody>();

            ReadSystemConfig("../cfg/kerbal.xml");

            // Bodies list init
            for (int i = 0; i < Bodies.Count; i++)
            {
                BodyData data = new BodyData();
                Bodies[i].get_data(ref data);

                if (data.name != "Sun")
                {
                    BodiesList.Items.Add(data.name);
                    comboHomanArrivList.Items.Add(data.name);
                    comboHomanDepList.Items.Add(data.name);
                }
            }

            BodiesList.SelectedIndex = 0;
            comboHomanArrivList.SelectedIndex = 0;
            comboHomanDepList.SelectedIndex = 5;

            comboHomanArrivList.SelectedText = "Kerbin";
            comboHomanDepList.SelectedText = "Duna";

            for (int i = 1; i <= KCalendar.Days; i++)
            {
                comboDay.Items.Add(i.ToString());
                comboBeginDay.Items.Add(i.ToString());
                comboEndDay.Items.Add(i.ToString());
            }

            comboDay.SelectedIndex = 0;
            comboBeginDay.SelectedIndex = 0;
            comboEndDay.SelectedIndex = 0;

            for (int i = 0; i < KCalendar.Hours; i++)
            {
                comboHour.Items.Add(i.ToString());
                comboBeginHour.Items.Add(i.ToString());
                comboEndHour.Items.Add(i.ToString());
            }

            comboHour.SelectedIndex = 0;
            comboBeginHour.SelectedIndex = 0;
            comboEndHour.SelectedIndex = 0;

            for (int i = 0; i < KCalendar.Mins; i++)
            {
                comboMin.Items.Add(i.ToString());
                comboBeginMin.Items.Add(i.ToString());
                comboEndMin.Items.Add(i.ToString());
            }

            comboMin.SelectedIndex = 0;
            comboBeginMin.SelectedIndex = 0;
            comboEndMin.SelectedIndex = 0;

            for (int i = 0; i < KCalendar.Secs; i++)
            {
                comboSec.Items.Add(i.ToString());
                comboBeginSec.Items.Add(i.ToString());
                comboEndSec.Items.Add(i.ToString());
            }

            comboSec.SelectedIndex = 0;
            comboBeginSec.SelectedIndex = 0;
            comboEndSec.SelectedIndex = 0;

            label34.Text = "\u03c8, deg.";    // Psi letter
            label41.Text = "\u0394\u03c8, deg.";
            groupLat.Text = "Latitude";
        }
Example #12
0
        //---------------------------------------------------------------------
        //
        //---------------------------------------------------------------------
        private void buttonHomanSearch_Click(object sender, EventArgs e)
        {
            double t0 = KCalendar.date_to_sec(int.Parse(textBeginYear.Text.ToString()),
                                            int.Parse(comboBeginDay.Text.ToString()),
                                            int.Parse(comboBeginHour.Text.ToString()),
                                            int.Parse(comboBeginMin.Text.ToString()),
                                            int.Parse(comboBeginSec.Text.ToString()));

            double t1 = KCalendar.date_to_sec(int.Parse(textEndYear.Text.ToString()),
                                            int.Parse(comboEndDay.Text.ToString()),
                                            int.Parse(comboEndHour.Text.ToString()),
                                            int.Parse(comboEndMin.Text.ToString()),
                                            int.Parse(comboEndSec.Text.ToString()));

            int dep_idx = get_body_index(comboHomanArrivList.Text.ToString());
            int arr_idx = get_body_index(comboHomanDepList.Text.ToString());

            // Check same reference body!!!
            if (Bodies[dep_idx].get_ref_body() != Bodies[arr_idx].get_ref_body())
            {
                labelNoTransfer.Text = "Bodies must have same reference body!\nPlease, change other bodies";
                return;
            }

            Transfer trans = new Transfer();

            double psi = Convert.ToDouble(textPsi.Text) * RAD;

            bool ready = Lambert.get_transfer_date(t0, t1, Bodies[dep_idx], Bodies[arr_idx], psi, ref trans);

            if (!ready)
            {
                panelHomanRes.Visible = false;
                labelNoTransfer.Text = "Transfer is imposible in changed period";
                return;
            }

            labelNoTransfer.Text = "";

            panelHomanRes.Visible = true;

            KDate deltaDate = new KDate();

            KCalendar.DeltaDate(trans.arrivTime - trans.depTime, ref deltaDate);

            labelArivDate.Text = trans.depDate.year.ToString() + "y " +
                                 trans.depDate.day.ToString() + "d " +
                                 trans.depDate.hour.ToString() + "h " +
                                 trans.depDate.min.ToString() + "m " +
                                 trans.depDate.sec.ToString() + "s";

            labelDepDate.Text = trans.arrivDate.year.ToString() + "y " +
                                 trans.arrivDate.day.ToString() + "d " +
                                 trans.arrivDate.hour.ToString() + "h " +
                                 trans.arrivDate.min.ToString() + "m " +
                                 trans.arrivDate.sec.ToString() + "s";

            labelTransTime.Text = deltaDate.year.ToString() + "y " +
                                 deltaDate.day.ToString() + "d " +
                                 deltaDate.hour.ToString() + "h " +
                                 deltaDate.min.ToString() + "m " +
                                 deltaDate.sec.ToString() + "s";

            labelSmiMajorAxis.Text = Math.Round(trans.orbit.a, 0).ToString() + " m";
            labelEccentricity.Text = Math.Round(trans.orbit.e, 4).ToString();
            labelInclination.Text = Math.Round(trans.orbit.i, 4).ToString() + " deg";
            labelLAN.Text = Math.Round(trans.orbit.Omega, 4).ToString() + " deg";
            labelArgPe.Text = Math.Round(trans.orbit.omega, 4).ToString() + " deg";

            CelestialBody craft = new CelestialBody();

            BodyData craft_data = new BodyData();

            craft_data.name = "Space craft";
            craft_data.orbit = trans.orbit;
            craft.set_data(ref craft_data);
            craft.set_refGravParameter(Bodies[dep_idx].get_refGravParameter());

            DepManuever manuever = new DepManuever();

            manuever.h = double.Parse(textAltitude.Text)*1000.0;
            manuever.turns = int.Parse(textWaitTurns.Text);

            Lambert.get_depatrure_manuever(Bodies[dep_idx],
                                           craft,
                                           trans.depTime,
                                           ref manuever);

            labelDeltaV.Text = Math.Round(manuever.dv, 2).ToString();
            labelInc.Text = Math.Round(manuever.orbit.i, 4).ToString();
            labelStartLAN.Text = Math.Round(manuever.orbit.Omega, 4).ToString();

            labelEjectDate.Text = manuever.ejectDate.year.ToString() + "y " +
                                  manuever.ejectDate.day.ToString() + "d " +
                                  manuever.ejectDate.hour.ToString() + "h " +
                                  manuever.ejectDate.min.ToString() + "m " +
                                  manuever.ejectDate.sec.ToString() + "s";

            double latDeg = double.Parse(textLatDeg.Text);
            double latMin = double.Parse(textLatMin.Text);
            double latSec = double.Parse(textLatSec.Text);

            double lonDeg = double.Parse(textLonDeg.Text);
            double lonMin = double.Parse(textLonMin.Text);
            double lonSec = double.Parse(textLonSec.Text);

            manuever.launchLat = (latDeg + latMin / 60.0 + latSec / 3600.0) * RAD;
            manuever.launchLon = (lonDeg + lonMin / 60.0 + lonSec / 3600.0) * RAD;

            if (radioButtonSouth.Checked)
                manuever.launchLat = -manuever.launchLat;

            if (radioButtonWest.Checked)
                manuever.launchLon = -manuever.launchLon;

            bool flag = Lambert.get_launch_params(Bodies[dep_idx], ref manuever);

            if (flag)
            {
                labelStartDate.Text = manuever.launchDate.year.ToString() + "y " +
                                      manuever.launchDate.day.ToString() + "d " +
                                      manuever.launchDate.hour.ToString() + "h " +
                                      manuever.launchDate.min.ToString() + "m " +
                                      manuever.launchDate.sec.ToString() + "s";

                labelAzimuth.Text = Math.Round(manuever.azimuth, 2).ToString();
            }

            // Draw trajectory
            DrawTransOrbit(panelTransOrbit, trans, Bodies[dep_idx], Bodies[arr_idx], craft);
        }