public override dynamic CalculateInteraction(Particle Input, Particle Comparison, Simulations.Simulation Sim)
        {
            //First we create a new force vector to store our result to
            Vector Force = new Vector(Input.NetForce.Capacity);

            //Make sure our input particle has "charge" and obtain it
            if (!Input.HasProperty("Charge")) return Force;
            double Charge = Input.GetPropertyVal("Charge");
            if (Charge == 0) return Force;

            //Determine the input's siblings
            List<Particle> Siblings;
            if (Input.ParentParticle != null)
            {
                Siblings = Input.ParentParticle.SubParticles;
            }
            else
            {
                //Assume top layer
                Siblings = Sim.SimUniverse.Particles;
            }

            //Get the electric and magnetic fields on the charge
            Vector ElectricField = CalculateElectricFieldAtPosition(Input.Position, Siblings, Sim.Parameters);
            Vector MagneticField = CalculateMagneticFieldAtPosition(Input.Position, Siblings, Sim.Parameters);

            //Calculate the Lorentz force
            Force = (Charge * ElectricField) + Vector.Vector_3DCross((Charge * Input.Velocity), MagneticField);

            //Return the new net force
            return Force;
        }
        public override dynamic CalculateInteraction(Particle Input, Particle Comparison, Simulations.Simulation Sim)
        {
            //First we create a new force vector to store our result to
            Vector Force = new Vector(Input.NetForce.Capacity);

            //Make sure both our input and comparison particles have "mass"
            if (!Input.HasProperty("Mass") || !Comparison.HasProperty("Mass")) return Force;

            //Now we calculate the actual distance between the particles (we will need this later)
            double ActualDistance = (Comparison.Position - Input.Position).Magnitude;
            Vector Dir = (Input.Position - Comparison.Position).Direction;

            //If the "Precision" simulation parameter is available to us:
            if (Sim.Parameters.HasParam("Precision"))
            {
                //Check to see if the actual distance is under the precision value
                if ((System.Math.Abs(ActualDistance) - Input.Radius - Comparison.Radius) <= Sim.Parameters.GetParam("Precision"))
                {
                    //Return no change in acceleration
                    return new Vector(Input.Acceleration.Count);
                }
            }
            else //Otherwise:
            {
                //Assume a precision of zero
                if ((System.Math.Abs(ActualDistance) - Input.Radius - Comparison.Radius) <= 0)
                {
                    //Return no change in acceleration
                    return new Vector(Input.Acceleration.Count);
                }
            }

            //Get all of our needed parts
            double InputMass = Input.GetPropertyVal("Mass");
            double ComparisonMass = Comparison.GetPropertyVal("Mass");
            double GravitationalConstant;
            if (Sim.Parameters.HasParam("GravitationalConstant"))
            {
                GravitationalConstant = Sim.Parameters.GetParam("GravitationalConstant");
            }
            else
            {
                GravitationalConstant = PhysicsConstants.GravitationalConstant;
            }

            Force = GravitationalConstant * InputMass * ComparisonMass / ActualDistance * Dir;

            //Return the new net force
            return Force;
        }
        public override dynamic CalculateInteraction(Particle Input, Particle Comparison, Simulation Sim)
        {
            //First we create a new force vector to store our result to
            Vector Force = new Vector(Input.NetForce.Capacity);

            //Make sure both our input and comparison particles have "mass"
            if (!Input.HasProperty("Mass") || !Comparison.HasProperty("Mass")) return Force;

            //Now we calculate the actual distance between the particles (we will need this later)
            double ActualDistance = (Comparison.Position - Input.Position).Magnitude;
            if (ActualDistance == 0) return new Vector(Input.Acceleration.Count);

            //Assume a precision of zero
            if ((ActualDistance - Input.Radius - Comparison.Radius) <= 0)
            {
                //Return no change in acceleration
                return new Vector(Input.Acceleration.Count);
            }

            //If the "SofteningValue" simulation parameter is available to us:
            double Denominator = System.Math.Pow((ActualDistance * ActualDistance), (3.0 / 2.0));

            //Get all of our needed parts
            double InputMass = Input.GetPropertyVal("Mass");
            double ComparisonMass = Comparison.GetPropertyVal("Mass");

            //For each dimension of movement/location:
            for (int i = 0; i < Force.Capacity; i++)
            {
                //Calculate the component distance of this dimension
                double ComponentDistance = Comparison.Position[i] - Input.Position[i];

                //Calculate the new force
                Force[i] = (SimMath.GenerateRandomDouble(-ComparisonMass, ComparisonMass) * ComponentDistance) / Denominator;
            }

            //Return the new net force
            return Force;
        }
        public override dynamic CalculateInteraction(Particle Input, Particle Comparison, Simulation Sim)
        {
            //First we create a new force vector to store our result to
            Vector Force = new Vector(Input.NetForce.Capacity);

            //Make sure both our input and comparison particles have "mass"
            if (!Input.HasProperty("Mass") || !Comparison.HasProperty("Mass")) return Force;

            //Now we calculate the actual distance between the particles (we will need this later)
            double ActualDistance = (Comparison.Position - Input.Position).Magnitude;
            if (ActualDistance == 0) return new Vector(Input.Acceleration.Count);

            //If the "Precision" simulation parameter is available to us:
            if (Sim.Parameters.HasParam("Precision"))
            {
                //Check to see if the actual distance is under the precision value
                if ((ActualDistance - Input.Radius - Comparison.Radius) <= Sim.Parameters.GetParam("Precision"))
                {
                    //Return no change in acceleration
                    return new Vector(Input.Acceleration.Count);
                }
            }
            else //Otherwise:
            {
                //Assume a precision of zero
                if ((ActualDistance - Input.Radius - Comparison.Radius) <= 0)
                {
                    //Return no change in acceleration
                    return new Vector(Input.Acceleration.Count);
                }
            }

            //If the "SofteningValue" simulation parameter is available to us:
            double Denominator;
            if (Sim.Parameters.HasParam("SofteningValue"))
            {
                //Calculate the denominator of the equation
                double SofteningValue = Sim.Parameters.GetParam("SofteningValue");
                Denominator = System.Math.Pow(((ActualDistance * ActualDistance) + (SofteningValue * SofteningValue)), (3.0 / 2.0));
            }
            else //Otherwise:
            {
                //Calculate the denominator of the equation
                Denominator = System.Math.Pow((ActualDistance * ActualDistance), (3.0 / 2.0));
            }

            //Get all of our needed parts
            double InputMass = Input.GetPropertyVal("Mass");
            double ComparisonMass = Comparison.GetPropertyVal("Mass");
            double GravitationalConstant;
            if (Sim.Parameters.HasParam("GravitationalConstant"))
            {
                GravitationalConstant = Sim.Parameters.GetParam("GravitationalConstant");
            }
            else
            {
                GravitationalConstant = PhysicsConstants.GravitationalConstant;
            }

            //For each dimension of movement/location:
            for (int i = 0; i < Force.Capacity; i++)
            {
                //Calculate the component distance of this dimension
                double ComponentDistance = Comparison.Position[i] - Input.Position[i];

                //Calculate the new force
                Force[i] = GravitationalConstant * (InputMass * ComparisonMass * ComponentDistance) / Denominator;
            }

            //Return the new net force
            return Force;
        }