Beispiel #1
0
        //---------------------------------------------------------------------
        //
        //---------------------------------------------------------------------
        public void get_ecliptic_coords(double theta, ref EclipticPos ecoords)
        {
            double Omega = data.orbit.Omega * math.RAD;
            double omega = data.orbit.omega * math.RAD;
            double i = data.orbit.i * math.RAD;
            double V = theta;

            ecoords.beta = Math.Asin(Math.Sin(i) * Math.Sin(omega + V));

            double sin_lambda = (Math.Sin(Omega) * Math.Cos(V + omega) + Math.Cos(Omega) * Math.Cos(i) * Math.Sin(V + omega)) / Math.Cos(ecoords.beta);
            double cos_lambda = (Math.Cos(Omega) * Math.Cos(V + omega) - Math.Sin(Omega) * Math.Cos(i) * Math.Sin(V + omega)) / Math.Cos(ecoords.beta);

            ecoords.lambda = math.arg(sin_lambda, cos_lambda);
        }
Beispiel #2
0
        //---------------------------------------------------------------------
        //      Cartesian system position of body
        //---------------------------------------------------------------------
        public Vector3D get_cartesian_pos(double theta)
        {
            double r = 0;
            double e = data.orbit.e;

            if ( (e > -1) && (e < 1) )
                r = data.orbit.a * (1 - e * e) / (1 + e * Math.Cos(theta));

            if (e == 1)
                r = 2 * data.orbit.a / (1 + e * Math.Cos(theta));

            if (e > 1)
                r = data.orbit.a * (e*e - 1) / (1 + e * Math.Cos(theta));

            EclipticPos epos = new EclipticPos();

            get_ecliptic_coords(theta, ref epos);

            double x = r * Math.Cos(epos.beta) * Math.Cos(epos.lambda);
            double y = r * Math.Cos(epos.beta) * Math.Sin(epos.lambda); ;
            double z = r * Math.Sin(epos.beta);

            return new Vector3D(x, y, z);
        }
Beispiel #3
0
        //---------------------------------------------------------------------
        //
        //---------------------------------------------------------------------
        public static double LambdaErr(double t,
                                     CelestialBody arivBody,
                                     CelestialBody destBody,
                                     double phi)
        {
            Orbit orbit = new Orbit();

            double destLambda = 0;
            double transTime = get_transfer_orbit(t, arivBody, destBody, phi, ref orbit, ref destLambda);

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

            destBody.get_position(t + transTime, ref pos);
            destBody.get_ecliptic_coords(pos.theta, ref epos);

            return get_phase(epos.lambda - destLambda);
        }
Beispiel #4
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;
        }
Beispiel #5
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);
        }
Beispiel #6
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);
        }
Beispiel #7
0
        //-----------------------------------------------------------
        //
        //-----------------------------------------------------------
        private void buttonEphCalc_Click(object sender, EventArgs e)
        {
            int body_idx = get_body_index(BodiesList.Text.ToString());

            if (body_idx == -1)
            {
                MessageBox.Show("There are no " + BodiesList.Text.ToString() + " in data base");
                return;
            }

            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()));

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

            Bodies.ElementAt(body_idx).get_position(t, ref pos);
            Bodies.ElementAt(body_idx).get_ecliptic_coords(pos.theta, ref ecoords);

            labelTrueAnomaly.Text = Math.Round(pos.theta / RAD, 4).ToString() + " deg";
            labelRadiusVector.Text = Math.Round(pos.r, 0).ToString() + " m";
            labelEccAnomaly.Text = Math.Round(pos.E, 4).ToString() + " rad";
            labelLat.Text = Math.Round(ecoords.beta / RAD, 4).ToString() + " deg";
            labelLon.Text = Math.Round(ecoords.lambda / RAD, 4).ToString() + " deg";
            labelAltitude.Text = Math.Round(pos.refAltitude, 0).ToString() + " m";

            DrawPlanet(panelBodyPos, pos.theta, body_idx);
        }