vx, vy: Geschwindigkeit in $x$- und $y$-Richtung (Einheit: Pixel/s)
r: Radius (Einheit: Pixel)
m: Masse (die Einheit ist irrelevant, sie muss nur für alle Bälle dieselbe sein)
Die Berechnung der Position aller im System vorhandener Bälle erfolgt fps
(frames per second) mal pro Sekunde. Wenn es zu keiner Kollision kommt, wird
der Ball um vx/fps bzw. vy/fps Pixel in
$x$- bzw. $y$-Richtung verschoben:
b.x+=b.vx/fps;b.y+=b.vy/fps;
Je höher die Framrate ist, desto genauer wird die Bewegungsbahn der Bälle simuliert.
functioncollisionBallBall(p_b1,p_b2){// l_n: Normalenvektor (Verbindung zwischen den beiden Kugelnn)varl_nx=p_b2.x()-p_b1.x();varl_ny=p_b2.y()-p_b1.y();// Abstand der beiden Kugelnvarl_dist=Math.sqrt(l_nx*l_nx+l_ny*l_ny);// Die Kugeln dürfen sich nicht an derselben Stelle befinden,// weil sie sonst nicht entlang der nicht-existenten Normalen// auseinandergezogen werden können.// Dieser Fall sollte nur sehr selten eintreten (z.B. wenn eine// neue Kugel genau an der Stelle einer existenten Kugel erstellt wird).if(l_dist<EPSILON){p_b2.x=p_b2.x+p_b2.r;l_nx+=p_b2.r;l_dist=Math.sqrt(l_nx*l_nx+l_ny*l_ny);};// Kugeln kollidieren, wenn der Abstand kleiner gleich der Summe// der Radien beider Kugeln ist.if(l_dist<=p_b1.getR()+p_b2.getR()){// Normalenvektor wird normalisiert: |l_n| = 1l_nx/=l_dist;l_ny/=l_dist;//Tangentialvektor (senkrecht zu Normalenvektor, zwischen beiden Kugeln)varl_tx=l_ny;varl_ty=-l_nx;// Summe der Massen beider Kugelnvarl_sm1m2=p_b1.m+p_b2.m;// Überlappung der beiden Kugelnvarl_overlap=(p_b1.r+p_b2.r)-l_dist;// Verschieben der beiden Kugeln entlang der Normalen,// so dass sie sich nicht mehr überlappen!p_b1.x=p_b1.x-l_nx*l_overlap*(p_b2.m/l_sm1m2)*(1+EPSILON));p_b1.y=p_b1.y-l_ny*l_overlap*(p_b2.m/l_sm1m2)*(1+EPSILON));p_b2.x=p_b2.x+l_nx*l_overlap*(p_b1.m/l_sm1m2)*(1+EPSILON));p_b2.y=p_b2.y+l_ny*l_overlap*(p_b1.m/l_sm1m2)*(1+EPSILON));// Zerlegung der Geschwindigkeitsvektoren in Normalen- und // Tangentialanteil: v=sn*n+st*t, wobei // v Vektor, n Normalenvektor, t Tagentialvektor und// sn, st zwei skalare Werte sind.// Es gilt: v*n = sn*(n*n)+st*(t*n) = sn, da t*n=0 und n*n = 1// Es gilt: v*t = sn*(n*t)+st*(t*t) = st, da t*n=0 und t*t = 1// Also ist: sn = v*n und st=v*t// Ball 1: Zerlegung des Geschwindigkeitsvektors in n- und t-Anteilvarl_sn1=l_nx*p_b1.vx+l_ny*p_b1.vy;varl_st1=l_tx*p_b1.vx+l_ty*p_b1.vy;varl_n1x=l_nx*l_sn1;// Normalenvektor-Anteil von p_b1.vxvarl_n1y=l_ny*l_sn1;varl_t1x=l_tx*l_st1;// Tangentialvektor-Anteil von p_b1.vxvarl_t1y=l_ty*l_st1;// Ball 2: Zerlegung des Geschwindigkeitsvektors in n- und t-Anteilvarl_sn2=l_nx*p_b2.vx+l_ny*p_b2.vy;varl_st2=l_tx*p_b2.vx+l_ty*p_b2.vy;varl_n2x=l_nx*l_sn2;// Normalenvektor-Anteil von p_b2.vxvarl_n2y=l_ny*l_sn2;varl_t2x=l_tx*l_st2;// Tangentialvektor-Anteil von p_b2.vxvarl_t2y=l_ty*l_st2;// Der Impulserhaltungssatz// m1*v1 + m2*v2 = m1*u1 + m2*u2 // (wobei m1, m2 = Massen der Körper // und v1, v2, u1, u2 die Geschwindigkeiten)// und der Energieerhaltsungssatz// 0,5*m1*v1² + 0,5*m2*v2² = 0,5*m1*u1² + 0,5*m2*u2²// führen nach einfachen mathematischen Umformungen zu// folgenden Beziehungen (für den eindimensionalen Fall):// u1 = 2*(m1*v1+m2*v2)/(m1+m2) - v1// u2 = 2*(m1*v1+m2*v2)/(m1+m2) - v2// 2*(m1*v1+m2*v2)/(m1+m2) ist die Geschwindigkeit des // gemeinsamen Schwerpunktes.// Im zweidimensionalen Fall gilt, dass die Kollision entlang// der Normalen erfolgt. Die tangentialen Anteile der der // Bewegungsrichtungen werden unverändert übernommen.varl_vspx=2*(p_b1.m*l_n1x+p_b2.m*l_n2x)/l_sm1m2;varl_vspy=2*(p_b1.m*l_n1y+p_b2.m*l_n2y)/l_sm1m2;p_b1.vx=l_vspx-l_n1x+l_t1x;p_b1.vy=l_vspy-l_n1y+l_t1y;p_b2.vy=l_vspx-l_n2x+l_t2x;p_b2.vy=l_vspy-l_n2y+l_t2y;//// Alternative Berechnung:// Differenz der Massen beide Kugeln// var l_dm2m1 = p_b2.m - p_b1.m;// p_b1.vx = (l_n2x*p_b2.m*2-l_n1x*l_dm2m1)/l_sm1m2 + l_t1x;// p_b1.vy = (l_n2y*p_b2.m*2-l_n1y*l_dm2m1)/l_sm1m2 + l_t1y;// p_b2.vx = (l_n1x*p_b1.m*2+l_n2x*l_dm2m1)/l_sm1m2 + l_t2x;// p_b2.vy =(l_n1y*p_b1.m*2+l_n2y*l_dm2m1)/l_sm1m2 + l_t2y;}}