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
- Colisión: Ocurre cuando dos o más objetos en el juego se tocan o se superponen.
- Bounding Volume: Una forma geométrica simple que envuelve un objeto complejo para facilitar la detección de colisiones.
- Algoritmos de Detección: Métodos utilizados para determinar si y cuándo ocurre una colisión.
Tipos de Bounding Volumes
-
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.
-
Bounding Sphere (Esfera Envolvente): Una esfera que envuelve el objeto. Es simple y eficiente para cálculos de colisión.
-
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
- 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
- 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.
Física de Videojuegos
Módulo 1: Introducción a la Física en Videojuegos
- Conceptos Básicos de Física
- Importancia de la Física en los Videojuegos
- Herramientas y Motores de Física
Módulo 2: Cinemática y Dinámica
- Movimiento Rectilíneo Uniforme (MRU)
- Movimiento Rectilíneo Uniformemente Acelerado (MRUA)
- Leyes de Newton
- Movimiento Circular
Módulo 3: Colisiones y Respuestas
Módulo 4: Física de Rigid Bodies
- Introducción a Rigid Bodies
- Simulación de Rigid Bodies
- Interacciones entre Rigid Bodies
- Constraints y Joints