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; }
//--------------------------------------------------------------------- // 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); }
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; }
//--------------------------------------------------------------------- // //--------------------------------------------------------------------- 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; }
//--------------------------------------------------------------------- // 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; }
//--------------------------------------------------------------- // //--------------------------------------------------------------- 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()); } } }
//---------------------------------------------------------------------- // 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; }
//------------------------------------------------------------ // //------------------------------------------------------------ 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; }
//--------------------------------------------------------------------- // //--------------------------------------------------------------------- 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); }
//----------------------------------------------------------- // //----------------------------------------------------------- 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); }
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"; }
//--------------------------------------------------------------------- // //--------------------------------------------------------------------- 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); }