Algoritmo de Matrices de Escala y Reflexión
Aprende la teoría, implementa ejemplos en Python y domina las mejores prácticas para usar estas transformaciones en proyectos reales.
1️⃣ ¿Qué son las matrices de escala?
Una matriz de escala permite cambiar el tamaño de un objeto en uno o varios ejes. En 2‑D, la forma más simple es:
S(s_x, s_y) = \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix}
s_xcontrola el factor horizontal.s_ycontrola el factor vertical.- Valores mayores que 1 agrandan; entre 0 y 1 reducen; negativos invierten el eje.
2️⃣ ¿Qué son las matrices de reflexión?
Una matriz de reflexión voltea un punto respecto a una línea (eje) de simetría. En 2‑D las más comunes son:
R_x = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} \quad // Reflejo sobre el eje X
R_y = \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix} \quad // Reflejo sobre el eje Y
R_{\theta}=\begin{bmatrix} \cos2\theta & \sin2\theta \\ \sin2\theta & -\cos2\theta \end{bmatrix} // Reflejo sobre una recta con ángulo \theta
Los valores -1 invierten la coordenada correspondiente, creando el espejo.
🔧 Implementación en Python (NumPy)
NumPy es la librería estándar para cálculos matriciales. A continuación, ejemplos completos con explicación paso‑a‑paso.
Escalado uniforme y no uniforme
import numpy as np
def escala(puntos, sx, sy):
"""Aplica escala a un conjunto de puntos 2‑D.
Args:
puntos (np.ndarray): shape (N, 2) con coordenadas x, y.
sx (float): factor de escala en X.
sy (float): factor de escala en Y.
"""
S = np.array([[sx, 0],
[0, sy]])
return puntos @ S.T # multiplicación matricial
# Ejemplo rápido
pts = np.array([[1, 2], [3, 4], [-1, -1]])
print('Original:', pts)
print('Escala 2x en X y 0.5x en Y:', escala(pts, 2, 0.5))
⚡ Tip de rendimiento: usa @ (operador matmul) en lugar de np.dot para mayor claridad y velocidad con float64.
Reflexión respecto a ejes y a una línea arbitraria
def reflejar(puntos, eje='x', theta=None):
"""Refleja puntos según el eje o ángulo.
Args:
puntos (np.ndarray): shape (N,2).
eje (str): 'x' o 'y' para ejes principales.
theta (float): ángulo en radianes para reflexión sobre línea.
"""
if eje == 'x':
R = np.array([[1, 0], [0, -1]])
elif eje == 'y':
R = np.array([[-1, 0], [0, 1]])
elif theta is not None:
c, s = np.cos(2*theta), np.sin(2*theta)
R = np.array([[c, s], [s, -c]])
else:
raise ValueError('Especifique eje="x"/"y" o theta.')
return puntos @ R.T
# Reflexión sobre eje X
print('Reflejo X:', reflejar(pts, eje='x'))
# Reflexión sobre línea que forma 45° (π/4 rad)
print('Reflejo 45°:', reflejar(pts, theta=np.pi/4))
🔐 Seguridad y validación: siempre verifica la forma de la matriz de entrada (puntos.shape == (N,2)) para evitar errores de broadcasting.
⚖️ Comparativa rápida: Escala vs Reflexión
Características
| Aspecto | Escala | Reflexión |
|---|---|---|
| Objetivo | Cambio de tamaño | Creación de espejo |
| Determinante | s_x·s_y (≥0) | -1 (inversión) o 1 (si se combina con rotación) |
| Preservación de ángulos | Sí (es isotrópica) o No (si s_x≠s_y) | Sí (es una isometría) |
| Aplicación típica | Zoom, UI responsive, modelado 3‑D | Simetría, efectos visuales, pruebas de colisión |
| Composición | Orden de multiplicación importa (no conmutativa) | Conmutativa solo con otras reflexiones ortogonales |
Rendimiento (Python/NumPy)
Ambas operaciones son O(N) para N puntos, ya que solo requieren una multiplicación por 2×2. Sin embargo, la reflexión sobre una línea arbitraria implica cálculo trigonométrico (cos, sin) que puede ser pre‑calculado si el ángulo es constante.
# Pre‑cálculo de R para ángulo fijo
theta = np.pi/6
c, s = np.cos(2*theta), np.sin(2*theta)
R_fixed = np.array([[c, s], [s, -c]])
# Uso posterior sin volver a calcular trigonometría
reflejado = puntos @ R_fixed.T
🔧 Optimización: para millones de puntos, emplea numpy.einsum o numba para evitar temporales intermedios.
🚀 Casos de uso del mundo real
- Visor GIS: escalar coordenadas para cambiar la resolución del mapa.
- Motor de videojuegos: reflejar sprites para crear animaciones de espejo sin duplicar assets.
- Procesamiento de imágenes: aplicar reflexión como paso de data‑augmentation en entrenamiento de redes neuronales.
- CAD / CAM: escalar modelos 3‑D antes de generar código G‑code.
🛠️ Depuración y buenas prácticas
- Validar dimensiones:
assert puntos.shape[1] == 2. - Usar tipos de datos consistentes:
float64para precisión en transformación geométrica. - Evitar mutaciones inesperadas: siempre devuelve una nueva matriz en vez de modificar
puntosin‑place. - Controlar errores de redondeo: después de múltiples transformaciones, aplana con
np.round(arr, decimals=10)para evitar drift numérico. - Testing unitario: compara resultados con valores esperados usando
np.allclosecon toleranciartol=1e-9.
def test_escala():
pts = np.array([[1,1]])
esperado = np.array([[2,3]])
assert np.allclose(escala(pts,2,3), esperado)
Algoritmo de Matrices de Escala y Reflexión: Conceptos, Implementación en Python y Buenas Prácticas