//Checks if atleast 3 inputs in a single dimention have been inputted //Checks if dimentions active have atleast 2 dimentiosn entered (min amount for calculation) //Returns true or false private static bool IsValid(ref newParticle values, int dimentions) { Debug.Log("Is valid ran"); //Bool based on if the program has atleast 1 dimention with three inputs int[] numberOfInputs = values.numberOfInputs; bool minThreeInputs = numberOfInputs[0] >= 3 || numberOfInputs[1] >= 3 || numberOfInputs[2] >= 3; Debug.Log("Is valid ran"); //Bool if all dimentions have 3 inputs bool allAboveThree = getAboveThree(values, dimentions); //Gets the number of inputs above 2 from all dimentions active int numberAboveTwo = GetNumberAboveN(values, 2, dimentions); Debug.Log("Is valid ran"); //Must have atleast 3 inputs and other dimentions have more than 2 inputs OR if all dimentions have 3 inputs Debug.Log("Isvalid done"); if ((minThreeInputs == true && numberAboveTwo == dimentions) || allAboveThree == true) { return(true); } else { return(false); } }
//Updates values of the UI with the values inside of the Particle parameter given in each dimention public void UpdateUI(newParticle values) { S_x.text = values.displacement[0].ToString(); S_y.text = values.displacement[1].ToString(); S_z.text = values.displacement[2].ToString(); U_x.text = values.initialVelocity[0].ToString(); U_y.text = values.initialVelocity[1].ToString(); U_z.text = values.initialVelocity[2].ToString(); V_x.text = values.currentVelocity[0].ToString(); V_y.text = values.currentVelocity[1].ToString(); V_z.text = values.currentVelocity[2].ToString(); A_x.text = values.acceleration[0].ToString(); A_y.text = values.acceleration[1].ToString(); A_z.text = values.acceleration[2].ToString(); Time.text = values.motionTime.ToString(); R_x.text = values.initialPosition[0].ToString(); R_y.text = values.initialPosition[1].ToString(); R_z.text = values.initialPosition[2].ToString(); Radius.text = values.diameter.ToString(); }
//Calculates and assigns values for non-suvat inputs private void MiscInfomation() { newParticle particle = newParticle.ParticleInstances[Suvat_UiController.instance.DropBox_Particle.value]; //Collisions enabled if (Toggle_Collisions.isOn == true) { //a particle with collisions must have collisions and restitution values particle.AddParticlePropery(newParticle.Properties.collisions); particle.collisions = true; particle.AddParticlePropery(newParticle.Properties.restitution); particle.restitution = Slider_Restitution.value; } //gravity enabled if (Toggle_Gravity.isOn == true) { particle.AddParticlePropery(newParticle.Properties.gravity); particle.gravity = true; } //updating mass value if (particle.hasMass) { particle.mass = Slider_Mass.value; } //no mass therefore must add component before assigning mass value else { particle.AddParticlePropery(newParticle.Properties.mass); particle.mass = Slider_Mass.value; } }
//Calculations when a border collision occurs private void BorderCollisionCalculation(Collider other) { newParticle particle = newParticle.ParticleInstances[particleIndex]; //particles in the collision must have collisions enabled if (particle.hasCollisions == false || particle.hasRestitution == false) { return; } //Gets restitution calculaues from the slider and from particle //Border collisions only occurs in the collisions module therefore can call the Collisions_InputController script float BorderRestitution = Collisions_InputController.Instance.Slider_BorderRestitution.value; float Restitution = particle.restitution; Vector3 previousVelocity = particle.currentVelocity; //Horizontal border (y velocity changes) if (other.transform.localScale.x > other.transform.localScale.y) { //If collided with a horizontal border then only the Y is afected by reversing the direction and multiplying by the restitutions particle.currentVelocity = new Vector3( previousVelocity.x, -1 * (BorderRestitution * Restitution) * previousVelocity.y, previousVelocity.z); } //Vertical border ( x velocity changes) else if (other.transform.localScale.x < other.transform.localScale.y) { //If collided with a vertical border then only the X is afected by reversing the direction and multiplying by the restitutions particle.currentVelocity = new Vector3( -1 * (BorderRestitution * Restitution) * previousVelocity.x, previousVelocity.y, previousVelocity.z); } }
//Gets non suvat based inputs from the UI and sassigns values to the particle instance private static void getMisc(ref newParticle values) { //Reference to the UI instance that being used Suvat_UiController controller = Suvat_UiController.instance; //Radius cannot be empty text or 0 if (controller.Radius.text != "" && controller.Radius.text != "0") { //converts text to float from the input field values.diameter = float.Parse(controller.Radius.text); } else { //If the radius has not been stated or =0 then a default value of 1 is assigned. values.diameter = 1; } try { //If the gravity toggle has been enabled if (controller.Gravity.isOn == true) { //gravity must be added.Gravity is negative therefore a vector subtraction occurs of the magnitude of gravity. //Y component only values.acceleration -= new Vector3(0, Gravity, 0); } } catch (NullReferenceException) { } }
//Ran when a Suvat calculation is too occur on the passed in instance of Particle. public static newParticle FindEquation(newParticle values) { //i is the dimention to calculate int i = 0; //Dictionary reference between key and function to be ran //When the key is indexed the function is ran with parameters values and i var Equations = new Dictionary <string, Action> { { "00111", () => RanOn_00111(values, i) }, { "01110", () => RanOn_01110(values, i) }, { "01011", () => RanOn_01011(values, i) }, { "01101", () => RanOn_01101(values, i) }, { "01111", () => RanOn_01111(values, i) }, { "10011", () => RanOn_10011(values, i) }, { "10101", () => RanOn_10101(values, i) }, { "10110", () => RanOn_10110(values, i) }, { "10111", () => RanOn_10111(values, i) }, { "11001", () => RanOn_11001(values, i) }, { "11010", () => RanOn_11010(values, i) }, { "11011", () => RanOn_11011(values, i) }, { "11100", () => RanOn_11100(values, i) }, { "11101", () => RanOn_11101(values, i) }, { "11110", () => RanOn_11110(values, i) }, { "11111", () => RanOn_11111(values, i) }, }; //The emergency escape incase something goes wrong //Prevents an infinite loop int j = 0; int maxj = 10; //While their are still values to calculate in any dimentions //and not all dimentions have invalid inputs while (((values.numberOfInputs[0] != 5 && values.numberOfInputs[1] != 5 && values.numberOfInputs[2] != 5) || (values.invalidInputs[0] == false || values.invalidInputs[1] == false || values.invalidInputs[2] == false)) && (j < maxj)) { //Dimention has 3 or more inputs if (values.numberOfInputs[0] >= 3) { i = 0; //Calls the corressponding equation Equations[values.key[i]](); } //Dimention has 3 or more inputs if (values.numberOfInputs[1] >= 3) { i = 1; //Calls the corressponding equation Equations[values.key[i]](); } //Dimention has 3 or more inputs if (values.numberOfInputs[2] >= 3) { i = 2; //Calls the corressponding equation Equations[values.key[i]](); } j++; } return(values); }
//V = u + at , rearranged for t public static void RanOn_11110(newParticle values, int dimention) { //Diffrent equations are used depending on acceleration if (values.acceleration[dimention] == 0) { //Cannot divide by 0 if ((values.initialVelocity[dimention] + values.currentVelocity[dimention]) != 0) { values.motionTime = 2 * values.displacement[dimention] / (values.initialVelocity[dimention] + values.currentVelocity[dimention]); values.key[0] = ReplaceAtIndex(4, '1', values.key[0]); values.key[1] = ReplaceAtIndex(4, '1', values.key[1]); values.key[2] = ReplaceAtIndex(4, '1', values.key[2]); } else { values.invalidInputs[dimention] = true; } } else { //Time calculations change the Key in 3 dimentions because time is shared values.motionTime = (values.currentVelocity[dimention] - values.initialVelocity[dimention]) / values.acceleration[dimention]; values.key[0] = ReplaceAtIndex(4, '1', values.key[0]); values.key[1] = ReplaceAtIndex(4, '1', values.key[1]); values.key[2] = ReplaceAtIndex(4, '1', values.key[2]); } }
//Creates then returns a particle with properties for the gravity simulator public static newParticle CreateGravityParticle() { newParticle particle = new newParticle(); particle.AddParticlePropery(newParticle.Properties.MyGameObject); particle.AddParticlePropery(newParticle.Properties.ParticlePrefabs); particle.AddParticlePropery(newParticle.Properties.ParticleSprites); particle.AddParticlePropery(newParticle.Properties.initialVelocity); particle.AddParticlePropery(newParticle.Properties.currentVelocity); particle.AddParticlePropery(newParticle.Properties.diameter); particle.AddParticlePropery(newParticle.Properties.restitution); particle.AddParticlePropery(newParticle.Properties.mass); particle.AddParticlePropery(newParticle.Properties.gravity); particle.AddParticlePropery(newParticle.Properties.collisions); particle.AddParticlePropery(newParticle.Properties.graphingValuesAcceleration); particle.AddParticlePropery(newParticle.Properties.graphingValuesSpeed); //Creates the gameobject for the gravity particle particle.CreateGravityObject(); particle.graphingValuesAcceleration = new List <Vector2>(); particle.graphingValuesSpeed = new List <Vector2>(); //Sets initial values for the gravity particle (defaults) particle.initialVelocity = Vector3.zero; particle.diameter = 0.25f; particle.restitution = 1; particle.mass = 1.0f; particle.gravity = true; particle.collisions = true; //returns particle which has been created return(particle); }
public void HyperbolicEncounter() { newParticle bigMass = newParticle.CreateGravityParticle(); bigMass.diameter = 0.25f; bigMass.mass = 2.3f; bigMass.initialVelocity = Vector3.zero; bigMass.MyGameObject.transform.position = new Vector3( 1, 0, 0); //Changes sprite to an earth sprite bigMass.MyGameObject.GetComponent <SpriteRenderer>().sprite = Resources.Load("Planet_Sprites\\earth-like", typeof(Sprite)) as Sprite; newParticle.ParticleInstances.Add(bigMass); newParticle smallMass = newParticle.CreateGravityParticle(); smallMass.diameter = 0.1f; smallMass.mass = 0.01f; smallMass.MyGameObject.transform.position = new Vector3( -3, 5f, 0); smallMass.MyGameObject.name = "Moon"; //Changes sprite to a moon-like sprite smallMass.MyGameObject.GetComponent <SpriteRenderer>().sprite = Resources.Load("Planet_Sprites\\Ice-Planet", typeof(Sprite)) as Sprite; //Velocity in X component required for perfect circular motion smallMass.initialVelocity = new Vector3( 2.5f, -1f, 0); newParticle.ParticleInstances.Add(smallMass); AddToDropBoxs(2); }
//Method which creates a Collisions particle //Adds required properties //Sets default values //Create GameObject scene public static newParticle CreateCollisionsParticle() { //Properties added to the particle newParticle particle = new newParticle(); particle.AddParticlePropery(newParticle.Properties.MyGameObject); particle.AddParticlePropery(newParticle.Properties.ParticlePrefabs); particle.AddParticlePropery(newParticle.Properties.initialVelocity); particle.AddParticlePropery(newParticle.Properties.currentVelocity); particle.AddParticlePropery(newParticle.Properties.diameter); particle.AddParticlePropery(newParticle.Properties.restitution); particle.AddParticlePropery(newParticle.Properties.mass); particle.AddParticlePropery(newParticle.Properties.collisions); particle.AddParticlePropery(newParticle.Properties.graphingValuesMomentumX); particle.AddParticlePropery(newParticle.Properties.graphingValuesMomentumY); //Creates gameobject for the scene particle.CreateCollisionsObject(); particle.graphingValuesMomentumX = new List <Vector2>(); particle.graphingValuesMomentumY = new List <Vector2>(); //Default values particle.initialVelocity = Vector3.zero; particle.diameter = 0.25f; particle.restitution = 1; particle.mass = 1.0f; particle.collisions = true; //returns particle return(particle); }
//Creates and gives random values to particles private void CreateRandomParticle() { //UnityEngine.Random.RandomRange generates a float between min and max newParticle random = newParticle.CreateCollisionsParticle(); random.initialVelocity = new Vector2( UnityEngine.Random.Range(-5f, 5f), UnityEngine.Random.Range(-5f, 5f)); random.mass = UnityEngine.Random.Range(1f, 5f); random.restitution = UnityEngine.Random.Range(1f, 1f); random.diameter = UnityEngine.Random.Range(1f, 1.5f); float minX = BorderLeft.transform.position.x + random.diameter / 2 + (BorderLeft.GetComponent <Renderer>().bounds.size.x / 2); float maxX = BorderRight.transform.position.x - random.diameter / 2 - (BorderRight.GetComponent <Renderer>().bounds.size.x / 2); float minY = BorderBottom.transform.position.y + random.diameter / 2 + (BorderBottom.GetComponent <Renderer>().bounds.size.y / 2); float maxY = BorderTop.transform.position.y - random.diameter / 2 - (BorderTop.GetComponent <Renderer>().bounds.size.y / 2); Vector3 newPosition = new Vector2( UnityEngine.Random.Range(minX, maxX), UnityEngine.Random.Range(minY, maxY)); random.MyGameObject.transform.position = newPosition; newParticle.ParticleInstances.Add(random); }
//Performs and controls the maths of the calculations private void CalculateCollision(newParticle first, newParticle second) { //Checking that particles in collisions are valid to collide if (first.hasCollisions == false || first.hasRestitution == false || second.hasCollisions == false || second.hasRestitution == false) { return; } //Getting unit direction vector Vector3 deltaPosition = first.MyGameObject.transform.position - second.MyGameObject.transform.position; Vector3 unitDirection = (deltaPosition) / (MyMaths.Vector_Magnitude(deltaPosition)); //Getting velocity parrlele and perpendicular before colllisiosn Vector3 FirstParrelleVelocity = CalculateParrelelVelocity(first.currentVelocity, unitDirection); Vector3 FirstPerpendicularVelocity = first.currentVelocity - FirstParrelleVelocity; Vector3 SecondParrelleVelocity = CalculateParrelelVelocity(second.currentVelocity, unitDirection); Vector3 SecondPerpendicularVelocity = second.currentVelocity - SecondParrelleVelocity; float first_e = first.restitution; float second_e = second.restitution; //Relative restitution float e = first_e * second_e; float m = first.mass; float M = second.mass; //maths first.currentVelocity = CalculateAfterVelocityFirst(m, M, FirstParrelleVelocity, SecondParrelleVelocity, e) + FirstPerpendicularVelocity; second.currentVelocity = CalculateAfterVelocitySecond(m, M, FirstParrelleVelocity, SecondParrelleVelocity, e) + SecondPerpendicularVelocity; }
// s = ut + 1/2 * a * t^2 rearranged for u public static void RanOn_10011(newParticle values, int dimention) { Vector3 temp = values.initialVelocity; temp[dimention] = (values.displacement[dimention] / values.motionTime) - 0.5f * (values.acceleration[dimention] * values.motionTime); values.initialVelocity = temp; values.key[dimention] = ReplaceAtIndex(1, '1', values.key[dimention]); }
// s = ut + 1/2 * a * t^2 public static void RanOn_01011(newParticle values, int dimention) { Vector3 temp = values.displacement; temp[dimention] = values.initialVelocity[dimention] * values.motionTime + 0.5f * values.acceleration[dimention] * Mathf.Pow(values.motionTime, 2); values.displacement = temp; values.key[dimention] = ReplaceAtIndex(0, '1', values.key[dimention]); }
//V = u + at public static void RanOn_11011(newParticle values, int dimention) { Vector3 temp = values.currentVelocity; temp[dimention] = values.initialVelocity[dimention] + values.acceleration[dimention] * values.motionTime; values.currentVelocity = temp; values.key[dimention] = ReplaceAtIndex(2, '1', values.key[dimention]); }
//Updates UI with values from a particle public void UpdateUI(newParticle values) { InputField_VelocityX.text = values.currentVelocity.x.ToString(); InputField_VelocityY.text = values.currentVelocity.y.ToString(); Slider_Mass.value = values.mass; Slider_Restitution.value = values.restitution; Slider_Radius.value = values.diameter; }
// s = 1/2 (u + v) t public static void RanOn_01101(newParticle values, int dimention) { Vector3 temp = values.displacement; temp[dimention] = 0.5f * (values.initialVelocity[dimention] + values.currentVelocity[dimention]) * values.motionTime; values.displacement = temp; values.key[dimention] = ReplaceAtIndex(0, '1', values.key[dimention]); }
//S = vt - 1/2 a t^2 private static void RanOn_00111(newParticle values, int dimention) { //S = vt - 1/2 a t^2 Vector3 temp = values.displacement; temp[dimention] = values.currentVelocity[dimention] * values.motionTime - 0.5f * (values.acceleration[dimention] * Mathf.Pow(values.motionTime, 2)); values.displacement = temp; values.key[dimention] = ReplaceAtIndex(0, '1', values.key[dimention]); }
//Updates UI with values from a planet public void UpdateUI(newParticle values) { Inputfield_VelocityX.text = values.currentVelocity.x.ToString(); Inputfield_VelocityY.text = values.currentVelocity.y.ToString(); Slider_Mass.value = values.mass; Slider_Diameter.value = values.diameter; //Updates UI values OnMassSliderChanged(); OnRadiusChanged(); }
private void CreateFirstParticle() { //Assigns default values to the particle newParticle particle = newParticle.CreateCollisionsParticle(); particle.initialVelocity = Vector3.zero; particle.mass = 1.0f; particle.restitution = 1.0f; particle.diameter = 1.0f; //Adds particle to the list which causes the prefab to be instatiated newParticle.ParticleInstances.Add(particle); }
//Returns if all dmentions active have 3 or more inputs private static bool getAboveThree(newParticle values, int dimentions) { bool allAbove = true; int[] numberOfInputs = values.numberOfInputs; for (int i = 0; i < dimentions; i++) { if (numberOfInputs[i] < 3) { allAbove = false; } } return(allAbove); }
//Creates a planet to be centered in the screen when scene loads private void CreateFirstObject() { if (newParticle.ParticleInstances.Count == 0) { //Assigns default values to the particle newParticle particle = newParticle.CreateGravityParticle(); newParticle.ParticleInstances.Add(particle); //Update values for UI OnRadiusChanged(); OnMassSliderChanged(); //remember restitution } }
private Vector3 GetAccelleration(newParticle particle) { Vector3 accelerationCounter = Vector3.zero; if (particle.hasGravity && particle.hasMass) { accelerationCounter = GetAccellerationGravity(particle); } if (particle.hasAcceleration) { accelerationCounter += particle.acceleration; } return(accelerationCounter); }
//Gets the inputs from the user for each Suvat quantitity in the X dimention //If the input is not NULL then Key is updated for the dimention and element private static void GetInput_Suvat_x(ref newParticle values, int dimentions) { //float.parse converts a string to float type //Reference to the UI element Suvat_UiController controller = Suvat_UiController.instance; if (controller.S_x.text != "") { Vector3 temp = values.displacement; temp[0] = float.Parse(controller.S_x.text); values.displacement = temp; values.key[0] = ReplaceAtIndex(0, '1', values.key[0]); } if (controller.U_x.text != "") { Vector3 temp = values.initialVelocity; temp[0] = float.Parse(controller.U_x.text); values.initialVelocity = temp; values.key[0] = ReplaceAtIndex(1, '1', values.key[0]); } if (controller.V_x.text != "") { Vector3 temp = values.currentVelocity; temp[0] = float.Parse(controller.V_x.text); values.currentVelocity = temp; values.key[0] = ReplaceAtIndex(2, '1', values.key[0]); } if (controller.A_x.text != "") { Vector3 temp = values.acceleration; temp[0] = float.Parse(controller.A_x.text); values.acceleration = temp; values.key[0] = ReplaceAtIndex(3, '1', values.key[0]); } if (controller.Time.text != "") { values.motionTime = float.Parse(controller.Time.text); //Time shared between all dimentions values.key[0] = ReplaceAtIndex(4, '1', values.key[0]); values.key[1] = ReplaceAtIndex(4, '1', values.key[1]); values.key[2] = ReplaceAtIndex(4, '1', values.key[2]); } if (controller.R_x.text != "") { Vector3 temp = values.initialPosition; temp[0] = float.Parse(controller.R_x.text); values.initialPosition = temp; } }
//s = 0.5 * *u+v)t , rearranged for v public static void RanOn_11001(newParticle values, int dimention) { //Cannot divide by 0 therefore will be invalid input. if (values.motionTime == 0) { values.invalidInputs[dimention] = true; } else { Vector3 temp = values.currentVelocity; temp[dimention] = 2 * (values.displacement[dimention] / values.motionTime) - values.initialVelocity[dimention]; values.currentVelocity = temp; values.key[dimention] = ReplaceAtIndex(2, '1', values.key[dimention]); } }
// V^2 = u^2 + 2as reaaragned for a public static void RanOn_11100(newParticle values, int dimention) { //Cannot divide by 0 which would cause invalid inputs if (values.displacement[dimention] == 0) { values.invalidInputs[dimention] = true; } else { Vector3 temp = values.acceleration; temp[dimention] = (Mathf.Pow(values.currentVelocity[dimention], 2) - Mathf.Pow(values.initialVelocity[dimention], 2)) / (2 * values.displacement[dimention]); values.acceleration = temp; values.key[dimention] = ReplaceAtIndex(3, '1', values.key[dimention]); } }
//V = u + at , rearranged for a public static void RanOn_11101(newParticle values, int dimention) { //Cannot divide by 0 if (values.motionTime == 0) { values.invalidInputs[dimention] = true; } else { Vector3 temp = values.acceleration; temp[dimention] = (values.currentVelocity[dimention] - values.initialVelocity[dimention]) / values.motionTime; values.acceleration = temp; values.key[dimention] = ReplaceAtIndex(3, '1', values.key[dimention]); } }
//S = (v^2-u^2) / 2a private static void RanOn_01110(newParticle values, int dimention) { //cannot devide by 0.Therefore would be invalid input if (values.acceleration[dimention] != 0) { //S = (v^2-u^2) / 2a Vector3 temp = values.displacement; temp[dimention] = (Mathf.Pow(values.currentVelocity[dimention], 2) - Mathf.Pow(values.initialVelocity[dimention], 2)) / (2 * values.acceleration[dimention]); values.displacement = temp; values.key[dimention] = ReplaceAtIndex(0, '1', values.key[dimention]); } else { values.invalidInputs[dimention] = true; } }
// V^2 = u^2 + 2as reaaragned for u public static void RanOn_10110(newParticle values, int dimention) { float InsideRoot = Mathf.Pow(values.currentVelocity[dimention], 2) - 2 * values.acceleration[dimention] * values.displacement[dimention]; //Square root must be positive if (InsideRoot < 0) { values.invalidInputs[dimention] = true; } else { Vector3 temp = values.initialVelocity; temp[dimention] = Mathf.Sqrt(InsideRoot); values.initialVelocity = temp; values.key[dimention] = ReplaceAtIndex(1, '1', values.key[dimention]); } }
//Creates the earth planet and gameobject private void CreateEarth() { newParticle earth = newParticle.CreateGravityParticle(); earth.MyGameObject.name = "Earth"; earth.diameter = 0.25f; earth.mass = 1; earth.initialVelocity = Vector3.zero; earth.MyGameObject.transform.position = new Vector3( 0, -2, 0); //Changes sprite to an earth sprite earth.MyGameObject.GetComponent <SpriteRenderer>().sprite = Resources.Load("Planet_Sprites\\earth-like", typeof(Sprite)) as Sprite; newParticle.ParticleInstances.Add(earth); }