Пример #1
0
        public static Vector GravityForce(MaterialPoint b1, MaterialPoint b2, double G)
        {
            double forceAbs;
            Vector forceOX;

            if (b1.Coordinates == b2.Coordinates)
            {
                return(Vector.ZeroVector());
            }

            forceAbs = G * (b1.Mass * b2.Mass) / (Math.Pow(b1.DistanceTo(b2), 2));
            forceOX  = new Vector(forceAbs, 0);
            forceOX  = forceOX.RotateTo(b2.Coordinates - b1.Coordinates);

            return(forceOX);
        }
Пример #2
0
        private void UpdateField()
        {
            Vector[] forces = new Vector[Bodies.Count];
            Vector   currForce, acceleration;
            int      i, j;
            bool     countingNeeded = true;

            for (i = 0; i < Bodies.Count; i++)
            {
                forces[i] = Vector.ZeroVector();
            }

            for (i = 0; i < Bodies.Count; i++)
            {
                for (j = 0; j < Bodies.Count; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }

                    if (CollisionsType == CollisionType.InelasticCollisions)
                    {
                        /*Check if bodies collided*/
                        if (Bodies[i] is PhysicalBody && Bodies[j] is PhysicalBody)
                        {
                            if (Bodies[i].DistanceTo(Bodies[j]) < ((PhysicalBody)Bodies[i]).Diameter + ((PhysicalBody)Bodies[j]).Diameter)
                            {
                                MaterialPoint newBody = new PhysicalBody(
                                    coordinates: Bodies[i].Coordinates,
                                    mass: Bodies[i].Mass + Bodies[j].Mass,
                                    /*Momentum conservation law*/
                                    velocity: (Bodies[i].Velocity * Bodies[i].Mass + Bodies[j].Velocity * Bodies[j].Mass) / (Bodies[i].Mass + Bodies[j].Mass),
                                    /*Sum of volumes*/
                                    diameter: Math.Pow(Math.Pow(((PhysicalBody)Bodies[i]).Diameter, 3) + Math.Pow(((PhysicalBody)Bodies[j]).Diameter, 3), (double)1 / 3)
                                    );

                                /*First must be deleted the last. In other cases this will cause an exception*/
                                BodyDeletedRaise(Math.Max(i, j));
                                BodyDeletedRaise(Math.Min(i, j));
                                Bodies.RemoveAt(Math.Max(i, j));
                                Bodies.RemoveAt(Math.Min(i, j));

                                BodyAddedRaise(newBody);
                                Bodies.Add(newBody);

                                countingNeeded = false;
                            }
                        }
                    }
                    else if (CollisionsType == CollisionType.ElasticCollisions)
                    {
                        /*Check if bodies collided*/
                        if (Bodies[i] is PhysicalBody && Bodies[j] is PhysicalBody)
                        {
                            if (Bodies[i].DistanceTo(Bodies[j]) < ((PhysicalBody)Bodies[i]).Diameter + ((PhysicalBody)Bodies[j]).Diameter)
                            {
                                double m1 = Bodies[i].Mass, m2 = Bodies[j].Mass;
                                Vector v1 = Bodies[i].Velocity, v2 = Bodies[j].Velocity;

                                /*Momentum conservation law*/
                                Bodies[i].Velocity = (m1 - m2) / (m1 + m2) * (v1 - v2) + v2;
                                Bodies[j].Velocity = (2 * m1 * v1) / (m1 + m2) + v2;

                                countingNeeded = false;
                            }
                        }
                    }

                    if (countingNeeded)
                    {
                        currForce  = MaterialPoint.GravityForce(Bodies[i], Bodies[j], G);
                        forces[i] += currForce;
                    }
                }
            }

            for (i = 0; i < Bodies.Count; i++)
            {
                acceleration           = forces[i] / Bodies[i].Mass;
                Bodies[i].Velocity     = Bodies[i].Velocity + acceleration * DeltaTime;
                Bodies[i].Coordinates += Bodies[i].Velocity * DeltaTime;
            }
        }
Пример #3
0
 private void BodyAddedRaise(MaterialPoint body)
 {
     BodyAdded?.Invoke(body);
 }
Пример #4
0
 public double DistanceTo(MaterialPoint b2) => (Coordinates - b2.Coordinates).Length;