コード例 #1
0
ファイル: Circle.cs プロジェクト: AshleyLubin/C-
 public Circle()
 {
     x = 0;
     y = 0;
     r = 1;
     angleWithPrevious         = RandomManager.getDouble(-1.2, 1.2);
     angleWithPreviousVelocity = RandomManager.getDouble(0.009, 0.015);
     if (RandomManager.getDouble(-1, 1) < 0)
     {
         angleWithPreviousVelocity = -angleWithPreviousVelocity;
     }
     collisions = new Dictionary <Circle, double>();
     next       = new List <Circle>();
 }
コード例 #2
0
        public void PreventCollision()
        {
            //			Console.WriteLine("===== PreventCollision 2 =====");
            foreach (Circle current in circles)
            {
                //				Console.WriteLine("----- Circle " + current.num + " -----");
                if (current.collisions.Count > 0)
                {
                    //if (current.collisions.Count == 1)
                    {
                        //Console.WriteLine("CAS 1");
                        // Une collision, on donne des impulsions opposées et dans le bon sens aux cercles en collision
                        // 2 cas possibles :
                        // Cas 1 : les cercles sont parents.
                        // il n'y a pas de ramification entre les cercles (collision entre un cercle et 1 de ses ancêtres
                        // il faut donc modifier l'angle des noeuds
                        Circle collisionCircle = null;
                        foreach (var item in current.collisions)
                        {
                            collisionCircle = item.Key; break;
                        }

                        // Recherche de parent
                        Circle parent = current.previous;
                        bool   found  = false;
                        if (parent != null)
                        {
                            Circle collisionNext = current;                             // noeud fils du noeud en collision parent de current
                            while (parent != null && parent != collisionCircle)
                            {
                                collisionNext = parent; parent = collisionNext.previous;
                                if (parent == collisionCircle)
                                {
                                    found = true; break;
                                }
                            }

                            if (parent != null)                             // noeud parent
                            {
                                // Calcul de l'angle entre les centre des noeud en collision
                                double angleCollision     = GetAngleBetweenCircles(collisionNext, current);
                                double _2pi               = Math.PI * 2;
                                double collisionNextAngle = (collisionNext.angleWithPrevious - Math.PI) < 0 ? _2pi + (collisionNext.angleWithPrevious - Math.PI) : (collisionNext.angleWithPrevious - Math.PI);
                                collisionNextAngle = (collisionNextAngle) % _2pi >= 0 ? collisionNextAngle % _2pi : _2pi + collisionNextAngle % _2pi;
                                if (collisionNextAngle < angleCollision || (collisionNextAngle - angleCollision > Math.PI && collisionNextAngle > angleCollision))
                                {
                                    // Alors current est plus à droite que parentNext
                                    // il faut appliquer une vélocité négative à current et une positive à
                                    //if (current.angleWithPreviousVelocity <= 0) current.angleWithPreviousVelocity -= RandomManager.getDouble(0.001, 0.005);
                                    //else current.angleWithPreviousVelocity = 0;

                                    if (current.angleWithPreviousVelocity <= 0 || (current.angleWithPreviousVelocity > 0 && (current.angleWithPreviousVelocity < collisionNext.angleWithPreviousVelocity || Math.Abs(current.angleWithPreviousVelocity - collisionNext.angleWithPreviousVelocity) < 0.5)))
                                    {
                                        if (Math.Abs(current.angleWithPreviousVelocity) < Circle.maxVelocity / 3.0)
                                        {
                                            current.angleWithPreviousVelocity += RandomManager.getDouble(0.0015, 0.006);
                                        }
                                        else
                                        {
                                            current.angleWithPreviousVelocity = current.angleWithPreviousVelocity / 2.0;
                                        }

                                        if (Math.Abs(collisionNext.angleWithPreviousVelocity) < Circle.maxVelocity / 3.0)
                                        {
                                            collisionNext.angleWithPreviousVelocity -= RandomManager.getDouble(0.0015, 0.006);
                                        }
                                        else if (collisionNext.angleWithPreviousVelocity > 0)
                                        {
                                            collisionNext.angleWithPreviousVelocity = collisionNext.angleWithPreviousVelocity / 2.0;
                                        }

                                        if (current.angleWithPreviousVelocity > Circle.maxVelocity)
                                        {
                                            current.angleWithPreviousVelocity = Circle.maxVelocity;
                                        }
                                        if (collisionNext.angleWithPreviousVelocity < -Circle.maxVelocity)
                                        {
                                            collisionNext.angleWithPreviousVelocity = -Circle.maxVelocity;
                                        }
                                    }
                                }
                                else
                                {
                                    if (current.angleWithPreviousVelocity >= 0 || (current.angleWithPreviousVelocity < 0 && (current.angleWithPreviousVelocity < collisionNext.angleWithPreviousVelocity || Math.Abs(current.angleWithPreviousVelocity - collisionNext.angleWithPreviousVelocity) < 0.5)))
                                    {
                                        if (Math.Abs(current.angleWithPreviousVelocity) < Circle.maxVelocity / 3.0)
                                        {
                                            current.angleWithPreviousVelocity -= RandomManager.getDouble(0.0015, 0.006);
                                        }
                                        else
                                        {
                                            current.angleWithPreviousVelocity = current.angleWithPreviousVelocity / 2.0;
                                        }

                                        if (Math.Abs(collisionNext.angleWithPreviousVelocity) < Circle.maxVelocity / 3.0)
                                        {
                                            collisionNext.angleWithPreviousVelocity += RandomManager.getDouble(0.0015, 0.006);
                                        }
                                        else
                                        {
                                            collisionNext.angleWithPreviousVelocity = collisionNext.angleWithPreviousVelocity / 2.0;
                                        }

                                        if (current.angleWithPreviousVelocity < -Circle.maxVelocity)
                                        {
                                            current.angleWithPreviousVelocity = -Circle.maxVelocity;
                                        }
                                        if (collisionNext.angleWithPreviousVelocity > Circle.maxVelocity)
                                        {
                                            collisionNext.angleWithPreviousVelocity = Circle.maxVelocity;
                                        }
                                    }
                                }

                                // Calcul de la proximité entre les bords des cercles : distance entre les centre - les rayons des cercles.
                                // La proximité permet de déterminer la force de la répulsion entre les cercles.
                            }
                            else
                            {
                                if (current.num > 2)
                                {
                                    // Noeud d'une ramification
                                    // Cas 2 : il y a une ramification, il faut retrouver le premier parent commun et modifier les angles des cercles problématiques.
                                    // Construction de la liste des parent de current
                                    List <Circle> currentParents = new List <Circle>();
                                    parent = current.previous;
                                    while (parent != null)
                                    {
                                        currentParents.Add(parent); parent = parent.previous;
                                    }
                                    List <Circle> collisionParents = new List <Circle>();
                                    parent = collisionCircle.previous;
                                    while (parent != null)
                                    {
                                        collisionParents.Add(parent); parent = parent.previous;
                                    }

                                    Circle commonParent = null;
                                    foreach (var item in currentParents)
                                    {
                                        if (collisionParents.Contains(item))
                                        {
                                            commonParent = item; break;
                                        }
                                    }

                                    // calcul des angles entre le parent commun et les cercle en collision


                                    double angleCurrent       = GetAngleBetweenCircles(commonParent, current);
                                    double angleCollision     = GetAngleBetweenCircles(commonParent, collisionCircle);
                                    double _2pi               = Math.PI * 2;
                                    double collisionNextAngle = angleCollision < 0 ? _2pi + (angleCollision - Math.PI) : (angleCollision);

                                    if ((collisionNextAngle < angleCurrent && angleCurrent - collisionNextAngle < Math.PI) || (collisionNextAngle - angleCurrent > Math.PI && collisionNextAngle > angleCurrent))
                                    {
                                        // Alors current est plus à droite que parentNext
                                        // il faut appliquer une vélocité négative à current et une positive à
                                        //if (current.angleWithPreviousVelocity <= 0) current.angleWithPreviousVelocity -= RandomManager.getDouble(0.001, 0.005);
                                        //else current.angleWithPreviousVelocity = 0;

                                        if (current.angleWithPreviousVelocity <= 0 || (current.angleWithPreviousVelocity > 0 && (current.angleWithPreviousVelocity < collisionCircle.angleWithPreviousVelocity || Math.Abs(current.angleWithPreviousVelocity - collisionCircle.angleWithPreviousVelocity) < 0.05)))
                                        {
                                            if (Math.Abs(current.angleWithPreviousVelocity) < Circle.maxVelocity / 3.0)
                                            {
                                                current.angleWithPreviousVelocity += RandomManager.getDouble(0.0015, 0.006);
                                            }
                                            else
                                            {
                                                current.angleWithPreviousVelocity = current.angleWithPreviousVelocity / 2.0;
                                            }

                                            //if (Math.Abs(collisionCircle.angleWithPreviousVelocity) < Circle.maxVelocity / 3.0) collisionCircle.angleWithPreviousVelocity -= RandomManager.getDouble(0.0015, 0.006);
                                            //else collisionCircle.angleWithPreviousVelocity = collisionCircle.angleWithPreviousVelocity / 2.0;

                                            if (current.angleWithPreviousVelocity > Circle.maxVelocity)
                                            {
                                                current.angleWithPreviousVelocity = Circle.maxVelocity;
                                            }
                                            //if (collisionCircle.angleWithPreviousVelocity < -Circle.maxVelocity) collisionCircle.angleWithPreviousVelocity = -Circle.maxVelocity;
                                        }
                                    }
                                    else
                                    {
                                        if (current.angleWithPreviousVelocity >= 0 || (current.angleWithPreviousVelocity < 0 && (current.angleWithPreviousVelocity < collisionCircle.angleWithPreviousVelocity || Math.Abs(current.angleWithPreviousVelocity - collisionCircle.angleWithPreviousVelocity) < 0.5)))
                                        {
                                            if (Math.Abs(current.angleWithPreviousVelocity) < Circle.maxVelocity / 3.0)
                                            {
                                                current.angleWithPreviousVelocity -= RandomManager.getDouble(0.0015, 0.006);
                                            }
                                            else
                                            {
                                                current.angleWithPreviousVelocity = current.angleWithPreviousVelocity / 2.0;
                                            }

                                            //if (Math.Abs(collisionCircle.angleWithPreviousVelocity) < Circle.maxVelocity / 3.0) collisionCircle.angleWithPreviousVelocity += RandomManager.getDouble(0.0015, 0.006);
                                            //else collisionCircle.angleWithPreviousVelocity = collisionCircle.angleWithPreviousVelocity / 2.0;

                                            if (current.angleWithPreviousVelocity < -Circle.maxVelocity)
                                            {
                                                current.angleWithPreviousVelocity = -Circle.maxVelocity;
                                            }
                                            //if (collisionCircle.angleWithPreviousVelocity > Circle.maxVelocity) collisionCircle.angleWithPreviousVelocity = Circle.maxVelocity;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    //Console.WriteLine("Nothing to do");
                }
                //Console.WriteLine("-----------------------");
            }
        }