NSAffineTransform — wat is het, soorten transformaties en hoe toe te passen

Auteur: IT Sectr Gepubliceerd: 2026-07-22 Leestijd: 9 min

NSAffineTransform — is een klasse uit AppKit (macOS) die een affiene transformatie in tweedimensionale grafische voorstelling vertegenwoordigt. Het kapselt een 3×3 matrix in die een combinatie van verplaatsing, schaling, rotatie en afschuiving van coördinaten beschrijft. Volgens Apple Documentation (2026) wordt NSAffineTransform veel gebruikt in Core Graphics voor het transformeren van paden, punten en grafische contexten op macOS.

Belangrijkste punten

  • NSAffineTransform — AppKit-klasse voor affiene transformaties op macOS met een 3×3 matrix
  • Affiene transformatie behoudt de parallelliteit van lijnen, maar kan afstanden en hoeken veranderen
  • Belangrijkste operaties: translate (verplaatsing), scale (schaling), rotate (rotatie), shear (afschuiving)
  • Transformaties worden gecombineerd door matrixvermenigvuldiging — de volgorde van operaties beïnvloedt het resultaat
  • NSAffineTransform wordt toegepast op punten, afmetingen, paden en grafische context van Core Graphics

Wat is NSAffineTransform?

NSAffineTransform — is een klasse uit het AppKit-framework, alleen beschikbaar op macOS. Het vertegenwoordigt een affiene transformatie in de tweedimensionale ruimte via een 3×3 matrix. In tegenstelling tot CGAffineTransform uit Core Graphics (die beschikbaar is op iOS), is NSAffineTransform een objectgeoriënteerde wrapper rond de CGAffineTransform-structuur, die handige methoden toevoegt voor het werken met NSBezierPath, NSPoint en NSSize.

Affiene transformatie — is een transformatie van het vlak die de relatie „punt ligt op een rechte lijn” en parallelliteit van lijnen behoudt. Met andere woorden, na een affiene transformatie blijven parallelle lijnen parallel en rechte lijnen recht. Echter, afstanden, hoeken en oppervlakten kunnen veranderen: schaling, rotatie en afschuiving zijn speciale gevallen van affiene transformaties.

Op iOS is de tegenhanger van NSAffineTransform de CGAffineTransform-structuur uit Core Graphics. Beide API’s zijn gebaseerd op hetzelfde wiskundige model — een 3×3 affiene transformatiematrix waarvan de laatste rij altijd [0, 0, 1] is. Het verschil is dat NSAffineTransform een klasse is (met retain/release in Objective-C), terwijl CGAffineTransform een structuur (waardetype) is in Swift en C.

Soorten affiene transformaties

NSAffineTransform ondersteunt vier basistypen transformaties: translate (verplaatsing), scale (schaling), rotate (rotatie) en shear (afschuiving). Elk type wordt vertegenwoordigd door een aparte methode en kan zowel worden toegepast op een bestaand transformatieobject als worden gebruikt om een nieuwe te maken.

OperatieNSAffineTransform-methodeParametersVisueel effect
TranslatetranslateXBy:yBy:deltaX, deltaYVerplaatsing van object langs X- en Y-as
ScalescaleBy: / scaleXBy:yBy:factor / scaleX, scaleYVergroten of verkleinen van afmetingen
RotaterotateByDegrees: / rotateByRadians:hoek in graden of radialenRotatie rond de oorsprong van coördinaten
ShearVia setTransformStructmatrixcomponenten m12, m21Afschuiving van object langs de as

Translate - verplaatsing

Translate voegt een verplaatsing toe aan de coördinaten van alle punten van het object. De parameters deltaX en deltaY geven respectievelijk de grootte van de horizontale en verticale verplaatsing aan. Een positieve deltaX-waarde verplaatst naar rechts, deltaY — naar boven. Translate verandert de vorm of grootte van het object niet — alleen de positie.

Scale - schaling

Scale vermenigvuldigt de coördinaten van punten met een gegeven factor. Bij uniforme schaling (één parameter) wordt het object proportioneel vergroot of verkleind. Bij niet-uniforme schaling wordt de vorm vervormd. Factor 1.0 laat de grootte ongewijzigd, groter dan 1.0 vergroot, van 0.0 tot 1.0 verkleint. Negatieve waarden creëren spiegeling.

Rotate - rotatie

Rotate roteert het object rond de oorsprong van het coördinatenstelsel over een gegeven hoek. Een positieve rotatiehoek komt overeen met rotatie tegen de klok in. rotateByDegrees accepteert graden (0–360), rotateByRadians — radialen (0–2π). Rotatie wordt altijd uitgevoerd ten opzichte van punt (0, 0), dus voor rotatie rond een willekeurig punt moet rotate worden gecombineerd met translate.

Matrixweergave 3×3

Affiene transformatie in NSAffineTransform wordt weergegeven door een 3×3 matrix, waarvan de laatste rij altijd [0, 0, 1] is. Dit is een standaard wiskundige weergave die het mogelijk maakt een combinatie van transformaties als product van matrices weer te geven. De structuur van de matrix wordt gedefinieerd via NSAffineTransformStruct, die zes belangrijke componenten bevat: m11, m12, m21, m22, tX, tY.

De componenten m11, m12, m21, m22 zijn verantwoordelijk voor schaling, rotatie en afschuiving. De componenten tX en tY zijn verantwoordelijk voor verplaatsing. In de standaardconfiguratie (eenheidsmatrix) zijn m11 = 1, m22 = 1, de rest is 0. Om de huidige matrixwaarden op te halen, wordt transformStruct gebruikt — de eigenschap van NSAffineTransform die de structuur NSAffineTransformStruct retourneert.

Matrixvermenigvuldiging is een niet-commutatieve bewerking. Dit betekent dat de volgorde van toepassing van transformaties ertoe doet: translate + rotate geeft een ander resultaat dan rotate + translate. Bij het combineren vermenigvuldigt NSAffineTransform de nieuwe matrix links met de huidige matrix: newMatrix = operation × currentMatrix. Daarom wordt de laatst toegevoegde transformatie als eerste toegepast.

Combineren van transformaties

NSAffineTransform maakt het mogelijk meerdere transformaties in één object te combineren. Elke aanroep van translateXBy:yBy:, scaleBy: of rotateByDegrees: wijzigt de interne matrix — vermenigvuldigt de huidige matrix met de matrix van de corresponderende transformatie. Dit maakt het mogelijk een complexe transformatie te creëren uit een reeks eenvoudige operaties.

Voor het inverteren van een gecombineerde transformatie wordt de methode invert gebruikt. De inverse creëert een nieuwe affiene transformatie die de originele tenietdoet: als we op een punt eerst de originele transformatie toepassen en daarna de inverse, keert het punt terug naar de oorspronkelijke positie. De inverse is nuttig voor het ongedaan maken van contexttransformatie vóór het tekenen van UI-elementen die niet getransformeerd mogen worden.

Controleren of een transformatie identiteit is (coördinaten niet verandert) kan via de eigenschap isIdentity. De identiteitstransformatie is de eenheidsmatrix, bij vermenigvuldiging waarmee de coördinaten van een punt niet veranderen. Een nieuw NSAffineTransform-object wordt gemaakt als identiteitstransformatie. Deze eigenschap is nuttig voor optimalisatie: als de transformatie identiteit is, kan de toepassing ervan worden overgeslagen.

Toepassen op objecten en context

NSAffineTransform kan worden toegepast op vier soorten objecten: NSPoint, NSSize, NSBezierPath en de grafische context NSGraphicsContext. Voor elk doel bestaat een aparte methode: transformPoint:, transformSize:, transformBezierPath: en set.

Transformatie van punten en afmetingen

Methode transformPoint: vermenigvuldigt de transformatiematrix met de coördinatenvector van het punt (x, y, 1) en retourneert de nieuwe positie van het punt. transformSize: werkt vergelijkbaar, maar houdt geen rekening met de tX- en tY-componenten — verplaatsing wordt niet toegepast, alleen schaling, rotatie en afschuiving. Dit is nuttig voor transformatie van vectoren en afmetingen die niet mogen worden verplaatst.

Transformatie van NSBezierPath-paden

Methode transformBezierPath: creëert een nieuw NSBezierPath-object waarvan elk punt is getransformeerd volgens de NSAffineTransform-matrix. Het originele pad verandert niet — er wordt een kopie met getransformeerde coördinaten gemaakt. Dit is een dure operatie voor complexe paden met een groot aantal knooppunten.

Toepassen op grafische context

Methode set past de transformatie toe op de huidige grafische context (NSGraphicsContext) en wijzigt de CTM (Current Transformation Matrix). Na het aanroepen van set wordt al het daaropvolgende tekenen in deze context getransformeerd. Gebruik voor tijdelijke transformatie saveGraphicsState / restoreGraphicsState vóór en na set.

Codevoorbeelden in Swift

Laten we praktische voorbeelden bekijken van het gebruik van NSAffineTransform in een macOS-applicatie voor transformatie van grafische objecten.

Maken en combineren van transformaties

Het voorbeeld creëert een NSAffineTransform die verplaatsing, rotatie en schaling combineert. Eerst wordt het object verplaatst naar (100, 50), vervolgens geroteerd over 45 graden en ten slotte 1.5 keer vergroot. De volgorde is belangrijk: rotate na translate geeft rotatie ten opzichte van de nieuwe oorsprong van het coördinatenstelsel.

swift
import AppKit

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

// Toepassen op punt
let point = NSPoint(x: 10, y: 20)
let transformedPoint = transform.transform(point)

// Toepassen op grootte
let size = NSSize(width: 100, height: 50)
let transformedSize = transform.transform(size)

Contexttransformatie voor tekenen

Het voorbeeld toont het toepassen van NSAffineTransform op de grafische context via set en concat. Na toepassing van de transformatie wordt al het daaropvolgende tekenen uitgevoerd in het getransformeerde coördinatensysteem. Opslaan van de grafische status via saveGraphicsState maakt het mogelijk terug te keren naar de originele 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()

    // Tekenen in getransformeerd coördinatensysteem
    let path = NSBezierPath(roundedRect: NSRect(
        x: -50, y: -50,
        width: 100, height: 100
    ), xRadius: 10, yRadius: 10)
    NSColor.blue.setFill()
    path.fill()

    ctx.restoreGraphicsState()
}

Transformatie van NSBezierPath-pad

Het voorbeeld demonstreert het maken van een kopie van NSBezierPath met getransformeerde coördinaten. Het originele pad blijft ongewijzigd en de getransformeerde kopie kan afzonderlijk worden getekend — dit is nuttig voor het creëren van herhalende elementen op verschillende posities.

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
}

Veelgestelde vragen

Wat is het verschil tussen NSAffineTransform en CGAffineTransform?

NSAffineTransform — is een klasse uit AppKit (alleen macOS), en CGAffineTransform — is een structuur uit Core Graphics (iOS en macOS). NSAffineTransform is een objectgeoriënteerde wrapper en biedt methoden voor het werken met NSBezierPath. CGAffineTransform is een lichte waardetype-structuur die wordt gebruikt met CGPath.

Hoe roteer je een object rond zijn middelpunt?

Voer voor rotatie rond het middelpunt drie stappen uit: 1) translate naar het middelpunt van het object (verplaatsing van de oorsprong naar het midden), 2) rotate over de gewenste hoek, 3) translate terug met de negatieve vector van het middelpunt. De combinatie translate—rotate—translate geeft rotatie rond een willekeurig punt, niet rond de oorsprong van het coördinatenstelsel.

Kan NSAffineTransform op iOS worden gebruikt?

Nee, NSAffineTransform is alleen beschikbaar op macOS binnen AppKit. Op iOS wordt de CGAffineTransform-structuur uit Core Graphics gebruikt, die vergelijkbare mogelijkheden biedt: CGAffineTransformMakeTranslation, CGAffineTransformMakeScale, CGAffineTransformMakeRotation en CGAffineTransformConcat.

Hoe maak je een transformatie ongedaan?

Gebruik de methode invert, die de inverse transformatie retourneert. Als we de originele transformatie met de inverse vermenigvuldigen, krijgen we de eenheidsmatrix (identiteitstransformatie). Gebruik voor tijdelijke toepassing saveGraphicsState vóór set en restoreGraphicsState erna.

Hoe maak je een spiegelbeeld?

Gebruik negatieve schaling: transform.scaleXBy(-1, yBy: 1) creëert horizontale spiegeling en scaleXBy(1, yBy: -1) verticale spiegeling. Voor spiegeling ten opzichte van een willekeurige as, combineer translate (verplaatsing naar de as), scale met -1 en inverse translate.

Samenvatting

  • NSAffineTransform — AppKit-klasse voor affiene transformaties met 3×3 matrix op macOS
  • Vier basistypen: translate (verplaatsing), scale (schaling), rotate (rotatie) en shear (afschuiving)
  • 3×3 matrix bevat zes belangrijke componenten: m11, m12, m21, m22, tX, tY
  • Volgorde van combineren beïnvloedt het resultaat — matrixvermenigvuldiging is niet-commutatief
  • Wordt toegepast op NSPoint, NSSize, NSBezierPath en grafische context via CTM
  • Inverse via methode invert maakt elke affiene transformatie ongedaan
  • Op iOS is het equivalent de structuur CGAffineTransform uit Core Graphics

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook