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; }
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(); }
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)); } } }