NSAffineTransform — egy osztály az AppKit-ből (macOS), amely egy affin transzformációt képvisel a kétdimenziós grafikában. Egy 3×3 mátrixot inkapszulál, amely a koordináták eltolásának, skálázásának, forgatásának és nyírásának kombinációját írja le. Az Apple Documentation (2026) szerint az NSAffineTransform széles körben használatos a Core Graphics-ben útvonalak, pontok és grafikus kontextusok transzformálására macOS-en.
Főbb pontok
NSAffineTransform — egy osztály az AppKit keretrendszerből, amely csak macOS-en érhető el. Egy affin transzformációt képvisel a kétdimenziós térben egy 3×3 mátrixon keresztül. Ellentétben a Core Graphics-beli CGAffineTransform-mel (amely iOS-en is elérhető), az NSAffineTransform egy objektumorientált burkoló a CGAffineTransform struktúra körül, amely kényelmes módszereket ad hozzá a NSBezierPath, NSPoint és NSSize használatához.
Affin transzformáció — a sík olyan transzformációja, amely megtartja a „pont egy egyenesen fekszik” relációt és a vonalak párhuzamosságát. Más szóval, affin transzformáció után a párhuzamos vonalak párhuzamosak maradnak, az egyenes vonalak pedig egyenesek. Azonban a távolságok, szögek és területek változhatnak: a skálázás, forgatás és nyírás az affin transzformációk speciális esetei.
iOS-en az NSAffineTransform megfelelője a CGAffineTransform struktúra a Core Graphics-ből. Mindkét API ugyanazon a matematikai modellen alapul — egy 3×3 affin transzformációs mátrixon, ahol az utolsó sor mindig [0, 0, 1]. A különbség az, hogy az NSAffineTransform egy osztály (retain/release-szel az Objective-C-ben), míg a CGAffineTransform egy struktúra (értéktípus) Swift-ben és C-ben.
NSAffineTransform négy alapvető transzformációtípust támogat: translate (eltolás), scale (skálázás), rotate (forgatás) és shear (nyírás). Minden típust egy külön metódus képvisel, és alkalmazható egy meglévő transzformációs objektumra, vagy felhasználható egy új létrehozására.
| Művelet | NSAffineTransform metódus | Paraméterek | Vizuális hatás |
|---|---|---|---|
| Translate | translateXBy:yBy: | deltaX, deltaY | Objektum eltolása az X és Y tengelyek mentén |
| Scale | scaleBy: / scaleXBy:yBy: | factor / scaleX, scaleY | Méretek növelése vagy csökkentése |
| Rotate | rotateByDegrees: / rotateByRadians: | szög fokban vagy radiánban | Forgatás a koordináták origója körül |
| Shear | setTransformStruct-on keresztül | m12, m21 mátrixkomponensek | Objektum nyírása a tengely mentén |
Translate eltolást ad hozzá az objektum összes pontjának koordinátáihoz. A deltaX és deltaY paraméterek határozzák meg az eltolás mértékét vízszintesen és függőlegesen. A pozitív deltaX érték jobbra, a deltaY — felfelé tol. A Translate nem változtatja meg az objektum alakját vagy méretét — csak a pozícióját.
Scale megszorozza a pontok koordinátáit egy adott tényezővel. Egységes skálázásnál (egy paraméter) az objektum arányosan nő vagy csökken. Nem egységes skálázásnál az alak torzul. Az 1.0 tényező változatlanul hagyja a méretet, 1.0-nál nagyobb növeli, 0.0-tól 1.0-ig csökkenti. A negatív értékek tükrözést hoznak létre.
Rotate az objektumot a koordináták origója körül egy adott szöggel forgatja. A pozitív forgatási szög az óramutató járásával ellentétes forgásnak felel meg. A rotateByDegrees fokokat (0–360), a rotateByRadians radiánokat (0–2π) fogad el. A forgatás mindig a (0, 0) ponthoz képest történik, ezért tetszőleges pont körüli forgatáshoz a rotate-t translate-tel kell kombinálni.
Affin transzformáció az NSAffineTransform-ben egy 3×3 mátrix reprezentálja, ahol az utolsó sor mindig [0, 0, 1]. Ez egy szabványos matematikai reprezentáció, amely lehetővé teszi a transzformációk kombinációjának mátrixok szorzataként történő bemutatását. A mátrix szerkezetét a NSAffineTransformStruct határozza meg, amely hat jelentős komponenst tartalmaz: m11, m12, m21, m22, tX, tY.
A m11, m12, m21, m22 komponensek felelősek a skálázásért, forgatásért és nyírásért. A tX és tY komponensek felelősek az eltolásért. A szabványos konfigurációban (egységmátrix) m11 = 1, m22 = 1, a többi 0. A mátrix aktuális értékeinek lekéréséhez a transformStruct tulajdonság használatos — az NSAffineTransform tulajdonsága, amely az NSAffineTransformStruct struktúrát adja vissza.
A mátrixszorzás nem kommutatív művelet. Ez azt jelenti, hogy a transzformációk alkalmazásának sorrendje számít: a translate + rotate más eredményt ad, mint a rotate + translate. Kombináláskor az NSAffineTransform az új mátrixot balról szorozza a jelenlegi mátrixra: newMatrix = operation × currentMatrix. Ezért az utoljára hozzáadott transzformáció kerül először alkalmazásra.
NSAffineTransform lehetővé teszi több transzformáció egyesítését egyetlen objektumban. Minden translateXBy:yBy:, scaleBy: vagy rotateByDegrees: hívás módosítja a belső mátrixot — megszorozza a jelenlegi mátrixot a megfelelő transzformáció mátrixával. Ez lehetővé teszi összetett transzformáció létrehozását egyszerű műveletek sorozatából.
A kombinált transzformáció megfordításához az invert metódus használható. Az inverz egy új affin transzformációt hoz létre, amely hatálytalanítja az eredetit: ha egy pontra alkalmazzuk az eredeti transzformációt, majd az inverzet, a pont visszatér az eredeti helyzetébe. Az inverz hasznos a kontextus transzformációjának visszavonásához olyan UI elemek rajzolása előtt, amelyeket nem szabad transzformálni.
Annak ellenőrzése, hogy a transzformáció identitás-e (nem változtatja meg a koordinátákat), az isIdentity tulajdonságon keresztül végezhető el. Az identitás transzformáció az egységmátrix, amellyel megszorozva a pont koordinátái nem változnak. Az új NSAffineTransform objektum identitás transzformációként jön létre. Ez a tulajdonság optimalizáláshoz hasznos: ha a transzformáció identitás, az alkalmazása kihagyható.
NSAffineTransform négy típusú objektumra alkalmazható: NSPoint, NSSize, NSBezierPath és NSGraphicsContext grafikus kontextus. Minden célhoz külön metódus tartozik: transformPoint:, transformSize:, transformBezierPath: és set.
Metódus transformPoint: megszorozza a transzformációs mátrixot a pont koordináta vektorával (x, y, 1), és visszaadja a pont új pozícióját. A transformSize: hasonlóan működik, de nem veszi figyelembe a tX és tY komponenseket — az eltolás nem kerül alkalmazásra, csak a skálázás, forgatás és nyírás. Ez hasznos olyan vektorok és méretek transzformálásához, amelyeket nem szabad eltolni.
Metódus transformBezierPath: egy új NSBezierPath objektumot hoz létre, amelynek minden pontja az NSAffineTransform mátrix szerint transzformálódik. Az eredeti útvonal nem változik — egy másolat jön létre transzformált koordinátákkal. Ez egy költséges művelet összetett, sok csomópontot tartalmazó útvonalak esetén.
Metódus set alkalmazza a transzformációt a jelenlegi grafikus kontextusra (NSGraphicsContext), módosítva annak CTM-jét (Current Transformation Matrix). A set meghívása után az ebben a kontextusban végzett összes későbbi rajzolás transzformálva lesz. Ideiglenes transzformációhoz használja a saveGraphicsState / restoreGraphicsState függvényeket a set előtt és után.
Nézzük meg a gyakorlati példákat az NSAffineTransform használatára egy macOS alkalmazásban grafikus objektumok transzformálásához.
A példa egy NSAffineTransform-et hoz létre, amely eltolást, forgatást és skálázást kombinál. Először az objektum (100, 50) eltolást kap, majd 45 fokkal elforgatják, végül 1.5-szeresére nagyítják. A sorrend fontos: a translate utáni rotate az új koordináta-origóhoz képest forgat.
import AppKit
let transform = NSAffineTransform()
transform.translateXBy(100, yBy: 50)
transform.rotateByDegrees(45)
transform.scaleBy(1.5)
// Alkalmazás pontra
let point = NSPoint(x: 10, y: 20)
let transformedPoint = transform.transform(point)
// Alkalmazás méretre
let size = NSSize(width: 100, height: 50)
let transformedSize = transform.transform(size)
A példa az NSAffineTransform grafikus kontextusra való alkalmazását mutatja be a set és concat segítségével. A transzformáció alkalmazása után az összes későbbi rajzolás a transzformált koordináta-rendszerben történik. A grafikus állapot mentése a saveGraphicsState segítségével lehetővé teszi az eredeti mátrixhoz való visszatérést.
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()
// Rajzolás transzformált koordináta-rendszerben
let path = NSBezierPath(roundedRect: NSRect(
x: -50, y: -50,
width: 100, height: 100
), xRadius: 10, yRadius: 10)
NSColor.blue.setFill()
path.fill()
ctx.restoreGraphicsState()
}
A példa az NSBezierPath másolatának létrehozását mutatja be transzformált koordinátákkal. Az eredeti útvonal változatlan marad, a transzformált másolat pedig külön rajzolható — ez hasznos ismétlődő elemek létrehozásához különböző pozíciókban.
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
}
Gyakran ismételt kérdések
NSAffineTransform — egy osztály az AppKit-ből (csak macOS), míg a CGAffineTransform — egy struktúra a Core Graphics-ből (iOS és macOS). Az NSAffineTransform egy objektumorientált burkoló, és módszereket biztosít a NSBezierPath használatához. A CGAffineTransform egy könnyű értéktípusú struktúra, amelyet a CGPath-pel használnak.
A középpont körüli forgatáshoz három lépést hajtson végre: 1) translate az objektum középpontjába (a koordináta-origó áthelyezése a középpontba), 2) rotate a kívánt szöggel, 3) translate vissza a középpont negatív vektorával. A translate—rotate—translate kombináció tetszőleges pont körüli forgatást biztosít, nem a koordináta-origó körül.
Nem, az NSAffineTransform csak macOS-en érhető el az AppKit keretrendszerben. iOS-en a CGAffineTransform struktúrát használják a Core Graphics-ből, amely hasonló képességeket biztosít: CGAffineTransformMakeTranslation, CGAffineTransformMakeScale, CGAffineTransformMakeRotation és CGAffineTransformConcat.
Használja az invert metódust, amely visszaadja az inverz transzformációt. Ha az eredeti transzformációt megszorozzuk az inverzzel, megkapjuk az egységmátrixot (identitás transzformáció). Ideiglenes alkalmazáshoz hívja meg a saveGraphicsState függvényt a set előtt és a restoreGraphicsState függvényt utána.
Használjon negatív skálázást: a transform.scaleXBy(-1, yBy: 1) vízszintes tükrözést hoz létre, a scaleXBy(1, yBy: -1) pedig függőleges tükrözést. Tetszőleges tengelyhez viszonyított tükrözéshez kombinálja a translate-t (eltolás a tengelyre), a scale-t -1-gyel és az inverz translate-t.
Összefoglaló
invert metódussal hatálytalanítja bármely affin transzformáció hatásátKulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is