NSAffineTransform — was es ist, Arten von Transformationen und wie man sie anwendet

Autor: IT Sectr Veröffentlicht: 2026-07-22 Lesezeit: 9 Min.

NSAffineTransform ist eine Klasse aus AppKit (macOS), die eine affine Transformation in der zweidimensionalen Grafik darstellt. Sie kapselt eine 3×3-Matrix, die eine Kombination aus Verschiebung, Skalierung, Drehung und Scherung von Koordinaten beschreibt. Laut Apple-Dokumentation (2026) wird NSAffineTransform in Core Graphics häufig zum Transformieren von Pfaden, Punkten und Grafikkontexten auf macOS verwendet.

Wichtige Punkte

  • NSAffineTransform ist eine AppKit-Klasse für affine Transformationen auf macOS mit einer 3×3-Matrix
  • Affine Transformation bewahrt die Parallelität von Linien, kann aber Abstände und Winkel ändern
  • Grundlegende Operationen: translate (Verschiebung), scale (Skalierung), rotate (Drehung), shear (Scherung)
  • Transformationen werden durch Matrixmultiplikation kombiniert — die Reihenfolge der Operationen beeinflusst das Ergebnis
  • NSAffineTransform wird auf Punkte, Größen, Pfade und den Core-Graphics-Kontext angewendet

Was ist NSAffineTransform?

NSAffineTransform ist eine Klasse aus dem AppKit-Framework, die nur auf macOS verfügbar ist. Sie stellt eine affine Transformation im zweidimensionalen Raum durch eine 3×3-Matrix dar. Im Gegensatz zu CGAffineTransform aus Core Graphics (das auf iOS verfügbar ist), ist NSAffineTransform ein objektorientierter Wrapper um die CGAffineTransform-Struktur, der bequeme Methoden für die Arbeit mit NSBezierPath, NSPoint und NSSize hinzufügt.

Eine affine Transformation ist eine Transformation der Ebene, die die Beziehung „Der Punkt liegt auf einer Linie“ und die Parallelität von Linien bewahrt. Mit anderen Worten: Nach einer affinen Transformation bleiben parallele Linien parallel und gerade Linien gerade. Allerdings können sich Abstände, Winkel und Flächen ändern: Skalierung, Drehung und Scherung sind Spezialfälle von affinen Transformationen.

Auf iOS ist das Äquivalent zu NSAffineTransform die CGAffineTransform-Struktur aus Core Graphics. Beide APIs basieren auf demselben mathematischen Modell — einer 3×3-Matrix für affine Transformationen, bei der die letzte Zeile immer [0, 0, 1] ist. Der Unterschied besteht darin, dass NSAffineTransform eine Klasse (mit retain/release in Objective-C) ist, während CGAffineTransform eine Struktur (Wertetyp) in Swift und C ist.

Arten von affinen Transformationen

NSAffineTransform unterstützt vier grundlegende Arten von Transformationen: translate (Verschiebung), scale (Skalierung), rotate (Drehung) und shear (Scherung). Jede Art wird durch eine separate Methode dargestellt und kann auf ein vorhandenes Transformationsobjekt angewendet oder zum Erstellen eines neuen verwendet werden.

OperationNSAffineTransform-MethodeParameterVisueller Effekt
TranslatetranslateXBy:yBy:deltaX, deltaYVerschiebt das Objekt entlang der X- und Y-Achse
ScalescaleBy: / scaleXBy:yBy:factor / scaleX, scaleYVergrößert oder verkleinert die Größe
RotaterotateByDegrees: / rotateByRadians:Winkel in Grad oder BogenmaßDreht um den Ursprung
ShearÜber setTransformStructMatrixkomponenten m12, m21Neigt das Objekt entlang einer Achse

Translate — Verschiebung

Translate fügt den Koordinaten aller Punkte eines Objekts einen Offset hinzu. Die Parameter deltaX und deltaY legen den Betrag der horizontalen bzw. vertikalen Verschiebung fest. Ein positiver deltaX-Wert verschiebt nach rechts, deltaY nach oben. Translate ändert weder Form noch Größe des Objekts — nur seine Position.

Scale — Skalierung

Scale multipliziert die Koordinaten von Punkten mit einem gegebenen Faktor. Bei gleichmäßiger Skalierung (ein Parameter) vergrößert oder verkleinert sich das Objekt proportional. Bei ungleichmäßiger Skalierung wird die Form verzerrt. Ein Faktor von 1,0 belässt die Größe unverändert, größer als 1,0 vergrößert, von 0,0 bis 1,0 verkleinert. Negative Werte erzeugen eine Spiegelung.

Rotate — Drehung

Rotate dreht das Objekt um den Ursprung um einen gegebenen Winkel. Ein positiver Drehwinkel entspricht einer Drehung gegen den Uhrzeigersinn. rotateByDegrees akzeptiert Grad (0–360), rotateByRadians akzeptiert Bogenmaß (0–2π). Die Drehung erfolgt immer relativ zum Punkt (0, 0). Um um einen beliebigen Punkt zu drehen, muss rotate mit translate kombiniert werden.

3×3-Matrixdarstellung

Die affine Transformation in NSAffineTransform wird durch eine 3×3-Matrix dargestellt, bei der die letzte Zeile immer [0, 0, 1] ist. Dies ist die standardmäßige mathematische Darstellung, die es ermöglicht, eine Kombination von Transformationen als Produkt von Matrizen darzustellen. Die Matrixstruktur wird durch NSAffineTransformStruct definiert, die sechs signifikante Komponenten enthält: m11, m12, m21, m22, tX, tY.

Die Komponenten m11, m12, m21, m22 sind für Skalierung, Drehung und Scherung verantwortlich. Die Komponenten tX und tY sind für die Verschiebung verantwortlich. In der Standardkonfiguration (Einheitsmatrix) ist m11 = 1, m22 = 1, der Rest ist 0. Um die aktuellen Matrixwerte zu erhalten, wird transformStruct verwendet — die Eigenschaft von NSAffineTransform, die eine NSAffineTransformStruct-Struktur zurückgibt.

Die Matrixmultiplikation ist eine nicht-kommutative Operation. Das bedeutet, dass die Reihenfolge der Anwendung von Transformationen wichtig ist: translate + rotate ergibt ein anderes Ergebnis als rotate + translate. Beim Kombinieren multipliziert NSAffineTransform die neue Matrix von links mit der aktuellen Matrix: newMatrix = operation × currentMatrix. Daher wird die zuletzt hinzugefügte Transformation zuerst angewendet.

Kombinieren von Transformationen

NSAffineTransform ermöglicht das Kombinieren mehrerer Transformationen in einem einzelnen Objekt. Jeder Aufruf von translateXBy:yBy:, scaleBy: oder rotateByDegrees: modifiziert die interne Matrix — multipliziert die aktuelle Matrix mit der Matrix der entsprechenden Transformation. Dies ermöglicht die Erstellung einer komplexen Transformation aus einer Folge einfacher Operationen.

Zum Invertieren einer kombinierten Transformation wird die Methode invert verwendet. Die Inverse erzeugt eine neue affine Transformation, die die ursprüngliche aufhebt: Wenn man die ursprüngliche Transformation auf einen Punkt anwendet und dann die invertierte, kehrt der Punkt in seine ursprüngliche Position zurück. Die Invertierung ist nützlich, um eine Kontexttransformation vor dem Zeichnen von UI-Elementen aufzuheben, die nicht transformiert werden sollen.

Um zu prüfen, ob eine Transformation identisch ist (Koordinaten nicht ändert), verwendet man die Eigenschaft isIdentity. Die Identitätstransformation ist eine Einheitsmatrix — die Multiplikation mit ihr lässt die Koordinaten des Punktes unverändert. Ein neues NSAffineTransform-Objekt wird als Identitätstransformation erstellt. Diese Eigenschaft ist nützlich für die Optimierung: Wenn die Transformation identisch ist, kann ihre Anwendung übersprungen werden.

Anwendung auf Objekte und Kontext

NSAffineTransform kann auf vier Arten von Objekten angewendet werden: NSPoint, NSSize, NSBezierPath und den Grafikkontext NSGraphicsContext. Für jedes Ziel gibt es eine separate Methode: transformPoint:, transformSize:, transformBezierPath: und set.

Transformation von Punkten und Größen

Die Methode transformPoint: multipliziert die Transformationsmatrix mit dem Koordinatenvektor des Punktes (x, y, 1) und gibt die neue Position des Punktes zurück. transformSize: funktioniert ähnlich, berücksichtigt aber nicht die Komponenten tX und tY — die Verschiebung wird nicht angewendet, nur Skalierung, Drehung und Scherung. Dies ist nützlich für die Transformation von Vektoren und Größen, die nicht verschoben werden sollen.

Transformation von NSBezierPath-Pfaden

Die Methode transformBezierPath: erstellt ein neues NSBezierPath-Objekt, dessen jeder Punkt gemäß der NSAffineTransform-Matrix transformiert wird. Der ursprüngliche Pfad wird nicht verändert — es wird eine Kopie mit transformierten Koordinaten erstellt. Dies ist eine teure Operation für komplexe Pfade mit vielen Knoten.

Anwendung auf den Grafikkontext

Die Methode set wendet die Transformation auf den aktuellen Grafikkontext (NSGraphicsContext) an und modifiziert dessen CTM (Current Transformation Matrix). Nach dem Aufruf von set wird alles nachfolgende Zeichnen in diesem Kontext transformiert. Für temporäre Transformationen verwenden Sie saveGraphicsState / restoreGraphicsState vor und nach set.

Swift-Codebeispiele

Betrachten wir praktische Beispiele der Verwendung von NSAffineTransform in einer macOS-Anwendung zur Transformation von Grafikobjekten.

Erstellen und Kombinieren von Transformationen

Dieses Beispiel erstellt einen NSAffineTransform, der Verschiebung, Drehung und Skalierung kombiniert. Zuerst wird das Objekt um (100, 50) verschoben, dann um 45 Grad gedreht und schließlich um den Faktor 1,5 skaliert. Die Reihenfolge ist wichtig: Drehen nach dem Verschieben dreht relativ zum neuen Ursprung.

swift
import AppKit

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

// Auf Punkt anwenden
let point = NSPoint(x: 10, y: 20)
let transformedPoint = transform.transform(point)

// Auf Größe anwenden
let size = NSSize(width: 100, height: 50)
let transformedSize = transform.transform(size)

Kontexttransformation für das Zeichnen

Dieses Beispiel zeigt die Anwendung von NSAffineTransform auf einen Grafikkontext über set und concat. Nach dem Anwenden der Transformation erfolgt alles nachfolgende Zeichnen im transformierten Koordinatensystem. Das Speichern des Grafikzustands über saveGraphicsState ermöglicht die Rückkehr zur ursprünglichen Matrix.

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()

    // Zeichnen im transformierten Koordinatensystem
    let path = NSBezierPath(roundedRect: NSRect(
        x: -50, y: -50,
        width: 100, height: 100
    ), xRadius: 10, yRadius: 10)
    NSColor.blue.setFill()
    path.fill()

    ctx.restoreGraphicsState()
}

Transformation eines NSBezierPath

Dieses Beispiel zeigt das Erstellen einer Kopie eines NSBezierPath mit transformierten Koordinaten. Der ursprüngliche Pfad bleibt unverändert, und die transformierte Kopie kann separat gezeichnet werden — dies ist nützlich für das Erstellen von wiederholten Elementen an verschiedenen Positionen.

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
}

Häufig gestellte Fragen

Was ist der Unterschied zwischen NSAffineTransform und CGAffineTransform?

NSAffineTransform ist eine Klasse aus AppKit (nur macOS), während CGAffineTransform eine Struktur aus Core Graphics (iOS und macOS) ist. NSAffineTransform ist ein objektorientierter Wrapper und bietet Methoden für die Arbeit mit NSBezierPath. CGAffineTransform ist eine leichte Werttyp-Struktur, die mit CGPath verwendet wird.

Wie drehe ich ein Objekt um seinen Mittelpunkt?

Um um den Mittelpunkt zu drehen, führen Sie drei Schritte aus: 1) Verschieben zum Mittelpunkt des Objekts (Ursprung in die Mitte verschieben), 2) um den gewünschten Winkel drehen, 3) um den negativen Mittelpunktvektor zurückverschieben. Die Kombination Verschiebung—Drehung—Verschiebung ergibt eine Drehung um einen beliebigen Punkt, anstatt um den Ursprung.

Kann ich NSAffineTransform auf iOS verwenden?

Nein, NSAffineTransform ist nur auf macOS als Teil von AppKit verfügbar. Auf iOS wird die CGAffineTransform-Struktur aus Core Graphics verwendet, die ähnliche Funktionen bietet: CGAffineTransformMakeTranslation, CGAffineTransformMakeScale, CGAffineTransformMakeRotation und CGAffineTransformConcat.

Wie hebe ich eine Transformation auf?

Verwenden Sie die invert-Methode, die die inverse Transformation zurückgibt. Wenn Sie die ursprüngliche Transformation mit der inversen multiplizieren, erhalten Sie eine Einheitsmatrix (Identitätstransformation). Für eine temporäre Anwendung rufen Sie saveGraphicsState vor set und restoreGraphicsState danach auf.

Wie erstelle ich eine Spiegelung?

Verwenden Sie negative Skalierung: transform.scaleXBy(-1, yBy: 1) erzeugt eine horizontale Spiegelung, während scaleXBy(1, yBy: -1) eine vertikale Spiegelung erzeugt. Für eine Spiegelung relativ zu einer beliebigen Achse kombinieren Sie translate (Verschiebung zur Achse), scale mit -1 und inverse translate.

Zusammenfassung

  • NSAffineTransform ist eine AppKit-Klasse für affine Transformationen mit 3×3-Matrix auf macOS
  • Vier grundlegende Typen: translate (Verschiebung), scale (Skalierung), rotate (Drehung) und shear (Scherung)
  • Die 3×3-Matrix enthält sechs signifikante Komponenten: m11, m12, m21, m22, tX, tY
  • Die Reihenfolge der Kombination von Transformationen beeinflusst das Ergebnis — Matrixmultiplikation ist nicht kommutativ
  • Anwendung auf NSPoint, NSSize, NSBezierPath und den Grafikkontext über CTM
  • Invertierung über die Methode invert hebt jede affine Transformation auf
  • Auf iOS ist das Äquivalent die CGAffineTransform-Struktur aus Core Graphics

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch