22 Ekim 2020 Perşembe

Collision Detection

Giriş 
Özellikle 2D oyunlarda sıkça karşımıza çıkar. Bu konuyu burada gördüğüm için yazmak istedim

1. Axis-Aligned Bounding Box
Açıklaması şöyle
One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.
Onun sağ üst köşesi benim sol üst köşemin sağındaysa ve //X ekseni
Onun sol üst köşesi benim sağ üst köşemin solundaysa ve //X ekseni
Onun sağ alt köşesi benim sağ alt köşemin altındaysa ve //Y ekseni
Onun sol üst köşesi benim sağ alt köşemin üstündeyse  //Y ekseni

mutlaka üst üste gelme vardır

Örnek
Bu metodun ismi overlaps() veya intersects() olabilirdi. Şöyle yaparız
var rect1 = {x: 5, y: 5, width: 50, height: 50}
var rect2 = {x: 20, y: 10, width: 10, height: 10}

if (rect1.x < rect2.x + rect2.width &&
   rect1.x + rect1.width > rect2.x &&
   rect1.y < rect2.y + rect2.height &&
   rect1.y + rect1.height > rect2.y) {
    // collision detected!
}
Örnek
Şöyle yaparız
bool valueInRange(int value, int min, int max)
{ return (value >= min) && (value <= max); }

bool rectOverlap(rect A, rect B)
{
  bool xOverlap = valueInRange(A.x, B.x, B.x + B.width) ||
                  valueInRange(B.x, A.x, A.x + A.width);

  bool yOverlap = valueInRange(A.y, B.y, B.y + B.height) ||
                  valueInRange(B.y, A.y, A.y + A.height);

  return xOverlap && yOverlap;
}
2. Circle Collision
Açıklaması şöyle. İki dairenin merkezleri arasındaki mesafeyi bularak bu mesafenin iki dairenin yarıçaplarını toplamından küçük olup olmamasın dayalı
Another simple shape for collision detection is between two circles. This algorithm works by taking the centre points of the two circles and ensuring the distance between the centre points are less than the two radii added together.
Örnek
Şöyle yaparız
var circle1 = {radius: 20, x: 5, y: 5};
var circle2 = {radius: 12, x: 10, y: 5};

var dx = circle1.x - circle2.x;
var dy = circle1.y - circle2.y;
var distance = Math.sqrt(dx * dx + dy * dy);

if (distance < circle1.radius + circle2.radius) {
    // collision detected!
}
3. Circle + Square Collision
Açıklaması şöyle
We have a circle with the position (cx,cy) with a radius r and a square at (rx,ry) with a width/height (rw,rh).

Our code will first test which edge of the rectangle is closest to the circle, then see if there is a collision using the Pythagorean Theorem. 
Dairenin hangi tarafta olduğunu anlamak için kare sınıfının kodunu şöyle yaparız. Burada karenin sol üst köşesi rx , ry noktası. Dairenin merkezi ise cx,cy noktası
Elimizde şöyle iki değişken olsunn
// temporary variables to set edges for testing
float testX = cx;
float testY = cy;
Şöyle yaparız
if (cx < rx)         
  testX = rx;        // left edge
else if (cx > rx+rw) 
  testX = rx+rw;     // right edge

if (cy < ry)         
  testY = ry;        // top edge
else if (cy > ry+rh) 
  testY = ry+rh;     // bottom edge
Daha sonra şöyle yaparız
// get distance from closest edges
float distX = cx-testX;
float distY = cy-testY;
float distance = sqrt( (distX*distX) + (distY*distY) );

// if the distance is less than the radius, collision!
if (distance <= radius) {
  return true;
}
return false;

Hiç yorum yok:

Yorum Gönder