NSAffineTransform — ay isang klase mula sa AppKit (macOS) na kumakatawan sa isang affine transformation sa dalawang-dimensional na graphics. Nag-encapsulate ito ng 3×3 matrix na naglalarawan ng kombinasyon ng paglipat, pag-scale, pag-ikot, at paggupit ng mga coordinate. Ayon sa Apple Documentation (2026), ang NSAffineTransform ay malawakang ginagamit sa Core Graphics para sa pag-transform ng mga path, punto, at graphical na konteksto sa macOS.
Mga pangunahing punto
NSAffineTransform — ay isang klase mula sa AppKit framework, available lamang sa macOS. Kinakatawan nito ang isang affine transformation sa dalawang-dimensional na espasyo sa pamamagitan ng 3×3 matrix. Hindi tulad ng CGAffineTransform mula sa Core Graphics (na available sa iOS), ang NSAffineTransform ay isang object-oriented na wrapper ng CGAffineTransform structure, na nagdaragdag ng mga maginhawang pamamaraan para sa pagtatrabaho sa NSBezierPath, NSPoint, at NSSize.
Affine transformation — ay isang pagbabago ng eroplano na nagpapanatili ng relasyon na “ang punto ay nasa isang tuwid na linya” at paralelismo ng mga linya. Sa madaling salita, pagkatapos ng affine transformation, ang mga parallel na linya ay nananatiling parallel, at ang mga tuwid na linya ay nananatiling tuwid. Gayunpaman, ang mga distansya, anggulo, at lugar ay maaaring magbago: ang pag-scale, pag-ikot, at paggupit ay mga espesyal na kaso ng affine transformations.
Sa iOS, ang katumbas ng NSAffineTransform ay ang CGAffineTransform structure mula sa Core Graphics. Ang parehong API ay batay sa parehong mathematical model — isang 3×3 affine transformation matrix kung saan ang huling row ay palaging [0, 0, 1]. Ang pagkakaiba ay ang NSAffineTransform ay isang klase (na may retain/release sa Objective-C), habang ang CGAffineTransform ay isang structure (value type) sa Swift at C.
NSAffineTransform ay sumusuporta sa apat na pangunahing uri ng transformasyon: translate (paglipat), scale (pag-scale), rotate (pag-ikot), at shear (paggupit). Ang bawat uri ay kinakatawan ng isang hiwalay na pamamaraan at maaaring ilapat sa isang umiiral na object ng transformasyon o gamitin upang lumikha ng bago.
| Operasyon | Pamamaraan ng NSAffineTransform | Mga Parameter | Epektong biswal |
|---|---|---|---|
| Translate | translateXBy:yBy: | deltaX, deltaY | Paglipat ng bagay sa kahabaan ng X at Y axes |
| Scale | scaleBy: / scaleXBy:yBy: | factor / scaleX, scaleY | Pagpapalaki o pagpapaliit ng mga sukat |
| Rotate | rotateByDegrees: / rotateByRadians: | anggulo sa degrees o radians | Pag-ikot sa paligid ng pinagmulan ng mga coordinate |
| Shear | Sa pamamagitan ng setTransformStruct | mga component na m12, m21 ng matrix | Paggupit ng bagay sa kahabaan ng axis |
Translate ay nagdaragdag ng paglipat sa mga coordinate ng lahat ng punto ng bagay. Ang mga parameter na deltaX at deltaY ay tumutukoy sa laki ng paglipat nang pahalang at patayo. Ang positibong halaga ng deltaX ay lumilipat sa kanan, deltaY — pataas. Hindi binabago ng Translate ang hugis o sukat ng bagay — tanging ang posisyon nito.
Scale ay nagpaparami ng mga coordinate ng mga punto sa isang ibinigay na factor. Sa uniform scaling (isang parameter), ang bagay ay lumalaki o lumiliit nang proporsyonal. Sa non-uniform scaling, ang hugis ay nababaluktot. Ang factor na 1.0 ay nag-iiwan ng sukat na hindi nagbabago, mas malaki sa 1.0 ay nagpapalaki, mula 0.0 hanggang 1.0 ay nagpapaliit. Ang mga negatibong halaga ay lumilikha ng salamin.
Rotate ay umiikot ng bagay sa paligid ng pinagmulan ng mga coordinate sa isang ibinigay na anggulo. Ang positibong anggulo ng pag-ikot ay tumutugma sa pag-ikot counterclockwise. rotateByDegrees ay tumatanggap ng degrees (0–360), rotateByRadians — radians (0–2π). Ang pag-ikot ay palaging isinasagawa kaugnay sa punto (0, 0), kaya para sa pag-ikot sa paligid ng isang arbitraryong punto, ang rotate ay dapat isama sa translate.
Affine transformation sa NSAffineTransform ay kinakatawan ng isang 3×3 matrix, kung saan ang huling row ay palaging [0, 0, 1]. Ito ay isang standard na mathematical representation na nagbibigay-daan sa pagpapakita ng kombinasyon ng mga transformasyon bilang produkto ng mga matrix. Ang istraktura ng matrix ay tinutukoy sa pamamagitan ng NSAffineTransformStruct, na naglalaman ng anim na mahahalagang component: m11, m12, m21, m22, tX, tY.
Ang mga component na m11, m12, m21, m22 ay responsable para sa pag-scale, pag-ikot, at paggupit. Ang mga component na tX at tY ay responsable para sa paglipat. Sa standard na configuration (identity matrix) m11 = 1, m22 = 1, ang iba ay 0. Upang makuha ang kasalukuyang halaga ng matrix, gamitin ang transformStruct — property ng NSAffineTransform na nagbabalik ng NSAffineTransformStruct structure.
Ang matrix multiplication ay isang non-commutative na operasyon. Ito ay nangangahulugan na ang pagkakasunod-sunod ng paglalapat ng mga transformasyon ay mahalaga: translate + rotate ay nagbibigay ng ibang resulta mula sa rotate + translate. Sa pagsasama, pinaparami ng NSAffineTransform ang bagong matrix sa kaliwa ng kasalukuyang matrix: newMatrix = operation × currentMatrix. Kaya, ang huling idinagdag na transformasyon ay unang inilalapat.
NSAffineTransform ay nagpapahintulot sa pagsasama ng maraming transformasyon sa isang bagay. Ang bawat tawag sa translateXBy:yBy:, scaleBy:, o rotateByDegrees: ay nagmo-modify ng internal matrix — pinaparami ang kasalukuyang matrix sa matrix ng kaukulang transformasyon. Ito ay nagbibigay-daan sa paglikha ng isang komplikadong transformasyon mula sa isang sequence ng mga simpleng operasyon.
Para sa pagbaliktad ng pinagsamang transformasyon, gamitin ang pamamaraang invert. Ang inverse ay lumilikha ng bagong affine transformation na nagkansela ng orihinal: kung ilalapat natin sa isang punto ang orihinal na transformasyon, pagkatapos ay ang inverted, ang punto ay babalik sa orihinal na posisyon. Ang inverse ay kapaki-pakinabang para sa pagkansela ng context transformation bago gumuhit ng mga UI element na hindi dapat ma-transform.
Ang pagsuri kung ang transformasyon ay identity (hindi nagbabago ng mga coordinate) ay maaaring gawin sa pamamagitan ng property na isIdentity. Ang identity transformation ay ang identity matrix, kung saan ang mga coordinate ng punto ay hindi nagbabago kapag pinarami. Ang bagong NSAffineTransform object ay nilikha bilang identity transformation. Ang property na ito ay kapaki-pakinabang para sa optimization: kung ang transformasyon ay identity, ang paglalapat nito ay maaaring laktawan.
NSAffineTransform ay maaaring ilapat sa apat na uri ng mga bagay: NSPoint, NSSize, NSBezierPath, at graphical na konteksto na NSGraphicsContext. Para sa bawat layunin mayroong hiwalay na pamamaraan: transformPoint:, transformSize:, transformBezierPath:, at set.
Pamamaraan transformPoint: ay nagpaparami ng transformation matrix sa coordinate vector ng punto (x, y, 1), na nagbabalik ng bagong posisyon ng punto. Ang transformSize: ay gumagana nang katulad ngunit hindi isinasaalang-alang ang tX at tY component — ang paglipat ay hindi inilalapat, tanging pag-scale, pag-ikot, at paggupit. Ito ay kapaki-pakinabang para sa pag-transform ng mga vector at sukat na hindi dapat ilipat.
Pamamaraan transformBezierPath: ay lumilikha ng bagong NSBezierPath object, kung saan ang bawat punto ay na-transform ayon sa NSAffineTransform matrix. Ang orihinal na path ay hindi nagbabago — isang kopya na may transformed na coordinate ay nilikha. Ito ay isang mahal na operasyon para sa komplikadong mga path na may malaking bilang ng mga node.
Pamamaraan set ay naglalapat ng transformasyon sa kasalukuyang graphical na konteksto (NSGraphicsContext), na nagmo-modify ng CTM (Current Transformation Matrix) nito. Pagkatapos tawagan ang set, lahat ng kasunod na pagguhit sa kontekstong ito ay mai-transform. Para sa pansamantalang transformasyon, gamitin ang saveGraphicsState / restoreGraphicsState bago at pagkatapos ng set.
Tingnan natin ang mga praktikal na halimbawa ng paggamit ng NSAffineTransform sa isang macOS application para sa pag-transform ng mga graphical na bagay.
Ang halimbawa ay lumilikha ng NSAffineTransform na pinagsasama ang paglipat, pag-ikot, at pag-scale. Una ang bagay ay inilipat ng (100, 50), pagkatapos ay pinaikot ng 45 degrees, at sa wakas ay pinalaki ng 1.5 beses. Ang pagkakasunod-sunod ay mahalaga: rotate pagkatapos ng translate ay nagbibigay ng pag-ikot kaugnay sa bagong pinagmulan ng mga coordinate.
import AppKit
let transform = NSAffineTransform()
transform.translateXBy(100, yBy: 50)
transform.rotateByDegrees(45)
transform.scaleBy(1.5)
// Paglalapat sa punto
let point = NSPoint(x: 10, y: 20)
let transformedPoint = transform.transform(point)
// Paglalapat sa sukat
let size = NSSize(width: 100, height: 50)
let transformedSize = transform.transform(size)
Ang halimbawa ay nagpapakita ng paglalapat ng NSAffineTransform sa graphical na konteksto sa pamamagitan ng set at concat. Pagkatapos ng paglalapat ng transformasyon, lahat ng kasunod na pagguhit ay isinasagawa sa transformed coordinate system. Ang pag-save ng graphical na estado sa pamamagitan ng saveGraphicsState ay nagbibigay-daan sa pagbalik sa orihinal na matrix.
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()
// Pagguhit sa transformed coordinate system
let path = NSBezierPath(roundedRect: NSRect(
x: -50, y: -50,
width: 100, height: 100
), xRadius: 10, yRadius: 10)
NSColor.blue.setFill()
path.fill()
ctx.restoreGraphicsState()
}
Ang halimbawa ay nagpapakita ng paglikha ng kopya ng NSBezierPath na may transformed na coordinate. Ang orihinal na path ay nananatiling hindi nagbabago, at ang transformed na kopya ay maaaring iguhit nang hiwalay — ito ay kapaki-pakinabang para sa paglikha ng mga paulit-ulit na elemento sa iba’t ibang posisyon.
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
}
Mga madalas itanong
NSAffineTransform — ay isang klase mula sa AppKit (macOS lamang), at CGAffineTransform — ay isang structure mula sa Core Graphics (iOS at macOS). Ang NSAffineTransform ay isang object-oriented na wrapper at nagbibigay ng mga pamamaraan para sa pagtatrabaho sa NSBezierPath. Ang CGAffineTransform ay isang magaan na value-type structure na ginagamit sa CGPath.
Para sa pag-ikot sa paligid ng sentro, gawin ang tatlong hakbang: 1) translate sa sentro ng bagay (paglipat ng pinagmulan ng coordinate sa sentro), 2) rotate sa nais na anggulo, 3) translate pabalik sa negatibong vector ng sentro. Ang kombinasyon na translate—rotate—translate ay nagbibigay ng pag-ikot sa paligid ng isang arbitraryong punto, hindi sa paligid ng pinagmulan ng coordinate.
Hindi, ang NSAffineTransform ay available lamang sa macOS sa loob ng AppKit. Sa iOS, ginagamit ang CGAffineTransform structure mula sa Core Graphics, na nagbibigay ng mga katulad na kakayahan: CGAffineTransformMakeTranslation, CGAffineTransformMakeScale, CGAffineTransformMakeRotation, at CGAffineTransformConcat.
Gamitin ang pamamaraang invert, na nagbabalik ng inverse transformation. Kung paramihin natin ang orihinal na transformasyon sa inverse, makakakuha tayo ng identity matrix (identity transformation). Para sa pansamantalang paglalapat, tawagan ang saveGraphicsState bago ang set at restoreGraphicsState pagkatapos.
Gamitin ang negatibong scale: transform.scaleXBy(-1, yBy: 1) ay lumilikha ng horizontal na salamin, at scaleXBy(1, yBy: -1) — vertical na salamin. Para sa salamin kaugnay sa isang arbitraryong axis, pagsamahin ang translate (paglipat sa axis), scale na may -1, at inverse translate.
Buod
invert method ay nagkakansela ng epekto ng anumang affine transformationGagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din