Dengan bantuan komunitas Stack Overflow, saya telah menulis simulator fisika yang cukup mendasar namun menyenangkan.
Anda klik dan seret mouse untuk meluncurkan bola. Ini akan memantul dan akhirnya berhenti di "lantai".
Fitur besar berikutnya yang ingin saya tambahkan adalah bola ke bola tabrakan. Gerakan bola dipecah menjadi vektor kecepatan kapak dan y. Saya memiliki gravitasi (pengurangan kecil dari vektor y setiap langkah), saya memiliki gesekan (pengurangan kecil dari kedua vektor setiap tabrakan dengan dinding). Bola-bola itu dengan jujur bergerak dengan cara yang realistis dan mengejutkan.
Saya kira pertanyaan saya memiliki dua bagian:
- Apa metode terbaik untuk mendeteksi tabrakan bola ke bola?
Apakah saya hanya memiliki loop O (n ^ 2) yang berulang pada setiap bola dan memeriksa setiap bola lainnya untuk melihat apakah radiusnya tumpang tindih? - Persamaan apa yang saya gunakan untuk menangani bola ke bola tabrakan? Fisika 101
Bagaimana pengaruhnya terhadap dua bola kecepatan vektor x / y? Apa arah yang dihasilkan kedua bola itu? Bagaimana saya menerapkan ini pada setiap bola?
Menangani deteksi tabrakan "dinding" dan perubahan vektor yang dihasilkan mudah tetapi saya melihat lebih banyak komplikasi dengan tabrakan bola-bola. Dengan dinding saya hanya harus mengambil negatif dari vektor x atau y yang sesuai dan pergi ke arah yang benar. Dengan bola saya tidak berpikir seperti itu.
Beberapa klarifikasi cepat: untuk kesederhanaan saya baik-baik saja dengan tabrakan elastis sempurna untuk saat ini, juga semua bola saya memiliki massa yang sama sekarang, tetapi saya mungkin mengubahnya di masa depan.
Sunting: Sumber yang saya temukan bermanfaat
Fisika Bola 2d dengan vektor: Tabrakan 2-Dimensi Tanpa Trigonometri.pdf
Contoh deteksi tabrakan 2d Bola: Menambahkan Deteksi Tabrakan
Keberhasilan!
Saya memiliki deteksi dan respons tabrakan bola bekerja dengan baik!
Kode yang relevan:
Deteksi Tabrakan:
for (int i = 0; i < ballCount; i++)
{
for (int j = i + 1; j < ballCount; j++)
{
if (balls[i].colliding(balls[j]))
{
balls[i].resolveCollision(balls[j]);
}
}
}
Ini akan memeriksa tabrakan antara setiap bola tetapi melewatkan pemeriksaan berlebih (jika Anda harus memeriksa apakah bola 1 bertabrakan dengan bola 2 maka Anda tidak perlu memeriksa apakah bola 2 bertabrakan dengan bola 1. Selain itu, ia melompat memeriksa tabrakan dengan dirinya sendiri. ).
Kemudian, di kelas bola saya, saya memiliki metode colliding () dan resolCollision () saya:
public boolean colliding(Ball ball)
{
float xd = position.getX() - ball.position.getX();
float yd = position.getY() - ball.position.getY();
float sumRadius = getRadius() + ball.getRadius();
float sqrRadius = sumRadius * sumRadius;
float distSqr = (xd * xd) + (yd * yd);
if (distSqr <= sqrRadius)
{
return true;
}
return false;
}
public void resolveCollision(Ball ball)
{
// get the mtd
Vector2d delta = (position.subtract(ball.position));
float d = delta.getLength();
// minimum translation distance to push balls apart after intersecting
Vector2d mtd = delta.multiply(((getRadius() + ball.getRadius())-d)/d);
// resolve intersection --
// inverse mass quantities
float im1 = 1 / getMass();
float im2 = 1 / ball.getMass();
// push-pull them apart based off their mass
position = position.add(mtd.multiply(im1 / (im1 + im2)));
ball.position = ball.position.subtract(mtd.multiply(im2 / (im1 + im2)));
// impact speed
Vector2d v = (this.velocity.subtract(ball.velocity));
float vn = v.dot(mtd.normalize());
// sphere intersecting but moving away from each other already
if (vn > 0.0f) return;
// collision impulse
float i = (-(1.0f + Constants.restitution) * vn) / (im1 + im2);
Vector2d impulse = mtd.normalize().multiply(i);
// change in momentum
this.velocity = this.velocity.add(impulse.multiply(im1));
ball.velocity = ball.velocity.subtract(impulse.multiply(im2));
}
Kode Sumber: Sumber lengkap untuk collider bola ke bola.
Jika ada yang punya saran untuk meningkatkan simulator fisika dasar ini, beri tahu saya! Satu hal yang belum saya tambahkan adalah momentum sudut sehingga bola akan bergulir lebih realistis. Ada saran lain? Tinggalkan komentar!
Vector2d impulse = mtd.multiply(i);
harus i * vektor mtd yang dinormalisasi. Sesuatu seperti:Vector2d impulse = mtd.normalize().multiply(i);