La detección de colisiones es un componente esencial en la física de videojuegos, ya que permite identificar cuándo y dónde los objetos dentro del juego interactúan entre sí. Este proceso es fundamental para simular interacciones realistas y responder adecuadamente a eventos como choques, rebotes y contactos.

Conceptos Clave

  1. Colisión: Ocurre cuando dos o más objetos en el juego se tocan o se superponen.
  2. Bounding Volume: Una forma geométrica simple que envuelve un objeto complejo para facilitar la detección de colisiones.
  3. Algoritmos de Detección: Métodos utilizados para determinar si y cuándo ocurre una colisión.

Tipos de Bounding Volumes

  1. Bounding Box (Caja Envolvente):

    • Axis-Aligned Bounding Box (AABB): Una caja que siempre está alineada con los ejes del mundo.
    • Oriented Bounding Box (OBB): Una caja que puede rotar y alinearse con el objeto que envuelve.
  2. Bounding Sphere (Esfera Envolvente): Una esfera que envuelve el objeto. Es simple y eficiente para cálculos de colisión.

  3. Bounding Capsule (Cápsula Envolvente): Una cápsula que envuelve el objeto, útil para personajes y objetos alargados.

Comparación de Bounding Volumes

Bounding Volume Ventajas Desventajas
AABB Simple y rápida de calcular No se ajusta bien a objetos rotados
OBB Se ajusta mejor a objetos rotados Más costosa de calcular
Esfera Muy rápida para cálculos de colisión No se ajusta bien a formas no esféricas
Cápsula Buena para objetos alargados Más compleja que la esfera

Algoritmos de Detección de Colisiones

  1. Detección de Colisiones AABB

El algoritmo de detección de colisiones AABB es uno de los más simples y eficientes. Se basa en verificar si las cajas envolventes de dos objetos se superponen.

Ejemplo de Código: Detección de Colisiones AABB en Python

class AABB:
    def __init__(self, min_x, min_y, max_x, max_y):
        self.min_x = min_x
        self.min_y = min_y
        self.max_x = max_x
        self.max_y = max_y

def check_collision(aabb1, aabb2):
    # Verificar si hay separación en el eje X
    if aabb1.max_x < aabb2.min_x or aabb1.min_x > aabb2.max_x:
        return False
    # Verificar si hay separación en el eje Y
    if aabb1.max_y < aabb2.min_y or aabb1.min_y > aabb2.max_y:
        return False
    # Si no hay separación en ninguno de los ejes, hay colisión
    return True

# Ejemplo de uso
aabb1 = AABB(0, 0, 2, 2)
aabb2 = AABB(1, 1, 3, 3)
print(check_collision(aabb1, aabb2))  # Output: True

  1. Detección de Colisiones Esféricas

La detección de colisiones esféricas se basa en verificar si la distancia entre los centros de dos esferas es menor que la suma de sus radios.

Ejemplo de Código: Detección de Colisiones Esféricas en Python

import math

class Sphere:
    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius

def check_collision(sphere1, sphere2):
    distance = math.sqrt((sphere1.x - sphere2.x)**2 + (sphere1.y - sphere2.y)**2)
    return distance < (sphere1.radius + sphere2.radius)

# Ejemplo de uso
sphere1 = Sphere(0, 0, 1)
sphere2 = Sphere(1, 1, 1)
print(check_collision(sphere1, sphere2))  # Output: True

Ejercicios Prácticos

Ejercicio 1: Implementar Detección de Colisiones OBB

Implementa una función en Python que verifique la colisión entre dos OBBs. Considera que cada OBB está definido por su centro, dimensiones y ángulo de rotación.

Ejercicio 2: Optimización de Detección de Colisiones

Investiga y aplica un algoritmo de partición espacial (como Quadtrees o BSP Trees) para optimizar la detección de colisiones en una escena con múltiples objetos.

Soluciones a Ejercicios

Solución al Ejercicio 1

import numpy as np

class OBB:
    def __init__(self, center, half_sizes, angle):
        self.center = np.array(center)
        self.half_sizes = np.array(half_sizes)
        self.angle = angle
        self.rotation_matrix = np.array([
            [np.cos(angle), -np.sin(angle)],
            [np.sin(angle), np.cos(angle)]
        ])

def check_collision_obb(obb1, obb2):
    # Transformar los centros de los OBBs al sistema de coordenadas del otro OBB
    T = obb2.center - obb1.center
    T = np.dot(T, obb1.rotation_matrix.T)
    
    # Proyectar las medias dimensiones de los OBBs en los ejes de cada OBB
    R = np.dot(obb1.rotation_matrix, obb2.rotation_matrix.T)
    abs_R = np.abs(R) + np.finfo(float).eps  # Añadir un pequeño valor para evitar divisiones por cero
    
    for i in range(2):
        ra = obb1.half_sizes[i]
        rb = np.dot(obb2.half_sizes, abs_R[i, :])
        if np.abs(T[i]) > ra + rb:
            return False
    
    for i in range(2):
        ra = np.dot(obb1.half_sizes, abs_R[:, i])
        rb = obb2.half_sizes[i]
        if np.abs(np.dot(T, R[:, i])) > ra + rb:
            return False
    
    return True

# Ejemplo de uso
obb1 = OBB([0, 0], [1, 1], np.pi / 4)
obb2 = OBB([1, 1], [1, 1], -np.pi / 4)
print(check_collision_obb(obb1, obb2))  # Output: True

Solución al Ejercicio 2

Para implementar un algoritmo de partición espacial como Quadtrees, se puede seguir la siguiente estructura básica:

class Quadtree:
    def __init__(self, boundary, capacity):
        self.boundary = boundary  # AABB que define los límites del quadtree
        self.capacity = capacity  # Número máximo de objetos antes de subdividir
        self.objects = []
        self.divided = False

    def subdivide(self):
        # Implementar la lógica para subdividir el quadtree en cuatro cuadrantes
        pass

    def insert(self, obj):
        # Implementar la lógica para insertar un objeto en el quadtree
        pass

    def query(self, range, found):
        # Implementar la lógica para consultar objetos en un rango específico
        pass

# Ejemplo de uso
boundary = AABB(0, 0, 10, 10)
quadtree = Quadtree(boundary, 4)
# Insertar objetos y realizar consultas

Conclusión

La detección de colisiones es una parte fundamental en la física de videojuegos, permitiendo simular interacciones realistas entre objetos. Hemos explorado diferentes tipos de bounding volumes y algoritmos de detección de colisiones, proporcionando ejemplos prácticos y ejercicios para reforzar los conceptos. En el próximo tema, abordaremos la resolución de colisiones, donde aprenderemos cómo responder adecuadamente a las colisiones detectadas.

© Copyright 2024. Todos los derechos reservados