NSAffineTransform — co to je, typy transformací a jak je používat

Autor: IT Sectr Publikováno: 2026-07-22 Doba čtení: 9 min

NSAffineTransform — je třída z AppKit (macOS), která představuje afinní transformaci ve dvourozměrné grafice. Zapouzdřuje matici 3×3, která popisuje kombinaci posunutí, měřítka, otočení a zkosení souřadnic. Podle Apple Documentation (2026) je NSAffineTransform široce používán v Core Graphics pro transformaci cest, bodů a grafických kontextů na macOS.

Hlavní body

  • NSAffineTransform — třída AppKit pro afinní transformace na macOS s maticí 3×3
  • Afinní transformace zachovává rovnoběžnost čar, ale může měnit vzdálenosti a úhly
  • Hlavní operace: translate (posunutí), scale (měřítko), rotate (otočení), shear (zkosení)
  • Transformace se kombinují násobením matic — pořadí operací ovlivňuje výsledek
  • NSAffineTransform se aplikuje na body, velikosti, cesty a grafický kontext Core Graphics

Co je NSAffineTransform?

NSAffineTransform — je třída z frameworku AppKit, dostupná pouze na macOS. Představuje afinní transformaci ve dvourozměrném prostoru pomocí matice 3×3. Na rozdíl od CGAffineTransform z Core Graphics (který je dostupný na iOS), je NSAffineTransform objektově orientovaným obalem struktury CGAffineTransform, který přidává pohodlné metody pro práci s NSBezierPath, NSPoint a NSSize.

Afinní transformace — je transformace roviny, která zachovává vztah „bod leží na přímce“ a rovnoběžnost přímek. Jinými slovy, po afinní transformaci zůstávají rovnoběžné čáry rovnoběžné a přímky přímkami. Avšak vzdálenosti, úhly a plochy se mohou měnit: měřítko, otočení a zkosení jsou speciálními případy afinních transformací.

Na iOS je obdobou NSAffineTransform struktura CGAffineTransform z Core Graphics. Obě API jsou založena na stejném matematickém modelu — matici afinní transformace 3×3, kde poslední řádek je vždy [0, 0, 1]. Rozdíl je v tom, že NSAffineTransform je třída (s retain/release v Objective-C), zatímco CGAffineTransform je struktura (hodnotový typ) ve Swift a C.

Typy afinních transformací

NSAffineTransform podporuje čtyři základní typy transformací: translate (posunutí), scale (měřítko), rotate (otočení) a shear (zkosení). Každý typ je reprezentován samostatnou metodou a může být aplikován jak na existující transformační objekt, tak použit k vytvoření nového.

OperaceMetoda NSAffineTransformParametryVizuální efekt
TranslatetranslateXBy:yBy:deltaX, deltaYPosunutí objektu podél os X a Y
ScalescaleBy: / scaleXBy:yBy:factor / scaleX, scaleYZvětšení nebo zmenšení rozměrů
RotaterotateByDegrees: / rotateByRadians:úhel ve stupních nebo radiánechOtočení kolem počátku souřadnic
ShearPřes setTransformStructsložky m12, m21 maticeZkosení objektu podél osy

Translate — posunutí

Translate přidává posunutí k souřadnicím všech bodů objektu. Parametry deltaX a deltaY určují velikost posunutí horizontálně a vertikálně. Kladná hodnota deltaX posouvá doprava, deltaY — nahoru. Translate nemění tvar ani velikost objektu — pouze jeho polohu.

Scale — měřítko

Scale násobí souřadnice bodů daným faktorem. Při rovnoměrném měřítku (jeden parametr) se objekt proporcionálně zvětšuje nebo zmenšuje. Při nerovnoměrném měřítku se tvar deformuje. Faktor 1.0 ponechává velikost nezměněnou, větší než 1.0 zvětšuje, od 0.0 do 1.0 zmenšuje. Záporné hodnoty vytvářejí zrcadlení.

Rotate — otočení

Rotate otáčí objekt kolem počátku souřadnic o daný úhel. Kladný úhel otočení odpovídá otočení proti směru hodinových ručiček. rotateByDegrees přijímá stupně (0–360), rotateByRadians — radiány (0–2π). Otočení se vždy provádí vzhledem k bodu (0, 0), proto pro otočení kolem libovolného bodu je třeba kombinovat rotate s translate.

Maticová reprezentace 3×3

Afinní transformace v NSAffineTransform je reprezentována maticí 3×3, kde poslední řádek je vždy [0, 0, 1]. Toto je standardní matematická reprezentace, která umožňuje prezentovat kombinaci transformací jako součin matic. Struktura matice je definována prostřednictvím NSAffineTransformStruct, která obsahuje šest důležitých složek: m11, m12, m21, m22, tX, tY.

Složky m11, m12, m21, m22 jsou odpovědné za měřítko, otočení a zkosení. Složky tX a tY jsou odpovědné za posunutí. Ve standardní konfiguraci (jednotková matice) je m11 = 1, m22 = 1, ostatní jsou 0. Pro získání aktuálních hodnot matice se používá transformStruct — vlastnost NSAffineTransform vracející strukturu NSAffineTransformStruct.

Násobení matic je nekomutativní operace. To znamená, že pořadí aplikace transformací má význam: translate + rotate dává jiný výsledek než rotate + translate. Při kombinování NSAffineTransform násobí novou matici zleva aktuální maticí: newMatrix = operation × currentMatrix. Proto se naposledy přidaná transformace aplikuje jako první.

Kombinování transformací

NSAffineTransform umožňuje kombinovat několik transformací v jednom objektu. Každé volání translateXBy:yBy:, scaleBy: nebo rotateByDegrees: modifikuje vnitřní matici — násobí aktuální matici maticí příslušné transformace. To umožňuje vytvořit složitou transformaci z posloupnosti jednoduchých operací.

Pro inverzi kombinované transformace se používá metoda invert. Inverze vytváří novou afinní transformaci, která ruší původní: pokud na bod aplikujeme původní transformaci a poté invertovanou, bod se vrátí do původní polohy. Inverze je užitečná pro zrušení transformace kontextu před kreslením UI prvků, které by neměly být transformovány.

Ověření, zda je transformace identitická (nemění souřadnice), lze provést pomocí vlastnosti isIdentity. Identická transformace je jednotková matice, při jejímž násobení se souřadnice bodu nemění. Nový objekt NSAffineTransform je vytvořen jako identická transformace. Tato vlastnost je užitečná pro optimalizaci: pokud je transformace identická, její aplikaci lze přeskočit.

Aplikace na objekty a kontext

NSAffineTransform lze aplikovat na čtyři typy objektů: NSPoint, NSSize, NSBezierPath a grafický kontext NSGraphicsContext. Pro každý účel existuje samostatná metoda: transformPoint:, transformSize:, transformBezierPath: a set.

Transformace bodů a velikostí

Metoda transformPoint: násobí transformační matici vektorem souřadnic bodu (x, y, 1) a vrací novou polohu bodu. transformSize: funguje podobně, ale nebere v úvahu složky tX a tY — posunutí se neaplikuje, pouze měřítko, otočení a zkosení. To je užitečné pro transformaci vektorů a velikostí, které by neměly být posunuty.

Transformace cest NSBezierPath

Metoda transformBezierPath: vytváří nový objekt NSBezierPath, jehož každý bod je transformován podle matice NSAffineTransform. Původní cesta se nemění — vytváří se kopie s transformovanými souřadnicemi. Toto je nákladná operace pro složité cesty s velkým počtem uzlů.

Aplikace na grafický kontext

Metoda set aplikuje transformaci na aktuální grafický kontext (NSGraphicsContext) a modifikuje jeho CTM (Current Transformation Matrix). Po zavolání set bude veškeré následné kreslení v tomto kontextu transformováno. Pro dočasnou transformaci použijte saveGraphicsState / restoreGraphicsState před a po set.

Příklady kódu ve Swift

Podívejme se na praktické příklady použití NSAffineTransform v aplikaci pro macOS pro transformaci grafických objektů.

Vytvoření a kombinování transformací

Příklad vytváří NSAffineTransform kombinující posunutí, otočení a měřítko. Nejprve je objekt posunut o (100, 50), poté otočen o 45 stupňů a nakonec zvětšen 1.5krát. Pořadí je důležité: rotate po translate dává otočení vzhledem k novému počátku souřadnic.

swift
import AppKit

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

// Aplikace na bod
let point = NSPoint(x: 10, y: 20)
let transformedPoint = transform.transform(point)

// Aplikace na velikost
let size = NSSize(width: 100, height: 50)
let transformedSize = transform.transform(size)

Transformace kontextu pro kreslení

Příklad ukazuje aplikaci NSAffineTransform na grafický kontext pomocí set a concat. Po aplikaci transformace probíhá veškeré následné kreslení v transformovaném souřadném systému. Uložení stavu grafiky pomocí saveGraphicsState umožňuje návrat k původní matici.

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

    // Kreslení v transformovaném souřadném systému
    let path = NSBezierPath(roundedRect: NSRect(
        x: -50, y: -50,
        width: 100, height: 100
    ), xRadius: 10, yRadius: 10)
    NSColor.blue.setFill()
    path.fill()

    ctx.restoreGraphicsState()
}

Transformace cesty NSBezierPath

Příklad demonstruje vytvoření kopie NSBezierPath s transformovanými souřadnicemi. Původní cesta zůstává nezměněna a transformovaná kopie může být kreslena samostatně — to je užitečné pro vytváření opakujících se prvků na různých pozicích.

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
}

Často kladené otázky

Čím se liší NSAffineTransform od CGAffineTransform?

NSAffineTransform — je třída z AppKit (pouze macOS), zatímco CGAffineTransform — je struktura z Core Graphics (iOS a macOS). NSAffineTransform je objektově orientovaný obal a poskytuje metody pro práci s NSBezierPath. CGAffineTransform je lehká struktura hodnotového typu používaná s CGPath.

Jak otočit objekt kolem jeho středu?

Pro otočení kolem středu proveďte tři kroky: 1) translate do středu objektu (posunutí počátku souřadnic do středu), 2) rotate o požadovaný úhel, 3) translate zpět o záporný vektor středu. Kombinace translate—rotate—translate poskytuje otočení kolem libovolného bodu, ne kolem počátku souřadnic.

Lze použít NSAffineTransform na iOS?

Ne, NSAffineTransform je dostupný pouze na macOS v rámci AppKit. Na iOS se používá struktura CGAffineTransform z Core Graphics, která poskytuje podobné možnosti: CGAffineTransformMakeTranslation, CGAffineTransformMakeScale, CGAffineTransformMakeRotation a CGAffineTransformConcat.

Jak zrušit transformaci?

Použijte metodu invert, která vrací inverzní transformaci. Pokud vynásobíme původní transformaci inverzní, získáme jednotkovou matici (identickou transformaci). Pro dočasnou aplikaci zavolejte saveGraphicsState před set a restoreGraphicsState po.

Jak vytvořit zrcadlení?

Použijte záporné měřítko: transform.scaleXBy(-1, yBy: 1) vytváří horizontální zrcadlení a scaleXBy(1, yBy: -1) — vertikální zrcadlení. Pro zrcadlení vzhledem k libovolné ose kombinujte translate (posunutí na osu), scale s -1 a inverzní translate.

Shrnutí

  • NSAffineTransform — třída AppKit pro afinní transformace s maticí 3×3 na macOS
  • Čtyři základní typy: translate (posunutí), scale (měřítko), rotate (otočení) a shear (zkosení)
  • Matice 3×3 obsahuje šest důležitých složek: m11, m12, m21, m22, tX, tY
  • Pořadí kombinování transformací ovlivňuje výsledek — násobení matic je nekomutativní
  • Aplikuje se na NSPoint, NSSize, NSBezierPath a grafický kontext přes CTM
  • Inverze pomocí metody invert ruší účinek jakékoli afinní transformace
  • Na iOS je obdobou struktura CGAffineTransform z Core Graphics

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také