NSAffineTransform — qué es, tipos de transformaciones y cómo aplicarlas

Autor: IT Sectr Publicado: 2026-07-22 Tiempo de lectura: 9 min

NSAffineTransform es una clase de AppKit (macOS) que representa una transformación afín en gráficos bidimensionales. Encapsula una matriz 3×3 que describe una combinación de traslación, escalado, rotación y corte de coordenadas. Según la Documentación de Apple (2026), NSAffineTransform se usa ampliamente en Core Graphics para transformar rutas, puntos y contextos gráficos en macOS.

Puntos Clave

  • NSAffineTransform es una clase de AppKit para transformaciones afines en macOS con una matriz 3×3
  • Transformación afín conserva el paralelismo de las líneas, pero puede cambiar distancias y ángulos
  • Operaciones básicas: translate (desplazamiento), scale (escala), rotate (rotación), shear (corte)
  • Las transformaciones se combinan mediante la multiplicación de matrices — el orden de las operaciones afecta el resultado
  • NSAffineTransform se aplica a puntos, tamaños, rutas y al contexto de Core Graphics

¿Qué es NSAffineTransform?

NSAffineTransform es una clase del framework AppKit, disponible solo en macOS. Representa una transformación afín en el espacio bidimensional a través de una matriz 3×3. A diferencia de CGAffineTransform de Core Graphics (que está disponible en iOS), NSAffineTransform es un envoltorio orientado a objetos sobre la estructura CGAffineTransform, añadiendo métodos convenientes para trabajar con NSBezierPath, NSPoint y NSSize.

Una transformación afín es una transformación del plano que conserva la relación “el punto está en una línea” y el paralelismo de las líneas. En otras palabras, después de una transformación afín, las líneas paralelas permanecen paralelas y las líneas rectas permanecen rectas. Sin embargo, las distancias, los ángulos y las áreas pueden cambiar: el escalado, la rotación y el corte son casos especiales de transformaciones afines.

En iOS, el equivalente de NSAffineTransform es la estructura CGAffineTransform de Core Graphics. Ambas API se basan en el mismo modelo matemático — una matriz de transformación afín 3×3 donde la última fila es siempre [0, 0, 1]. La diferencia es que NSAffineTransform es una clase (con retain/release en Objective-C), mientras que CGAffineTransform es una estructura (tipo valor) en Swift y C.

Tipos de transformaciones afines

NSAffineTransform admite cuatro tipos básicos de transformaciones: translate (traslación), scale (escalado), rotate (rotación) y shear (corte). Cada tipo está representado por un método separado y puede aplicarse a un objeto de transformación existente o usarse para crear uno nuevo.

OperaciónMétodo de NSAffineTransformParámetrosEfecto visual
TranslatetranslateXBy:yBy:deltaX, deltaYDesplaza el objeto a lo largo de los ejes X e Y
ScalescaleBy: / scaleXBy:yBy:factor / scaleX, scaleYAumenta o reduce el tamaño
RotaterotateByDegrees: / rotateByRadians:ángulo en grados o radianesRota alrededor del origen
ShearMediante setTransformStructcomponentes m12, m21 de la matrizInclina el objeto a lo largo de un eje

Translate — Traslación

Translate añade un desplazamiento a las coordenadas de todos los puntos de un objeto. Los parámetros deltaX y deltaY establecen la cantidad de desplazamiento horizontal y vertical respectivamente. Un valor positivo de deltaX desplaza a la derecha, deltaY hacia arriba. Translate no cambia la forma ni el tamaño del objeto — solo su posición.

Scale — Escalado

Scale multiplica las coordenadas de los puntos por un factor dado. Con el escalado uniforme (un solo parámetro), el objeto aumenta o disminuye proporcionalmente. Con el escalado no uniforme, la forma se distorsiona. Un factor de 1.0 deja el tamaño sin cambios, mayor de 1.0 aumenta, de 0.0 a 1.0 reduce. Los valores negativos crean un reflejo especular.

Rotate — Rotación

Rotate rota el objeto alrededor del origen en un ángulo dado. Un ángulo de rotación positivo corresponde a la rotación en sentido antihorario. rotateByDegrees acepta grados (0–360), rotateByRadians acepta radianes (0–2π). La rotación siempre se realiza con respecto al punto (0, 0), por lo que para rotar alrededor de un punto arbitrario, es necesario combinar rotate con translate.

Representación matricial 3×3

La transformación afín en NSAffineTransform se representa mediante una matriz 3×3 donde la última fila es siempre [0, 0, 1]. Esta es la representación matemática estándar que permite representar una combinación de transformaciones como un producto de matrices. La estructura de la matriz se define a través de NSAffineTransformStruct, que contiene seis componentes significativos: m11, m12, m21, m22, tX, tY.

Los componentes m11, m12, m21, m22 son responsables del escalado, la rotación y el corte. Los componentes tX y tY son responsables de la traslación. En la configuración estándar (matriz identidad), m11 = 1, m22 = 1, y el resto son 0. Para obtener los valores actuales de la matriz, se usa transformStruct — la propiedad de NSAffineTransform que devuelve una estructura NSAffineTransformStruct.

La multiplicación de matrices es una operación no conmutativa. Esto significa que el orden de aplicación de las transformaciones importa: translate + rotate da un resultado diferente que rotate + translate. Al combinar, NSAffineTransform multiplica la nueva matriz a la izquierda por la matriz actual: newMatrix = operation × currentMatrix. Por lo tanto, la última transformación añadida se aplica primero.

Composición de transformaciones

NSAffineTransform permite combinar múltiples transformaciones en un solo objeto. Cada llamada a translateXBy:yBy:, scaleBy: o rotateByDegrees: modifica la matriz interna — multiplica la matriz actual por la matriz de la transformación correspondiente. Esto permite crear una transformación compleja a partir de una secuencia de operaciones simples.

Para invertir una transformación combinada, se usa el método invert. La inversa crea una nueva transformación afín que cancela la original: si aplicas la transformación original a un punto y luego la invertida, el punto vuelve a su posición original. La inversión es útil para cancelar una transformación del contexto antes de dibujar elementos de la interfaz que no deben transformarse.

Para comprobar si una transformación es identidad (no cambia las coordenadas), se usa la propiedad isIdentity. La transformación identidad es una matriz unitaria — multiplicar por ella deja las coordenadas del punto sin cambios. Un nuevo objeto NSAffineTransform se crea como una transformación identidad. Esta propiedad es útil para la optimización: si la transformación es identidad, se puede omitir su aplicación.

Aplicación a objetos y contexto

NSAffineTransform puede aplicarse a cuatro tipos de objetos: NSPoint, NSSize, NSBezierPath y el contexto gráfico NSGraphicsContext. Para cada objetivo existe un método separado: transformPoint:, transformSize:, transformBezierPath: y set.

Transformación de puntos y tamaños

El método transformPoint: multiplica la matriz de transformación por el vector de coordenadas del punto (x, y, 1), devolviendo la nueva posición del punto. transformSize: funciona de manera similar pero no tiene en cuenta los componentes tX y tY — la traslación no se aplica, solo el escalado, la rotación y el corte. Esto es útil para transformar vectores y tamaños que no deben desplazarse.

Transformación de rutas NSBezierPath

El método transformBezierPath: crea un nuevo objeto NSBezierPath, cada punto del cual se transforma según la matriz de NSAffineTransform. La ruta original no se modifica — se crea una copia con coordenadas transformadas. Esta es una operación costosa para rutas complejas con un gran número de nodos.

Aplicación al contexto gráfico

El método set aplica la transformación al contexto gráfico actual (NSGraphicsContext), modificando su CTM (Current Transformation Matrix). Después de llamar a set, todo el dibujo posterior en este contexto se transformará. Para transformaciones temporales, usa saveGraphicsState / restoreGraphicsState antes y después de set.

Ejemplos de código en Swift

Veamos ejemplos prácticos del uso de NSAffineTransform en una aplicación de macOS para transformar objetos gráficos.

Creación y composición de transformaciones

Este ejemplo crea un NSAffineTransform que combina traslación, rotación y escalado. Primero, el objeto se desplaza por (100, 50), luego se rota 45 grados y finalmente se escala 1.5 veces. El orden importa: rotar después de trasladar rota con respecto al nuevo origen.

swift
import AppKit

let transform = NSAffineTransform()
transform.translateXBy(100, yBy: 50)
transform.rotateByDegrees(45)
transform.scaleBy(1.5)

// Aplicando al punto
let point = NSPoint(x: 10, y: 20)
let transformedPoint = transform.transform(point)

// Aplicando al tamaño
let size = NSSize(width: 100, height: 50)
let transformedSize = transform.transform(size)

Transformación del contexto para dibujo

Este ejemplo demuestra la aplicación de NSAffineTransform a un contexto gráfico mediante set y concat. Después de aplicar la transformación, todo el dibujo subsiguiente se realiza en el sistema de coordenadas transformado. Guardar el estado gráfico mediante saveGraphicsState permite volver a la matriz original.

swift
func drawWithTransform(in rect: NSRect) {
    guard let ctx = NSGraphicsContext.current
    else { return }

    ctx.saveGraphicsState()

    let xfm = NSAffineTransform()
    xfm.translateXBy(rect.midX, yBy: rect.midY)
    xfm.rotateByDegrees(30)
    xfm.scaleBy(0.8)
    xfm.concat()

    // Dibujando en el sistema de coordenadas transformado
    let path = NSBezierPath(roundedRect: NSRect(
        x: -50, y: -50,
        width: 100, height: 100
    ), xRadius: 10, yRadius: 10)
    NSColor.blue.setFill()
    path.fill()

    ctx.restoreGraphicsState()
}

Transformación de un NSBezierPath

Este ejemplo demuestra cómo crear una copia de un NSBezierPath con coordenadas transformadas. La ruta original permanece sin cambios, y la copia transformada puede dibujarse por separado — esto es útil para crear elementos repetidos en diferentes posiciones.

swift
func createTransformedTriangle() -> NSBezierPath {
    let triangle = NSBezierPath()
    triangle.move(to: NSPoint(x: 0, y: 0))
    triangle.line(to: NSPoint(x: 100, y: 0))
    triangle.line(to: NSPoint(x: 50, y: 100))
    triangle.close()

    let xfm = NSAffineTransform()
    xfm.translateXBy(200, yBy: 100)
    xfm.scaleXBy(1.5, yBy: 1.5)
    xfm.rotateByDegrees(45)

    let transformed = xfm.transform(triangle)
    return transformed
}

Preguntas Frecuentes

¿Cuál es la diferencia entre NSAffineTransform y CGAffineTransform?

NSAffineTransform es una clase de AppKit (solo macOS), mientras que CGAffineTransform es una estructura de Core Graphics (iOS y macOS). NSAffineTransform es un envoltorio orientado a objetos y proporciona métodos para trabajar con NSBezierPath. CGAffineTransform es una estructura ligera de tipo valor utilizada con CGPath.

¿Cómo roto un objeto alrededor de su centro?

Para rotar alrededor del centro, realiza tres pasos: 1) trasladar al centro del objeto (desplazar el origen al centro), 2) rotar el ángulo deseado, 3) trasladar de vuelta por el vector negativo del centro. La combinación traslación—rotación—traslación da una rotación alrededor de un punto arbitrario, en lugar de alrededor del origen.

¿Puedo usar NSAffineTransform en iOS?

No, NSAffineTransform solo está disponible en macOS como parte de AppKit. En iOS se usa la estructura CGAffineTransform de Core Graphics, que proporciona capacidades similares: CGAffineTransformMakeTranslation, CGAffineTransformMakeScale, CGAffineTransformMakeRotation y CGAffineTransformConcat.

¿Cómo cancelo una transformación?

Usa el método invert, que devuelve la transformación inversa. Si multiplicas la transformación original por la invertida, obtienes una matriz unitaria (transformación identidad). Para una aplicación temporal, llama a saveGraphicsState antes de set y restoreGraphicsState después.

¿Cómo creo un reflejo especular?

Usa escalado negativo: transform.scaleXBy(-1, yBy: 1) crea un reflejo horizontal, mientras que scaleXBy(1, yBy: -1) crea uno vertical. Para reflejar con respecto a un eje arbitrario, combina translate (desplazamiento al eje), scale con -1 y translate inverso.

Resumen

  • NSAffineTransform es una clase de AppKit para transformaciones afines con matriz 3×3 en macOS
  • Cuatro tipos básicos: translate (traslación), scale (escalado), rotate (rotación) y shear (corte)
  • La matriz 3×3 contiene seis componentes significativos: m11, m12, m21, m22, tX, tY
  • El orden de combinación de las transformaciones afecta el resultado — la multiplicación de matrices no es conmutativa
  • Se aplica a NSPoint, NSSize, NSBezierPath y al contexto gráfico a través de CTM
  • Inversión mediante el método invert cancela cualquier transformación afín
  • En iOS, el equivalente es la estructura CGAffineTransform de Core Graphics

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también