/// <summary> /// Add an element to the sequence using r0/v0/t0 initial conditions. /// /// Position and velocity are with respect to the center body (NOT world/physics space!). /// /// Orbit segements must be added in increasing time order. /// </summary> /// <param name="r0"></param> /// <param name="v0"></param> /// <param name="time"></param> /// <param name="relativePos"></param> /// <param name="body"></param> /// <param name="centerBody"></param> /// <param name="callback">(Optional) Method to call when sequence starts</param> /// <returns></returns> public OrbitUniversal AppendElementRVT(Vector3d r0, Vector3d v0, double time, bool relativePos, NBody body, NBody centerBody, ElementStarted callback) { if (BadTime(time)) { return(null); } KeplerElement ke = new KeplerElement { timeStart = time, callback = callback, returnToGE = false }; OrbitUniversal orbit = orbitsGO.AddComponent <OrbitUniversal>(); orbit.centerNbody = centerBody; orbit.SetNBody(body); orbit.InitFromRVT(r0, v0, time, centerBody, relativePos); orbit.evolveMode = OrbitUniversal.EvolveMode.KEPLERS_EQN; ke.orbit = orbit; keplerElements.Add(ke); return(orbit); }
// Update is called once per frame void Update() { // on a deferred add (while running) may get an OP update before actually added to GE. This would be bad. if (nbody.engineRef == null) { return; } // TODO: optimize/accuracy: if on rails could use orbitU (or KS) directly // Now there is MapToRender MUST use physics and not transform position Vector3 centerPos = GravityEngine.Instance().GetPhysicsPosition(aroundNBody); // Is the resulting orbit and ellipse or hyperbola? bool mapToScene = true; Vector3d pos = ge.GetPositionDoubleV3(nbody); Vector3d vel; if (velocityFromScript) { vel = new Vector3d(velocity); } else { vel = ge.GetVelocityDoubleV3(nbody); } orbitU.InitFromRVT(pos, vel, ge.GetPhysicalTimeDouble(), aroundNBody, false); // Add lines to the inclination=0 plane of the orbit Vector3[] points = orbitU.OrbitPositions(numPoints, centerPos, mapToScene, hyperDisplayRadius); int totalPoints = numPoints + 2 * numPlaneProjections; if (numPlaneProjections > 0) { Vector3[] pointsWithProj = new Vector3[totalPoints]; int projEvery = numPoints / numPlaneProjections; int p = 0; int orbitP = 0; while (p < totalPoints) { pointsWithProj[p++] = points[orbitP]; if ((orbitP % projEvery) == 0) { // add a line to plane and back pointsWithProj[p++] = Vector3.ProjectOnPlane(points[orbitP], planeNormal); pointsWithProj[p++] = points[orbitP]; } orbitP++; } lineR.SetPositions(pointsWithProj); } else { lineR.SetPositions(points); } }
// Update is called once per frame void Update() { // Now there is MapToRender MUST use physics and not transform position Vector3 centerPos = GravityEngine.Instance().GetPhysicsPosition(aroundNBody); // Is the resulting orbit and ellipse or hyperbola? bool mapToScene = true; Vector3d pos = ge.GetPositionDoubleV3(nbody); Vector3d vel; if (velocityFromScript) { vel = new Vector3d(velocity); } else { vel = ge.GetVelocityDoubleV3(nbody); } if (destination != null) { // since the segment code just uses this for the angle, the scale does not matter destPoint = destination.transform.position; } orbitU.InitFromRVT(pos, vel, ge.GetPhysicalTimeDouble(), aroundNBody, false); // TODO: Decide on best segment approach. Common for hyperbola vs ellipse ?? Vector3[] positions; if (orbitU.eccentricity < 1.0) { positions = orbitU.EllipseSegment(numPoints, centerPos, pos.ToVector3(), destPoint, shortPath); } else { float radius = (pos.ToVector3() - centerPos).magnitude; positions = orbitU.HyperSegmentSymmetric(numPoints, centerPos, radius, mapToScene); } lineR.SetPositions(positions); }