/// <summary> /// When using reference frame modes, the fact that reference frames can accelerate needs to be corrected for /// </summary> /// <param name="universe">universe to correct</param> /// <param name="dt">timestep used</param> internal void CorrectForMovingReferenceFrames(Universe universe, double dt) { // need to adjust the position/velocity vectors to account for the fact that reference frames are moving and accelerating. RelativeBody center = (RelativeBody)universe.GetBodies().First(); //TODO: rewrite to handle binary-style cases center.correctForMovingReferenceFrames(dt); }
public RelativeBody(double m0 = 0, string lbl = "") { parent = null; name = lbl; m = m0; Initialize(); }
public static Universe GenerateTestUniverse(bool useRel = false) { Universe universe = new Universe(useRel); if (universe.useRelative) { RelativeBody sr = new RelativeBody(100, "Sol"); RelativeBody jr = new RelativeBody(200, 100, sr, 1, lbl: "Jool"); RelativeBody tr = new RelativeBody(10, 2, jr, 0.1, lbl: "Tylo"); RelativeBody ast = new RelativeBody(1, -1, tr, 0.05, lbl: "Ast"); universe.AddBody(sr); universe.AddBody(jr); universe.AddBody(tr); universe.AddBody(ast); } else { Body s = new Body(100, lbl: "Sol"); Body j = new Body(200, 100, s, 1, lbl: "Jool"); Body t = new Body(10, 2, j, 0.1, lbl: "Tylo"); Body a = new Body(1, -1, t, 0.05, lbl: "Ast"); universe.AddBody(s); universe.AddBody(j); universe.AddBody(t); universe.AddBody(a); } return(universe); }
public RelativeBody( double x0, double y0, RelativeBody parentBody = null, double m0 = 0, Vector inV = null, double rho0 = 1, string lbl = "<>") { Vector inP = new Vector(x0, y0, 0.0); parent = parentBody; p = inP; v = parent == null ? new Vector() : inV; if (v == null) { Vector pN = p.Normal(); double mag = Math.Sqrt(parent.m / p.Mag()); v = mag * (new Vector(-pN.y, pN.x, pN.z)); } rho = rho0; m = m0; name = lbl; Initialize(); }
private void AbandonChild(RelativeBody child) { if (children.Contains(child)) { children.Remove(child); child.parent = null; } }
public void RecursiveAdd(RelativeBody body, List <Body> list) { list.Add(body); body.children = body.children.OrderBy(child => child.p.Mag()).ToList(); foreach (RelativeBody child in body.children) { RecursiveAdd(child, list); } }
internal Vector distanceFromParent(RelativeBody parent) { RelativeBody par = this; Vector relDis = new Vector(); while (par != null && par != parent) { relDis += par.p; par = par.parent; } return(relDis); }
public int parentDepth() { RelativeBody p = (RelativeBody)parent; int output = 0; while (p != null) { p = (RelativeBody)p.parent; output++; } return(output); }
/// <summary> /// Adds the child to this body's list of children, removes from old parent's children, and sets child's parent to this /// </summary> /// <param name="child">The body being 'adopted'</param> public void AdoptChild(RelativeBody child) { if (!children.Contains(child)) { if (child.parent != null && child.parent != this) { child.parent.AbandonChild(child); } child.parent = this; children.Add(child); } }
public void HeirarchicalSort() { if (!useRelative) { return; } RelativeBody center = (RelativeBody)bodies.First(); List <Body> sorted = new List <Body>(); RecursiveAdd(center, sorted); bodies = sorted; }
internal void RecursiveRenderParents(Graphics dc, Pen pen, RelativeBody body, Vector pOffset) { RelativeBody parent = body.parent; if (parent != null) { if (renderReferenceLines) { renderArrow(dc, pen, pOffset - body.p, pOffset); } RecursiveRenderChildren(dc, pen, parent, pOffset - body.p, body); RecursiveRenderParents(dc, pen, parent, pOffset - body.p); } }
internal void RecursiveRenderChildren(Graphics dc, Pen pen, RelativeBody body, Vector pOffset, RelativeBody skip = null) { renderBody(dc, pen, body, pOffset); foreach (RelativeBody child in body.children) { if (child != skip) { if (renderReferenceLines) { renderArrow(dc, pen, pOffset, pOffset + child.p); } RecursiveRenderChildren(dc, pen, child, pOffset + child.p); } } }
internal void RenderUniverseFromFocus(Graphics dc, Pen pen, Universe universe, RelativeBody focus) { RelativeBody center = (RelativeBody)universe.GetBodies().First(); // TODO: better handle binary-type cases Pen childPen = new Pen(Color.Blue, 1); if (focus == null && center != null) { RecursiveRenderChildren(dc, childPen, center, center.p); } else { RecursiveRenderChildren(dc, childPen, focus, Vector.zeroVect); RecursiveRenderParents(dc, pen, focus, Vector.zeroVect); } }
public static Universe GenerateTwoBody(bool useRel = false) { Universe universe = new Universe(useRel); if (useRel) { RelativeBody center = new RelativeBody(100, "Center"); RelativeBody orbit = new RelativeBody(100, 0, center, 10, lbl: "Orbiter"); universe.AddBody(center); universe.AddBody(orbit); } else { Body center = new Body(100, lbl: "Center"); Body orbit = new Body(100, 0, center, 10, lbl: "Orbiter"); universe.AddBody(center); universe.AddBody(orbit); } return(universe); }
/// <summary> /// Gets the 'distance' vector from a to b /// </summary> /// <param name="a">origin body</param> /// <param name="b">destination body</param> /// <param name="relativeMeasurements">bool determining if these bodies are using 'relative measurements'</param> /// <returns>the vector from A's position to B's position</returns> internal Vector Distance(Body a, Body b, bool relativeMeasurements) { // TODO: Look into making this a method within the Body classes, doesn't really need to be here Vector dist = new Vector(); if (a == b) { return(dist); } if (relativeMeasurements) { RelativeBody ra = (RelativeBody)a; RelativeBody rb = (RelativeBody)b; RelativeBody mutualParent = ra.getMutualParent(rb); dist = rb.distanceFromParent(mutualParent) - ra.distanceFromParent(mutualParent); } else { dist = b.p - a.p; } return(dist); }
internal RelativeBody getMutualParent(RelativeBody other) { int depthA = this.parentDepth(); int depthB = other.parentDepth(); RelativeBody aParent = this; RelativeBody bParent = other; while (depthA > depthB) { depthA--; aParent = aParent.parent; } while (depthB > depthA) { depthB--; bParent = bParent.parent; } while (aParent != bParent) { aParent = aParent.parent; bParent = bParent.parent; } return(aParent); }
public static Universe GenPseudoRandomUniverse( bool relative = true, int seed = 0, int count = 20, int nestFactor = 2, double mScale = 100.0, double mRatio = 1000.0, double dScale = 500.0) { Random random = seed == 0 ? new Random() : new Random(seed); Universe uni = new Universe(relative); double avgSplitFactor = Math.Log(count, nestFactor); int total = 1; if (relative) { RelativeBody center = new RelativeBody(mScale, "0_*"); uni.AddBody(center); int continues = 0; while (total < count) { RelativeBody host = (RelativeBody)uni.GetBodies()[random.Next(0, uni.GetBodies().Count())]; if (host.parentDepth() > nestFactor - 1) { continues++; if (continues < 4) { continue; } host = center; } continues = 0; double mass = (host.m / mRatio) * Math.Pow(2, -host.children.Count()); //double mag = random.NextDouble() * dScale * host.m / mScale; double mag; if (host == center) { mag = dScale; } else { mag = host.p.Mag() * Math.Pow(host.m / (3 * host.parent.m), 0.333) / 4.0; } mag *= random.NextDouble(); double theta = random.NextDouble() * Math.PI * 2; Vector distance = new Vector(mag * Math.Cos(theta), mag * Math.Sin(theta), 0); string name; if (host == center) { name = $"{center.children.Count() + 1}_*"; } else if (host.parentDepth() == 1) { name = $"{host.name.Substring(0, host.name.Length - 1)}{host.children.Count() + 1}"; } else { name = $"{host.name}_{host.children.Count() + 1}"; } RelativeBody addition = new RelativeBody(distance, host, mass, lbl: $"{name}"); uni.AddBody(addition); total++; } } uni.HeirarchicalSort(); return(uni); }
public static Universe PseudoRealSolarSystem(bool useRel = false) { //TODO: Try to scrape this from ephemeris data Universe universe = new Universe(useRel, 6.67e-11); if (useRel) { RelativeBody sol = new RelativeBody( new Vector(-3.91242e8, 1.13826e9, -1.36642e6), null, 1988500e24, new Vector(-1.46227e1, -7.226575e-1, 3.855625e-1), 1.408, "Sol"); universe.AddBody(sol); RelativeBody mer = new RelativeBody( new Vector(3.7265248e10, 2.99191857e10, -9.73742642e8), sol, 3.302e23, new Vector(-4.0081238e4, 4.00785892165e4, 6.95187127e3), 5.427, "Mercury"); universe.AddBody(mer); RelativeBody ven = new RelativeBody( new Vector(-8.285427e10, 6.823787e10, 5.7176105e9), sol, 48.685e23, new Vector(-2.239593e4, -2.72111445e4, 9.19038772e2), 5.204, "Venus"); universe.AddBody(ven); RelativeBody ear = new RelativeBody( new Vector(1.1724955e11, -9.6037042e10, 4.240154172e6), sol, 5.97219e24, new Vector(1.838051573e4, 2.292561645e4, -4.80362870085e-2), 5.51, "Earth"); universe.AddBody(ear); RelativeBody mar = new RelativeBody( new Vector(-2.176527e11, 1.2096152e11, 7.8749526e9), sol, 6.4171e23, new Vector(-1.0862549e4, -1.910899192e4, -1.338880148e2), 3.933, "Mars"); universe.AddBody(mar); RelativeBody jup = new RelativeBody( new Vector(-7.7324016329e10, -7.85692429e11, 4.9935554e9), sol, 1898.13e24, new Vector(1.28574958e4, -6.647244023e2, -2.84976624e2), 1.326, "Jupiter"); universe.AddBody(jup); RelativeBody sat = new RelativeBody( new Vector(4.646603288e11, -1.429337911e12, 6.35272334e9), sol, 5.6834e26, new Vector(8.6658972e3, 2.95812489e3, -3.9639882e2), 0.687, "Saturn"); universe.AddBody(sat); RelativeBody ura = new RelativeBody( new Vector(2.474143379e12, 1.6380446e12, -2.595844e10), sol, 86.813e24, new Vector(-3.797021e3, 5.360144026e3, 6.888360866e1), 1.271, "Uranus"); universe.AddBody(ura); RelativeBody nep = new RelativeBody( new Vector(4.3604752e12, -1.017071714e12, -7.955997546e10), sol, 102.413e24, new Vector(1.2111618e3, 5.3261598e3, -1.3733646447e2), 1.638, "Neptune"); universe.AddBody(nep); RelativeBody mon = new RelativeBody( new Vector(2.245235455e8, -3.335982581e8, -1.0562881438814e7), ear, 7.349e22, new Vector(8.23519443721e2, 5.26278905202e2, -8.574012751e1), 3.3437, "Moon"); universe.AddBody(mon); } else { } return(universe); }
public RelativeBody(RelativeBody parentBody) { parent = parentBody; Initialize(); }