Esempio n. 1
0
 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>();
 }
Esempio n. 2
0
        public void Animate()
        {
            foreach (Circle circle in circles)
            {
                double deltaX = Math.Abs(circle.x - circle.BoundingCircle_x);
                double deltaY = Math.Abs(circle.y - circle.BoundingCircle_y);
                double dist   = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
                double distR  = dist + circle.r;

                if (distR <= circle.BoundingCircle_r)
                {
                    circle.x += RandomManager.getDistance();
                }
                else if (distR > circle.BoundingCircle_r)
                {
                }
            }
        }
Esempio n. 3
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("-----------------------");
            }
        }
Esempio n. 4
0
        public static Pack BuildPack(int circleNb, int numBig, int diametreMax, int yCircle)
        {
            Pack pack = new Pack()
            {
                DiametreMax = diametreMax
            };

            R = diametreMax;

            // Create circles
            circles = new List <Circle>()
            {
                new Circle()
                {
                    num = 1
                }, new Circle()
                {
                    num = 2
                }, new Circle()
                {
                    num = 3
                }
            };
            if (circleNb > 3)
            {
                circles.Add(new Circle()
                {
                    num = 4
                });
            }
            if (circleNb > 4)
            {
                circles.Add(new Circle()
                {
                    num = 5
                });
            }
            if (circleNb > 5)
            {
                circles.Add(new Circle()
                {
                    num = 6
                });
            }

            // Big One position
            int bigOnePosition = numBig;

            // Radius
            List <double> rayon = new List <double>();

            //if (circleNb == 6)
            //{
            //    rayon.Add(1.0);
            //    rayon.Add(rayon[0] * 0.8);
            //    rayon.Add(rayon[1] * 0.9);
            //    rayon.Add(rayon[2] * 0.95);
            //    rayon.Add(rayon[3] * 0.975);
            //    rayon.Add(rayon[4] * 1);
            //}


            //2015_03_24 définition position en dur (dans un 1er temps) des cercles englobants
            if (circleNb == 6)
            {
                circles[0].BoundingCircle_x = 400;
                circles[0].BoundingCircle_y = 400;
                circles[0].BoundingCircle_r = 100; // Millieu

                circles[1].BoundingCircle_x = 200;
                circles[1].BoundingCircle_y = 450;
                circles[1].BoundingCircle_r = 100; // Gauche

                circles[2].BoundingCircle_x = 400;
                circles[2].BoundingCircle_y = 600;
                circles[2].BoundingCircle_r = 100; // Gauche

                circles[3].BoundingCircle_x = 280;
                circles[3].BoundingCircle_y = 230;
                circles[3].BoundingCircle_r = 100; // Gauche

                circles[4].BoundingCircle_x = 600;
                circles[4].BoundingCircle_y = 450;
                circles[4].BoundingCircle_r = 100; // Gauche

                circles[5].BoundingCircle_x = 510;
                circles[5].BoundingCircle_y = 230;
                circles[5].BoundingCircle_r = 100; // Gauche

                foreach (Circle c in circles)
                {
                    c.x = c.BoundingCircle_x;
                    c.y = c.BoundingCircle_y;
                    c.r = c.BoundingCircle_r / 3;
                }
            }

            return(pack);

            if (circleNb == 6)
            {
                int parent = 0;
                int fils   = 1;

                // Un Y n'est possible que sur les noeuds 2 à 4
                // puisque le 1er noeud n'a pas de parent, on ne peut pas faire de Y
                if (yCircle == 1)
                {
                    yCircle = 2;
                }
                // On ne peut pas dépasser 4 car il n'y a plus assez de fils pour faire un Y
                if (yCircle > 3)
                {
                    yCircle = 4;
                }
                for (int i = 0; fils < circleNb; i++)
                {
                    circles[parent].next.Add(circles[fils]); circles[fils].previous = circles[parent];
                    if (yCircle == parent + 1)
                    {
                        // On est dans le cas où on a 2 enfants à ce noeud
                        // On reclacul l'angleWithPrevious du fils courant avant de passer au suivant.
                        double min = 0;
                        min = circles[fils].angleWithPrevious = RandomManager.getDouble2(min, Math.PI / 2);

                        fils++;
                        circles[parent].next.Add(circles[fils]); circles[fils].previous = circles[parent];
                        circles[fils].angleWithPrevious = RandomManager.getDouble2(-Math.PI / 2, min / 6);
                    }
                    if (yCircle < parent + 1)
                    {
                        circles[fils].angleWithPrevious = circles[parent].angleWithPrevious + RandomManager.getDouble2(-0.8, 0.8);
                    }
                    parent++; fils++;
                }
            }

            circlesInitial = new List <Circle>();

            // Création des cercles dans la représentation initiale des cercles.
            foreach (var item in circles)
            {
                circlesInitial.Add(new Circle()
                {
                    x = item.x, y = item.y, num = item.num, r = item.r, angleWithPrevious = item.angleWithPrevious, angleWithPreviousVelocity = item.angleWithPreviousVelocity
                });
            }

            // Hiérarchisation de la représentation initiale des cercles.
            return(pack);
        }