// Update is called once per frame private void SpawnSolarObject() { // don't continue coroutine if no objects to spawn if (solarObjects.Count <= 0 || _numSolarObjects >= _maxSolarObjects) { return; } //yield return TimerHelper.instance.StartTimer(randomWaitTime); int randomIndex = Random.Range(0, solarObjects.Count); // Get spawn parameters set SolarObject solarObjectPrefab = solarObjects[randomIndex]; Vector3 additionalHeightVector = new Vector3(0, Utility.ScreenUtilities.GetDistanceInWS(0.2f), 0); Vector3 aboveTopLeftOfScreen = Utility.ScreenUtilities.GetWSofSSPosition(0.0f, 1.0f) + additionalHeightVector; Vector3 aboveTopRightOfScreen = Utility.ScreenUtilities.GetWSofSSPosition(1.0f, 1.0f) + additionalHeightVector; float randomRangeBetweenLeftAndRight = Random.Range(0, 1.0f); Vector3 spawnPos = Vector3.Lerp(aboveTopLeftOfScreen, aboveTopRightOfScreen, randomRangeBetweenLeftAndRight); // Spawn solar object spawnPos.z = -80; SolarObject solarObjectInstance = Instantiate(solarObjectPrefab, spawnPos, Quaternion.identity, this.transform); _maxSolarObjects++; float randomWaitTime = Random.Range(_minSpawnTime, _maxSpawnTime); Invoke("SpawnSolarObject", randomWaitTime); }
public static double CalculateAcceleration(SolarObject of, SolarObject by) { // Gets distance between two objects var distance = GetDistance(of, by); // Uses the Gravitational Acceleration formula to determine the acceleration of one object due to another object (a = GM/r^2) return((GRAV * by.Mass) / (Math.Pow(distance, 2))); }
public static double GetDistance(SolarObject obj1, SolarObject obj2) { // Calculates difference between two X co-ordinates var x = obj1.Position.X - obj2.Position.X; // Calculates difference between two Y co-ordinates var y = obj1.Position.Y - obj2.Position.Y; // Calculates difference between two Z co-ordinates var z = obj1.Position.Z - obj2.Position.Z; // Uses the Pythagoras Theorem to calculate the total scalar distance between Obj1's position and Obj2's position return(Math.Sqrt(x * x + y * y + z * z)); }
public ObjectForm(Simulation sim, SolarObject s = null) { Sim = sim; InitializeComponent(); if (s != null) { Update(s); } else { SolarObject = new SolarObject(); } }
// Occurs when the Confirm button is clicked. private void ConfirmButton_Click(object sender, EventArgs e) { if (Mode == 0) { // Set the "Object" variable to be equal to the object selected in the list. Object = Objects.First(x => x.Name == ObjectList.SelectedItems[0].Text); } else { // Set the "Location" variable to be equal to the object position/velocity selected in the list (depending on mode) Location = Locations[ObjectList.SelectedItems[0].Text]; } // Sets the DialogResult of this Dialog window to "OK", meaning the parent form of this form will know that something has occured. DialogResult = DialogResult.OK; // Closes the form. Close(); }
private void Update(SolarObject s) { // This method fills in all fields in the ObjectForm that already have a corresponding value in the object's related SolarObject // This will only trigger if "Edit" was selected on a pre-existing object. SolarObject = s; NameTextbox.Text = s.Name; XPos.Text = s.Position.X.ToString(); YPos.Text = s.Position.Y.ToString(); ZPos.Text = s.Position.Z.ToString(); XVec.Text = s.Velocity.X.ToString(); YVec.Text = s.Velocity.Y.ToString(); ZVec.Text = s.Velocity.Z.ToString(); Mass.Text = s.Mass.ToString(); Radius.Text = s.Radius.ToString(); OrbitalSpeed.Text = s.OrbitalSpeed.ToString(); Obliquity.Text = s.Obliquity.ToString(); TrailLength.Text = s.TrailLength.ToString(); TrailsActive.Checked = SolarObject.TrailsActive; // Converting from OpenTK colour objects to System.Drawing colour objects in order to display the colour in the form. if (SolarObject.ObjectColour.ToArgb() != 0) { ObjectColour.BackColor = Color.FromArgb(SolarObject.ObjectColour.ToArgb()); } if (SolarObject.TrailColour.ToArgb() != 0) { TrailColour.BackColor = Color.FromArgb(SolarObject.TrailColour.ToArgb()); } // Only allow the "Trail Length" and "Trail Colour" values to be modified if the "Trails Active?" checkbox is ticked. if (TrailsActive.Checked) { TrailLength.Enabled = true; TrailColour.Enabled = true; TrailColourButton.Enabled = true; } // Takes focus away from any other button in the form, meaning no button is highlighted on form open. testButton.Select(); }
public static AggregateObject RecalculateValues(SolarObject main, List <SolarObject> all, float timePeriod) { // A list of all objects other than the object being calculated for is formed (as calculating an acceleration of an object due to itself is unnecessary) all = all.Where(x => x != main).ToList(); // Initial acceleration is 0. This value is added to throughout this method. Vector3 totalAcceleration = new Vector3(0, 0, 0); // Iterate through each object in the "all" list of SolarObjects. foreach (var obj in all) { // Acceleration of the main object due to the object currently being iterated through is calculated var acc = CalculateAcceleration(main, obj); // The position difference between the main object and the object currently being iterated through is calculated var posDiffVector = GetPositionDifference(obj.Position, main.Position); // This position difference vector is converted to a unit position vector var posDiffUnitVector = GetUnitVector(posDiffVector); // The unit position vector is formed into an acceleration vector var accVector = GetAccelerationVector(posDiffUnitVector, (float)acc); // Vector addition occurs here, adding the three-dimensional acceleration vector to the "totalAcceleration" value set before the for loop. // As the for loop iterated through, accelerations caused by various objects may cancel each other out, // and a resultant acceleration vector will be reached at the end of the for loop. totalAcceleration += accVector; } // The resultant acceleration vector is used to calculate a resultant velocity vector var velVector = GetVelocityVector(main, totalAcceleration, timePeriod); // The resultant velocity vector is used to calculate a resultant position for the object after the time elapsed (timePeriod) var posVector = GetPositionVector(main, velVector, timePeriod); // This calculation method is not perfect, as it is mathematically impossible to create a model that perfectly represents // three or more bodies affecting each other at all times. // Therefore, I am using the best method available to me, which is calculating the positions and velocities in "jumps" - time periods. // The lower the time period, the more accurate the simulation is. // The resultant velocity and position vectors are returned along with the SolarObject itself. return(new AggregateObject(main, velVector, posVector)); }
public static Vector3 GetPositionVector(SolarObject obj, Vector3 velVector, float timePeriod) { // Change in position is velocity multiplied by time, and so each position vector is increased by the relevant velocity vector multiplied by the time period return(new Vector3(obj.Position.X + (velVector.X * timePeriod), obj.Position.Y + (velVector.Y * timePeriod), obj.Position.Z + (velVector.Z * timePeriod))); }
public static Vector3 GetVelocityVector(SolarObject obj, Vector3 accVector, float timePeriod) { // Change in velocity is acceleration multiplied by time, and so each velocity vector is increased by the relevant acceleration vector multiplied by the time period return(new Vector3(obj.Velocity.X + (accVector.X * timePeriod), obj.Velocity.Y + (accVector.Y * timePeriod), obj.Velocity.Z + (accVector.Z * timePeriod))); }
public AggregateObject(SolarObject obj, Vector3 velocity, Vector3 position) { Object = obj; Velocity = velocity; Position = position; }