Ir al contenido

IDEAS PRÁCTICAS · ASIMOV INGENIERÍA

Algoritmo de Matrices de Escala y Reflexión: Conceptos, Implementación en Python y Buenas Prácticas

Guía completa sobre matrices de escala y reflexión, su teoría, ejemplos en Python, comparativas, optimización y casos de uso reales.

Imagen ilustrativa · Jakub Żerdzicki / Unsplash.

Table of contents

No titles in the blog post

Aprende la teoría, implementa ejemplos en Python y domina las mejores prácticas para usar estas transformaciones en proyectos reales.

Representación tridimensional de gráficas y análisis de datos
Imagen ilustrativa · Deng Xiang / Unsplash.

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_x controla el factor horizontal.
  • s_y controla 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

AspectoEscalaReflexión
ObjetivoCambio de tamañoCreación de espejo
Determinantes_x·s_y (≥0)-1 (inversión) o 1 (si se combina con rotación)
Preservación de ángulosSí (es isotrópica) o No (si s_x≠s_y)Sí (es una isometría)
Aplicación típicaZoom, UI responsive, modelado 3‑DSimetría, efectos visuales, pruebas de colisión
ComposiciónOrden 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

  1. Validar dimensiones: assert puntos.shape[1] == 2.
  2. Usar tipos de datos consistentes: float64 para precisión en transformación geométrica.
  3. Evitar mutaciones inesperadas: siempre devuelve una nueva matriz en vez de modificar puntos in‑place.
  4. Controlar errores de redondeo: después de múltiples transformaciones, aplana con np.round(arr, decimals=10) para evitar drift numérico.
  5. Testing unitario: compara resultados con valores esperados usando np.allclose con tolerancia rtol=1e-9.
def test_escala():
    pts = np.array([[1,1]])
    esperado = np.array([[2,3]])
    assert np.allclose(escala(pts,2,3), esperado)

© 2025 BlogTech – Transformaciones lineales con Python