Not: Aşağıdakilerin tümü, topun yüzeyinin sürtünmesiz olduğunu varsayar (yani dönmeye başlamaz veya olduğu gibi farklı şekilde yükselir).
Çarpışma anında, top köşeye değecek. Katı nesneler çarpıştığında, yüzey normal olarak adlandırılan, yani çarpışma noktasında yüzeye dik olan bir kuvvet etki eder.
Bir top olduğundan, yüzeye dik, topun merkezine doğru. Tamam, gücün yönünü biliyoruz, peki ya büyüklüğü? Elastik bir çarpışmanın (ve dikdörtgenin hareket edemediğini) varsayarak, topun çarptığı hızda toparlanması gerekir.
(NDx, nDy) çarpışmadan sonraki hız, (oDx, oDy) çarpışmadan önceki hız ve (x, y) topun çarpışma noktasındaki konumu olsun. Topun çarpıştığı köşede (0,0) olduğunu varsayalım.
İçgörülerimizi formül olarak ifade ederek:
(nDx, nDy) = (oDx, oDy) + c * (x, y)
length (nDx, nDy) = length (oDx, oDy)
Hangi eşdeğerdir:
nDx = oDx + c * x
nDy = oDy + c * y
nDx^2 + nDy^2 = oDx^2 + oDy^2
En sondaki ilk iki denklemi değiştirerek, şunu elde ederiz:
(oDx + c * x)^2 + (oDy + c * y)^2 = oDx^2 + oDy^2
Binom thorem kullanarak genişleyen
(a+b)^2 = a^2 + 2ab + b^2
verim:
oDx^2 + 2 * oDx * c * x + (c * x) ^ 2 + oDy^2 + 2 * oDy * c * y + (c * y) ^ 2 = oDx^2 + oDy^2
2 * oDx * c * x + 2 * oDy * c * y + (c * x) ^ 2 + (c * y) ^ 2 = 0
(2 * oDx * x + 2 * oDy * y) * c + (x^2 + y^2) * c^2 = 0
Bu ikinci dereceden denklemin c
, biri 0 olan iki çözümü vardır. Açıkçası, ilgilendiğimiz çözüm bu değildir, çünkü topun yönü genellikle çarpışma sonucunda değişecektir. Diğer çözümü elde etmek için her iki tarafı da c ile bölüp alırız:
(2 * oDx * x + 2 * oDy * y) + (x^2 + y^2) * c = 0
Yani:
c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
Özetlemek gerekirse, biz var:
c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
nDx = oDx + c * x
nDy = oDy + c * y
Düzenleme : Kodda:
if (collision) {
float x = ballX - cornerX;
float y = ballY - cornerY;
float c = -2 * (ballDx * x + ballDy * y) / (x * x + y * y);
ballDx = ballDx + c * x;
ballDy = ballDy + c * y;
}
Birkaç uygulama düşüncesi: Simülasyon adımından sonra topun pozisyonuyla yaklaşık (x, y) değerine ulaşabiliyorken, bu yaklaşım sapma açısını değiştirecek ve bu nedenle çok dikkat çekici olacak, böylece simülasyon adımlarınızın çok iyi olması gerekiyor (belki de top adım başına çapının 1 / 20'sinden fazla hareket etmiyor). Daha doğru bir çözüm için, çarpışmanın meydana geldiği zamanı hesaplayabilir ve o zaman o simülasyon adımını bölebilirsiniz, yani çarpışma noktasına kadar kısmi bir adım ve adımın geri kalan kısmı için başka bir kısmi adım yapabilirsiniz.
Düzenleme 2: Etki noktasının hesaplanması
Simülasyonun başlangıcında r'nin yarıçap, (x0, y0) konumu ve (dx, dy) topun hızı olalım. Basit olması için, söz konusu köşenin (0,0) konumunda olduğunu varsayalım.
Biliyoruz:
(x,y) = (x0, y0) + (dx, dy) * t
İstiyoruz
length(x,y) = r
Yani
(x0 + dx * t) ^ 2 + (y0 + dy * t) ^ 2 = r^2
x0^2 + 2 * x0 * dx * t + dx^2 * t^2 + y0^2 + 2 * y0 * dy * t + dy^2 * t^2 = r ^ 2
(dx^2 + dy^2) * t^2 + (2 * x0 * dx + 2 * y0 * dy) * t + (x0^2 + y0^2 - r^2) = 0
\____ _____/ \____________ ___________/ \_______ ________/
\/ \/ \/
a b c
Bu, t cinsinden ikinci dereceden bir denklemdir . Ayrımcı ise
D = b^2 - 4 * a * c
negatif, çözümü yok, yani top, mevcut rotasında köşeye asla vuramaz. Aksi takdirde, iki çözümü tarafından verilir
t1 = (-b - sqrt(D)) / (2 * a)
t2 = (-b + sqrt(D)) / (2 * a)
Çarpışmanın başladığı zamanla ilgileniyoruz, ki bu daha önceki zamandır t1
.
Yöntemin şöyle olur:
// compute a,b,c and D as given above
if (D >= 0) {
t = (-b - sqrt(D)) / (2 * a);
if (0 < t && t <= ts) {
// collision during this timestep!
x = x + t * dx;
y = y + t * dy;
ts = ts - t;
// change dx and dy using the deflection formula
}
}
x = x + ts * dx;
y = y + ts * dy;