public void BotstMetDeeltje(Deeltje ander, float tijdBotsing, float huidigeTijd)
        {
            // terug naar positie bij botsing
            float dt = tijdBotsing - huidigeTijd;

            Px       += Vx * dt;
            Py       += Vy * dt;
            ander.Px += ander.Vx * dt;
            ander.Py += ander.Vy * dt;
            // snelheden berekenen
            float dx    = ander.Px - Px;
            float dy    = ander.Py - Py;
            float dvx   = ander.Vx - Vx;
            float dvy   = ander.Vy - Vy;
            float dvdp  = dx * dvx + dy * dvy;
            float sigma = Radius + ander.Radius;
            float J     = 2 * Massa * ander.Massa * dvdp / ((Massa + ander.Massa) * sigma);
            float Jx    = J * dx / sigma;
            float Jy    = J * dy / sigma;

            Vx       += Jx / Massa;
            Vy       += Jy / Massa;
            ander.Vx -= Jx / ander.Massa;
            ander.Vy -= Jy / ander.Massa;
            if (Elasticiteit < 1)
            {
                Vx       *= Elasticiteit;
                Vy       *= Elasticiteit;
                ander.Vx *= Elasticiteit;
                ander.Vy *= Elasticiteit;
            }
            // tellers verhogen
            AantalBotsingen++;
            ander.AantalBotsingen++;
        }
        public float TijdTotAnderDeeltje(Deeltje ander)
        {
            if (this == ander)
            {
                return(float.PositiveInfinity);
            }
            float dx   = ander.Px - Px;
            float dy   = ander.Py - Py;
            float dvx  = ander.Vx - Vx;
            float dvy  = ander.Vy - Vy;
            float dvdp = dx * dvx + dy * dvy;

            if (dvdp > 0)
            {
                return(float.PositiveInfinity);
            }
            float dvdv  = dvx * dvx + dvy * dvy;
            float dpdp  = dx * dx + dy * dy;
            float sigma = Radius + ander.Radius;
            float d     = dvdp * dvdp - dvdv * (dpdp - sigma * sigma);

            if (d < 0)
            {
                return(float.PositiveInfinity);
            }

            return(-(dvdp + (float)Math.Sqrt(d)) / dvdv);
        }
 public Botsing(float tijd, Deeltje deeltje, DockStyle wandtype)
 {
     Tijd     = tijd;
     Deeltje  = deeltje;
     WandType = wandtype;
     AantalBotsingenDeeltje = deeltje.AantalBotsingen;
 }
 public Botsing(float tijd, Deeltje deeltje, Obstakel obstakel, ContentAlignment orientatie)
 {
     Tijd                   = tijd;
     Deeltje                = deeltje;
     Obstakel               = obstakel;
     Orientatie             = orientatie;
     AantalBotsingenDeeltje = deeltje.AantalBotsingen;
 }
 public Botsing(float tijd, Deeltje deeltje, Deeltje anderDeeltje)
 {
     Tijd                        = tijd;
     Deeltje                     = deeltje;
     AnderDeeltje                = anderDeeltje;
     AantalBotsingenDeeltje      = deeltje.AantalBotsingen;
     AantalBotsingenAnderDeeltje = anderDeeltje.AantalBotsingen;
 }
Beispiel #6
0
        void timer_Tick(object sender, EventArgs e)
        // mogelijke bron van fouten:
        // deeltjes betrokken bij botsing worden teruggebracht naar positie tijdens botsing,
        // andere deeltjes worden over hele tijdeenheid verplaatst
        {
            huidigeTijd++;

            // botsingvrije verplaatsingen afhandelen
            foreach (var deeltje in lijstDeeltjes)
            {
                deeltje.LineaireVerplaatsing();
            }
            // botsingen afhandelen
            Botsing botsing;

            while (minPQ.BevatItem && minPQ.Minimum <= huidigeTijd)
            {
                botsing = minPQ.WisMinimum();
                if (botsing.IsGeldig)
                {
                    Deeltje deeltje = botsing.Deeltje;

                    if (botsing.AnderDeeltje == null && botsing.Obstakel == null) // botsing met wand
                    {
                        deeltje.BotstMetWand(botsing.WandType, botsing.Tijd, huidigeTijd);
                        voorspelBotsingen(deeltje, null, null);
                    }

                    else if (botsing.Obstakel == null) // botsing met ander deeltje
                    {
                        deeltje.BotstMetDeeltje(botsing.AnderDeeltje, botsing.Tijd, huidigeTijd);
                        voorspelBotsingen(deeltje, botsing.AnderDeeltje, null);
                        voorspelBotsingen(botsing.AnderDeeltje, deeltje, null);
                    }

                    else // botsing met obstakel
                    {
                        deeltje.BotstMetObstakel(botsing.Obstakel, botsing.Orientatie, botsing.Tijd, huidigeTijd);
                        voorspelBotsingen(deeltje, null, botsing.Obstakel);
                    }
                }
            }

            Refresh();
        }
Beispiel #7
0
        private void voorspelBotsingen(Deeltje deeltje, Deeltje uitgeslotenDeeltje, Obstakel uitgeslotenObstakel)
        // zojuist geraakte deeltje of obstakel uitsluiten bij voorspelling
        {
            DockStyle wandtype;
            float     dtWand = deeltje.TijdTotWand(out wandtype);

            if (dtWand < 1 << 16) // als deeltje stilstaat niet toevoegen
            {
                minPQ.Invoegen(new Botsing(huidigeTijd + dtWand, deeltje, wandtype));
            }

            foreach (Deeltje overigDeeltje in lijstDeeltjes)
            {
                if (overigDeeltje == deeltje || overigDeeltje == uitgeslotenDeeltje)
                {
                    continue;
                }
                float dt = deeltje.TijdTotAnderDeeltje(overigDeeltje);
                if (dt < dtWand) // tijden na botsing met wand niet relevant
                {
                    minPQ.Invoegen(new Botsing(huidigeTijd + dt, deeltje, overigDeeltje));
                }
            }

            ContentAlignment orientatie;

            foreach (Obstakel obstakel in lijstObstakels)
            {
                if (obstakel == uitgeslotenObstakel)
                {
                    continue;
                }
                float dtObstakel = deeltje.TijdTotObstakel(obstakel, out orientatie);
                if (dtObstakel < dtWand) // tijden na botsing met wand niet relevant
                {
                    minPQ.Invoegen(new Botsing(huidigeTijd + dtObstakel, deeltje, obstakel, orientatie));
                }
            }
        }