Der Orbitalbewegungsprädiktor ist nur genau, wenn der Satelliten auf einer bestimmten Seite des Planeten beginntC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Der Orbitalbewegungsprädiktor ist nur genau, wenn der Satelliten auf einer bestimmten Seite des Planeten beginnt

Post by Anonymous »

Ich habe ein Skript erstellt, das die Schwerkraft zwischen Satelliten und Planeten simuliert und die Umlaufbahn des Satelliten auf der Grundlage der Orbitalelemente, die durch die Geschwindigkeit und Positionsvektoren des Satelliten berechnet wurden, basieren. Es funktioniert alles überraschend, vollkommen gut, aber das Problem ist, dass der Orbit -Prädiktor nur korrekt ist, wenn der Satellit seine Umlaufbahn von einer bestimmten Seite des Planeten aus startet. Wenn ich es von einer anderen Seite aus starte, ist die Umlaufbahn entweder rückwärts, völlig falsch oder ein Fehler tritt auf, was dazu führt, dass der Pfad überhaupt nicht gezogen wird. Die Physik und der Orbitalbewegungsprädiktor. Dies ist das einzige aktive Skript in der Szene. Es ist an ein Sphere -Spielobjekt gebunden. G (Schwerkraft) beträgt 0,005, die Masse des Planeten (Masse) beträgt 1E+09: < /p>
using NUnit.Framework;
using UnityEngine;
using System.Collections.Generic;
using System;
using Unity.VisualScripting;
using UnityEngine.UIElements;
using JetBrains.Annotations;
//using static UnityEditor.PlayerSettings;
using System.Collections;
using Unity.Mathematics.Geometry;
//using UnityEditor.Experimental.GraphView;

public class Physics : MonoBehaviour
{
public Material shipTexture;
public Material trailTexture;
public Vector3 shipCoords;
public Vector3 shipThrust;
GameObject central;
Rigidbody planetMass;
float size;
public float gravity;
public float mass;

// What the player will control. Each ship has its own properties that are decided by the physics
public class Ship
{
public string name;
public float xPos;
public float yPos;
public float zPos;
public float xVel;
public float yVel;
public float zVel;
public Vector3 spam;
public Vector3 novec;
public float std;
public Vector3 ecvec;
public float semaj;
public float smen;
public float inclination;
public float rAscensionNode;
public float argumentOfPeriapsis;
public float trueAnomaly;
public float gnd;
public float dist;
public Vector3 point;
public GameObject body;
public Rigidbody mass;
public Transform pos;
public MeshFilter mFilter;
public Material mats;

public Ship(string shipName, Vector3 coords)
{
name = shipName;
xPos = coords.x;
yPos = coords.y;
zPos = coords.z;
dist = MathF.Sqrt(MathF.Pow(xPos, 2) + MathF.Pow(yPos, 2) + MathF.Pow(zPos, 2));
body = new GameObject(name);
mass = body.AddComponent();
mass.mass = 10;
mass.useGravity = false;
mass.angularDamping = 0;
mass.AddRelativeTorque(new Vector3(-0.3f, 1, 0.5f), ForceMode.Impulse);
pos = body.GetComponent();
pos.localScale = new Vector3(10, 10, 10);
mFilter = body.AddComponent();
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
mFilter.mesh = go.GetComponent().mesh;
mFilter.gameObject.AddComponent();
Destroy(go);
pos.position = new Vector3(xPos, yPos, zPos);

}

}

// Every equation I will need to map out orbits
public class Equations
{
public static float Gravity(Transform m2Loc, Rigidbody m1Mass, Rigidbody m2Mass, float gravityConstant)
{

return (m1Mass.mass * m2Mass.mass) * gravityConstant / MathF.Pow(m2Loc.position.magnitude, 3);
}

public static Vector3 SpecificAngularMomentum(Vector3 r, Vector3 v) // h
{
return Vector3.Cross(r, v);
}

public static Vector3 NodeVector(Vector3 SAM) // n
{
return Vector3.Cross(new Vector3(0, -1, 0), SAM);
}

public static float StandardGravParam(float gConst, float earthMass, float shipMass)
{

return gConst * (earthMass + shipMass);
}

public static Vector3 EccentricityVector(Vector3 r, Vector3 v, Vector3 h, float u) // e
{
return ((MathF.Pow(v.magnitude, 2) - u / r.magnitude) * r - (Vector3.Dot(r, v) * v)) / u;
}

public static float SpecialMechanicalEnergy(Vector3 v, Vector3 r, float u) // E
{
return (MathF.Pow(v.magnitude, 2) / 2) - (u / r.magnitude);
}

public static float Momentum(float a, Vector3 e) // p
{
return a * (1 - MathF.Pow(e.magnitude, 2));
}

//////////////////////////////////////////////////////////////////
// Five of the Six Orbital Elements (minus time since Periapsis)
public static float Inclination(Vector3 h) // i
{
return MathF.Acos(-1 * h.y / h.magnitude);
}

public static float RightAscendingNode(Vector3 n) // O
{
return MathF.Acos(n.x / n.magnitude);
}

public static float ArgumentOfPeriapsis(Vector3 n, Vector3 e) // w
{
float equation = MathF.Acos(Vector3.Dot(n, e) / (n.magnitude * e.magnitude));

if (e.z < 0)
{
return 2 * MathF.PI - equation;
}
else
{
return equation;
}
}

public static float SemiMajorAxis(float u, float SME) // a
{
return -1 * (u / (2 * SME));
}

public static float TrueAnomaly(Vector3 e, Vector3 r) // v
{
return Mathf.Acos(Vector3.Dot(e, r) / (e.magnitude * r.magnitude));
}

}
public List ships = new List();
public List paths = new List();

// Gets the orbital elements 1 second after game starts
IEnumerator GetElements()
{
yield return new WaitForSeconds(1.005f);

Predictor();

}

// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{

central = GameObject.Find("M1");
planetMass = central.AddComponent();
planetMass.mass = mass;
planetMass.angularDamping = 0;
size = central.GetComponent().localScale.magnitude;
planetMass.angularVelocity = new Vector3(0, 0.1f, 0);
Ship mil = new Ship("Player", shipCoords);
ships.Add(mil);

mil.mass.AddForce(shipThrust, ForceMode.Impulse);
foreach (Ship i in ships)
{
i.body.GetComponent().material = shipTexture;
}
//InvokeRepeating("Trail", 0, 0.1f);

StartCoroutine(GetElements());

}

// Drawn behind the ship for a motion trail effect
void Trail()
{
foreach(Ship i in ships)
{
Vector3 tailPos = i.pos.position;
GameObject tail = new GameObject("Tail");
tail.GetComponent().position = tailPos;
tail.GetComponent().localScale = i.pos.localScale * 0.5f;
MeshFilter mFilter = tail.AddComponent();
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
mFilter.mesh = go.GetComponent().mesh;
mFilter.gameObject.AddComponent();
tail.GetComponent().material = shipTexture;
Destroy(go);

}

}

//Uses the orbital elements (and their consituent equations) to determine the orbit of a ship by calculating its position based on a changing True Anomaly
void Predictor()
{
foreach(GameObject o in paths)
{
Destroy(o);
}
paths.Clear();
foreach (Ship i in ships)
{
for(int x = 0; x < 360; x++)
{
// Gets the r value using the equation, but plugs in x for the True Anomaly, so a complete orbit is drawn no matter what the ship's current TA
float r = (i.semaj * (1 - MathF.Pow(i.ecvec.magnitude, 2))) / (1 + i.ecvec.magnitude * MathF.Cos(x * Mathf.Deg2Rad));
Vector3 flatPos = new Vector3(r * MathF.Cos(x * Mathf.Deg2Rad), r * MathF.Sin(x * Mathf.Deg2Rad), 0);

// These rotate the X and Y coordinates so that they fit in 3D space
Quaternion rotationPeriapsis = Quaternion.Euler(0, 0, i.argumentOfPeriapsis * Mathf.Rad2Deg);
Quaternion rotationInclination = Quaternion.Euler(i.inclination * Mathf.Rad2Deg, 0, 0);
Quaternion rotationAscendingNode = Quaternion.Euler(0, 0, i.rAscensionNode * Mathf.Rad2Deg);

// Combine the rotations. The order of multiplication matters.
Quaternion totalRotation = rotationAscendingNode * rotationInclination * rotationPeriapsis * Quaternion.Euler(90, 0, 0);

// Apply the rotation to the orbital position
Vector3 nodePos = totalRotation * flatPos;

// Just creates a cube in each calculated position to make a trajectory.
GameObject orbit = new GameObject("Orbit");
orbit.GetComponent().position = nodePos;
orbit.GetComponent().localScale = i.pos.localScale * 0.5f;
MeshFilter mFilter = orbit.AddComponent();
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
mFilter.mesh = go.GetComponent().mesh;
mFilter.gameObject.AddComponent();
orbit.GetComponent().material = shipTexture;
Destroy(go);
paths.Add(orbit);
}

}
}

// Update is called once per frame
void FixedUpdate()
{
foreach(Ship i in ships)
{
// Calculates every value needed to then create all six orbital elements to determine orbital position
i.gnd = MathF.Abs(i.pos.position.magnitude) - (size / 2);
i.spam = Equations.SpecificAngularMomentum(i.pos.position, i.mass.linearVelocity);
i.novec = Equations.NodeVector(i.spam);
i.std = Equations.StandardGravParam(gravity, central.GetComponent().mass, i.mass.mass);
i.ecvec = Equations.EccentricityVector(i.pos.position, i.mass.linearVelocity, i.spam, i.std);
i.smen = Equations.SpecialMechanicalEnergy(i.mass.linearVelocity, i.pos.position, i.std);
i.semaj = Equations.SemiMajorAxis(i.std, i.smen);
i.inclination = Equations.Inclination(i.spam);
i.rAscensionNode = Equations.RightAscendingNode(i.novec);
i.argumentOfPeriapsis = Equations.ArgumentOfPeriapsis(i.novec, i.ecvec);
i.trueAnomaly = Equations.TrueAnomaly(i.ecvec, i.pos.position);
i.mass.AddForce(i.pos.position * -1 * Equations.Gravity(i.pos, planetMass, i.mass, gravity), ForceMode.Force);
i.pos.eulerAngles = i.mass.linearVelocity;

// Used to change the orbit while game is running. Found other problems when doing this
if (Input.GetKeyDown("space"))
{
i.mass.AddForce(0, -50, 0, ForceMode.Impulse);
}

}
}
}
< /code>
Wenn ich die Umlaufbahn nur auf der rechten Seite des Planeten (1200, 0, 0) starte ein Grund). src = "https://i.sstatic.net/tfxliwjj.png"/>
45 Grad Orbit:

Polare Umlaufbahnen:

retrograde Umlaufbahnen:

etc.
Aber wenn ich das Schiff von einer anderen Position aus starte (irgendetwas, irgendetwas, irgendetwas), ist die vorhergesagte Umlaufbahn völlig falsch. >

Beginn = "https://i.sstatic.net/yjjjh0lx.png"/>

Drücken Sie den Speicherplatz, während im Spielmodus die gleichen Probleme aufzeigen. Umlaufbahnen, indem Sie zu Beginn des Spiels im Editor -Modus bleiben. Ich bin schon kein Orbitalphysiker. Ich kann meinen Kopf einfach nicht umwickeln, was dieses Problem verursacht.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post