//--------------------------------------------------------------------- // //--------------------------------------------------------------------- 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); }
//--------------------------------------------------------------------- // //--------------------------------------------------------------------- public static bool get_transfer_date(double t0, double t1, CelestialBody depBody, CelestialBody arrivBody, double psi, ref Transfer trans) { double t = t0; double dL0; double dL1; double eps = 1e-8; double dt = 21600.0; bool ready = false; do { dL0 = LambdaErr(t, depBody, arrivBody, psi); t += dt; dL1 = LambdaErr(t, depBody, arrivBody, psi); if ((dL0 * dL1 < 0) && (Math.Abs(dL1) < 10.0 * math.RAD)) ready = true; else ready = false; } while ( (!ready) && (t <= t1) ); if (t > t1) return false; double ta = t - dt; double tb = t; double tc = 0; do { tc = (ta + tb) / 2; dL0 = LambdaErr(ta, depBody, arrivBody, psi); dL1 = LambdaErr(tc, depBody, arrivBody, psi); if (dL0 * dL1 >= 0) ta = tc; else tb = tc; } while (Math.Abs(dL1) >= eps); trans.depTime = tc; KCalendar.sec_to_date(tc, ref trans.depDate); trans.transTime = get_transfer_orbit(tc, depBody, arrivBody, psi, ref trans.orbit, ref trans.destLambda); trans.arrivTime = tc + trans.transTime; KCalendar.sec_to_date(trans.arrivTime, ref trans.arrivDate); return true; }
//--------------------------------------------------------------------- // //--------------------------------------------------------------------- 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); }