Kollision zweier Kugeln (2D): Unterschied zwischen den Versionen
aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg
Kowa (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
Kowa (Diskussion | Beiträge) |
||
| Zeile 9: | Zeile 9: | ||
[[Datei:KollisionZweiKugeln1.png|miniatur|375px|Kollision zweier Kugeln]] | [[Datei:KollisionZweiKugeln1.png|miniatur|375px|Kollision zweier Kugeln]] | ||
[[Datei:KollisionZweiKugeln2.png|miniatur|461px|Der Tunnel-Effekt]] | [[Datei:KollisionZweiKugeln2.png|miniatur|461px|Der Tunnel-Effekt]] | ||
==Grundannahmen== | |||
==[[A-posteriori-Kollisionserkennung]] von zwei Kugeln== | ==[[A-posteriori-Kollisionserkennung]] von zwei Kugeln== | ||
<source lang="javascript"> | |||
function collisionBallBall(p_b1, p_b2) | |||
{ | |||
// l_n: Normalenvektor (Verbindung zwischen den beiden Kugelnn) | |||
var l_nx = p_b2.getX() - p_b1.getX(); | |||
var l_ny = p_b2.getY() - p_b1.getY(); | |||
// Abstand der beiden Kugeln | |||
var l_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.setX(p_b2.getX()+ p_b2.getR()); | |||
l_nx += p_b2.getR(); | |||
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| = 1 | |||
l_nx /= l_dist; | |||
l_ny /= l_dist; | |||
//Tangentialvektor (senkrecht zu Normalenvektor, zwischen beiden Kugeln) | |||
var l_tx = l_ny; | |||
var l_ty = -l_nx; | |||
// Summe der Massen beider Kugeln | |||
var l_sm1m2 = p_b1.getMass() + p_b2.getMass(); | |||
// Überlappung der beiden Kugeln | |||
var l_overlap = ( p_b1.getR() + p_b2.getR() ) - l_dist; | |||
// Verschieben der beiden Kugeln entlang der Normalen, | |||
// so dass sie sich nicht mehr überlappen! | |||
p_b1.setX(p_b1.getX() - l_nx * l_overlap * (p_b2.getMass()/l_sm1m2) * (1+EPSILON)); | |||
p_b1.setY(p_b1.getY() - l_ny * l_overlap * (p_b2.getMass()/l_sm1m2) * (1+EPSILON)); | |||
p_b2.setX(p_b2.getX() + l_nx * l_overlap * (p_b1.getMass()/l_sm1m2) * (1+EPSILON)); | |||
p_b2.setY(p_b2.getY() + l_ny * l_overlap * (p_b1.getMass()/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-Anteil | |||
var l_sn1 = l_nx * p_b1.getVx() + l_ny * p_b1.getVy(); | |||
var l_st1 = l_tx * p_b1.getVx() + l_ty * p_b1.getVy(); | |||
var l_n1x = l_nx * l_sn1; // Normalenvektor-Anteil von p_b1.getVx() | |||
var l_n1y = l_ny * l_sn1; | |||
var l_t1x = l_tx * l_st1; // Tangentialvektor-Anteil von p_b1.getVx() | |||
var l_t1y = l_ty * l_st1; | |||
// Ball 2: Zerlegung des Geschwindigkeitsvektors in n- und t-Anteil | |||
var l_sn2 = l_nx * p_b2.getVx() + l_ny * p_b2.getVy(); | |||
var l_st2 = l_tx * p_b2.getVx() + l_ty * p_b2.getVy(); | |||
var l_n2x = l_nx * l_sn2; // Normalenvektor-Anteil von p_b2.getVx() | |||
var l_n2y = l_ny * l_sn2; | |||
var l_t2x = l_tx * l_st2; // Tangentialvektor-Anteil von p_b2.getVx() | |||
var l_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. | |||
var l_vspx = 2*(p_b1.getMass()*l_n1x+p_b2.getMass()*l_n2x)/l_sm1m2; | |||
var l_vspy = 2*(p_b1.getMass()*l_n1y+p_b2.getMass()*l_n2y)/l_sm1m2; | |||
p_b1.setVx(l_vspx - l_n1x + l_t1x); | |||
p_b1.setVy(l_vspy - l_n1y + l_t1y); | |||
p_b2.setVx(l_vspx - l_n2x + l_t2x); | |||
p_b2.setVy(l_vspy - l_n2y + l_t2y); | |||
//// Alternative Berechnung: | |||
// Differenz der Massen beide Kugeln | |||
// var l_dm2m1 = p_b2.getMass() - p_b1.getMass(); | |||
// p_b1.setVx((l_n2x*p_b2.getMass()*2-l_n1x*l_dm2m1)/l_sm1m2 + l_t1x); | |||
// p_b1.setVy((l_n2y*p_b2.getMass()*2-l_n1y*l_dm2m1)/l_sm1m2 + l_t1y); | |||
// p_b2.setVx((l_n1x*p_b1.getMass()*2+l_n2x*l_dm2m1)/l_sm1m2 + l_t2x); | |||
// p_b2.setVy((l_n1y*p_b1.getMass()*2+l_n2y*l_dm2m1)/l_sm1m2 + l_t2y); | |||
} | |||
} | |||
</source> | |||
==[[A-priori-Kollisionserkennung]] von zwei Kugeln== | ==[[A-priori-Kollisionserkennung]] von zwei Kugeln== | ||
Version vom 1. November 2016, 09:09 Uhr
Dieser Artikel erfüllt die GlossarWiki-Qualitätsanforderungen nur teilweise:
| Korrektheit: 0 (nicht überprüft) |
Umfang: 0 (viel zu gering) |
Quellenangaben: 1 (fehlen großteils) |
Quellenarten: 3 (gut) |
Konformität: 5 (ausgezeichnet) |
Dieser Artikel wird derzeit von einem Autor gründlich bearbeitet. Die Inhalte sind daher evtl. noch inkonsistent.


Grundannahmen
A-posteriori-Kollisionserkennung von zwei Kugeln
function collisionBallBall(p_b1, p_b2)
{
// l_n: Normalenvektor (Verbindung zwischen den beiden Kugelnn)
var l_nx = p_b2.getX() - p_b1.getX();
var l_ny = p_b2.getY() - p_b1.getY();
// Abstand der beiden Kugeln
var l_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.setX(p_b2.getX()+ p_b2.getR());
l_nx += p_b2.getR();
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| = 1
l_nx /= l_dist;
l_ny /= l_dist;
//Tangentialvektor (senkrecht zu Normalenvektor, zwischen beiden Kugeln)
var l_tx = l_ny;
var l_ty = -l_nx;
// Summe der Massen beider Kugeln
var l_sm1m2 = p_b1.getMass() + p_b2.getMass();
// Überlappung der beiden Kugeln
var l_overlap = ( p_b1.getR() + p_b2.getR() ) - l_dist;
// Verschieben der beiden Kugeln entlang der Normalen,
// so dass sie sich nicht mehr überlappen!
p_b1.setX(p_b1.getX() - l_nx * l_overlap * (p_b2.getMass()/l_sm1m2) * (1+EPSILON));
p_b1.setY(p_b1.getY() - l_ny * l_overlap * (p_b2.getMass()/l_sm1m2) * (1+EPSILON));
p_b2.setX(p_b2.getX() + l_nx * l_overlap * (p_b1.getMass()/l_sm1m2) * (1+EPSILON));
p_b2.setY(p_b2.getY() + l_ny * l_overlap * (p_b1.getMass()/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-Anteil
var l_sn1 = l_nx * p_b1.getVx() + l_ny * p_b1.getVy();
var l_st1 = l_tx * p_b1.getVx() + l_ty * p_b1.getVy();
var l_n1x = l_nx * l_sn1; // Normalenvektor-Anteil von p_b1.getVx()
var l_n1y = l_ny * l_sn1;
var l_t1x = l_tx * l_st1; // Tangentialvektor-Anteil von p_b1.getVx()
var l_t1y = l_ty * l_st1;
// Ball 2: Zerlegung des Geschwindigkeitsvektors in n- und t-Anteil
var l_sn2 = l_nx * p_b2.getVx() + l_ny * p_b2.getVy();
var l_st2 = l_tx * p_b2.getVx() + l_ty * p_b2.getVy();
var l_n2x = l_nx * l_sn2; // Normalenvektor-Anteil von p_b2.getVx()
var l_n2y = l_ny * l_sn2;
var l_t2x = l_tx * l_st2; // Tangentialvektor-Anteil von p_b2.getVx()
var l_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.
var l_vspx = 2*(p_b1.getMass()*l_n1x+p_b2.getMass()*l_n2x)/l_sm1m2;
var l_vspy = 2*(p_b1.getMass()*l_n1y+p_b2.getMass()*l_n2y)/l_sm1m2;
p_b1.setVx(l_vspx - l_n1x + l_t1x);
p_b1.setVy(l_vspy - l_n1y + l_t1y);
p_b2.setVx(l_vspx - l_n2x + l_t2x);
p_b2.setVy(l_vspy - l_n2y + l_t2y);
//// Alternative Berechnung:
// Differenz der Massen beide Kugeln
// var l_dm2m1 = p_b2.getMass() - p_b1.getMass();
// p_b1.setVx((l_n2x*p_b2.getMass()*2-l_n1x*l_dm2m1)/l_sm1m2 + l_t1x);
// p_b1.setVy((l_n2y*p_b2.getMass()*2-l_n1y*l_dm2m1)/l_sm1m2 + l_t1y);
// p_b2.setVx((l_n1x*p_b1.getMass()*2+l_n2x*l_dm2m1)/l_sm1m2 + l_t2x);
// p_b2.setVy((l_n1y*p_b1.getMass()*2+l_n2y*l_dm2m1)/l_sm1m2 + l_t2y);
}
}
A-priori-Kollisionserkennung von zwei Kugeln
Quellen
- Kowarschick (WebProg): Wolfgang Kowarschick; Vorlesung „Web-Programmierung“; Hochschule: Hochschule Augsburg; Adresse: Augsburg; Web-Link; 2024; Quellengüte: 3 (Vorlesung)
