NSAffineTransform — คืออะไร ชนิดของการแปลง และวิธีประยุกต์ใช้

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-22 เวลาอ่าน: 9 นาที

NSAffineTransform เป็นคลาสจาก AppKit (macOS) ที่แทนการแปลงแบบ affine ในกราฟิกสองมิติ มันห่อหุ้มเมทริกซ์ 3×3 ที่อธิบายการรวมกันของการเลื่อน การปรับขนาด การหมุน และการเฉือนของพิกัด ตามเอกสารของ Apple (2026) NSAffineTransform ถูกใช้อย่างแพร่หลายใน Core Graphics เพื่อแปลงเส้นทาง จุด และบริบทกราฟิกบน macOS

ประเด็นสำคัญ

  • NSAffineTransform เป็นคลาส AppKit สำหรับการแปลงแบบ affine บน macOS ด้วยเมทริกซ์ 3×3
  • การแปลงแบบ affine รักษาความขนานของเส้น แต่สามารถเปลี่ยนระยะทางและมุมได้
  • การดำเนินการพื้นฐาน: translate (การเลื่อน), scale (การปรับขนาด), rotate (การหมุน), shear (การเฉือน)
  • การแปลงถูกรวมผ่านการคูณเมทริกซ์ — ลำดับของการดำเนินการส่งผลต่อผลลัพธ์
  • NSAffineTransform ถูกประยุกต์ใช้กับจุด ขนาด เส้นทาง และบริบท Core Graphics

NSAffineTransform คืออะไร?

NSAffineTransform เป็นคลาสจากเฟรมเวิร์ก AppKit ที่มีเฉพาะบน macOS มันแทนการแปลงแบบ affine ในปริภูมิสองมิติผ่านเมทริกซ์ 3×3 แตกต่างจาก CGAffineTransform จาก Core Graphics (ซึ่งมีบน iOS) NSAffineTransform เป็นตัวห่อหุ้มเชิงวัตถุรอบโครงสร้าง CGAffineTransform เพิ่มเมธอดที่สะดวกสำหรับการทำงานกับ NSBezierPath, NSPoint และ NSSize

การแปลงแบบ affine คือการแปลงของระนาบที่รักษาความสัมพันธ์ “จุดอยู่บนเส้น” และความขนานของเส้น กล่าวอีกนัยหนึ่ง หลังจากการแปลงแบบ affine เส้นขนานยังคงขนานและเส้นตรงยังคงตรง อย่างไรก็ตาม ระยะทาง มุม และพื้นที่สามารถเปลี่ยนแปลงได้: การปรับขนาด การหมุน และการเฉือนเป็นกรณีพิเศษของการแปลงแบบ affine

บน iOS สิ่งที่เทียบเท่ากับ NSAffineTransform คือโครงสร้าง CGAffineTransform จาก Core Graphics API ทั้งสองใช้แบบจำลองทางคณิตศาสตร์เดียวกัน — เมทริกซ์การแปลงแบบ affine 3×3 ที่แถวสุดท้ายคือ [0, 0, 1] เสมอ ความแตกต่างคือ NSAffineTransform เป็นคลาส (มี retain/release ใน Objective-C) ในขณะที่ CGAffineTransform เป็นโครงสร้าง (ชนิดค่า) ใน Swift และ C

ชนิดของการแปลงแบบ affine

NSAffineTransform รองรับการแปลงพื้นฐานสี่ชนิด: translate (การเลื่อน), scale (การปรับขนาด), rotate (การหมุน) และ shear (การเฉือน) แต่ละชนิดแทนด้วยเมธอดแยกต่างหากและสามารถประยุกต์ใช้กับวัตถุการแปลงที่มีอยู่หรือใช้สร้างใหม่

การดำเนินการเมธอด NSAffineTransformพารามิเตอร์ผลลัพธ์ทางภาพ
TranslatetranslateXBy:yBy:deltaX, deltaYเลื่อนวัตถุตามแกน X และ Y
ScalescaleBy: / scaleXBy:yBy:factor / scaleX, scaleYขยายหรือย่อขนาด
RotaterotateByDegrees: / rotateByRadians:มุมในหน่วยองศาหรือเรเดียนหมุนรอบจุดกำเนิด
Shearผ่าน setTransformStructส่วนประกอบ m12, m21 ของเมทริกซ์เอียงวัตถุตามแนวแกน

Translate — การเลื่อน

Translate เพิ่มออฟเซ็ตให้กับพิกัดของทุกจุดของวัตถุ พารามิเตอร์ deltaX และ deltaY กำหนดปริมาณการเลื่อนในแนวนอนและแนวตั้งตามลำดับ ค่า deltaX ที่เป็นบวกเลื่อนไปทางขวา deltaY เลื่อนขึ้น Translate ไม่เปลี่ยนรูปร่างหรือขนาดของวัตถุ — เปลี่ยนเฉพาะตำแหน่ง

Scale — การปรับขนาด

Scale คูณพิกัดของจุดด้วยตัวประกอบที่กำหนด ด้วยการปรับขนาดแบบสม่ำเสมอ (พารามิเตอร์เดียว) วัตถุจะขยายหรือย่อตามสัดส่วน ด้วยการปรับขนาดไม่สม่ำเสมอ รูปร่างจะบิดเบือน ตัวประกอบ 1.0 คงขนาดไว้ มากกว่า 1.0 ขยายใหญ่ จาก 0.0 ถึง 1.0 ย่อเล็ก ค่าลบสร้างภาพสะท้อน

Rotate — การหมุน

Rotate หมุนวัตถุรอบจุดกำเนิดด้วยมุมที่กำหนด มุมหมุนที่เป็นบวกสอดคล้องกับการหมุนทวนเข็มนาฬิกา rotateByDegrees รับองศา (0–360) rotateByRadians รับเรเดียน (0–2π) การหมุนจะกระทำเทียบกับจุด (0, 0) เสมอ ดังนั้นการหมุนรอบจุดใดก็ได้ จำเป็นต้องรวม rotate กับ translate

การแสดงเมทริกซ์ 3×3

การแปลงแบบ affine ใน NSAffineTransform แสดงด้วยเมทริกซ์ 3×3 ที่แถวสุดท้ายคือ [0, 0, 1] เสมอ นี่คือการแสดงทางคณิตศาสตร์มาตรฐานที่อนุญาตให้แสดงการรวมกันของการแปลงเป็นผลคูณของเมทริกซ์ โครงสร้างเมทริกซ์ถูกกำหนดผ่าน NSAffineTransformStruct ซึ่งมีส่วนประกอบสำคัญหกส่วน: m11, m12, m21, m22, tX, tY

ส่วนประกอบ m11, m12, m21, m22 รับผิดชอบการปรับขนาด การหมุน และการเฉือน ส่วนประกอบ tX และ tY รับผิดชอบการเลื่อน ในการกำหนดค่ามาตรฐาน (เมทริกซ์เอกลักษณ์) m11 = 1, m22 = 1 และส่วนที่เหลือเท่ากับ 0 เพื่อรับค่าเมทริกซ์ปัจจุบัน ใช้ transformStruct — คุณสมบัติของ NSAffineTransform ที่คืนค่าโครงสร้าง NSAffineTransformStruct

การคูณเมทริกซ์เป็นการดำเนินการที่ไม่สลับที่ ซึ่งหมายความว่าลำดับการประยุกต์ใช้การแปลงมีความสำคัญ: translate + rotate ให้ผลลัพธ์ต่างจาก rotate + translate เมื่อรวมเข้าด้วยกัน NSAffineTransform จะคูณเมทริกซ์ใหม่ทางซ้ายด้วยเมทริกซ์ปัจจุบัน: newMatrix = operation × currentMatrix ดังนั้น การแปลงที่เพิ่มล่าสุดจะถูกนำไปใช้ก่อน

การรวมการแปลง

NSAffineTransform อนุญาตให้รวมการแปลงหลายรายการในวัตถุเดียว การเรียก translateXBy:yBy:, scaleBy: หรือ rotateByDegrees: แต่ละครั้งจะแก้ไขเมทริกซ์ภายใน — คูณเมทริกซ์ปัจจุบันด้วยเมทริกซ์ของการแปลงที่เกี่ยวข้อง ซึ่งช่วยให้สร้างการแปลงที่ซับซ้อนจากลำดับของการดำเนินการง่ายๆ

สำหรับการ กลับด้าน การแปลงที่รวมกัน ใช้เมธอด invert การกลับด้านสร้างการแปลง affine ใหม่ที่ยกเลิกการแปลงต้นฉบับ: หากคุณใช้การแปลงต้นฉบับกับจุดแล้วตามด้วยการกลับด้าน จุดจะกลับไปยังตำแหน่งเดิม การกลับด้านมีประโยชน์สำหรับการยกเลิกการแปลงบริบทธ์ก่อนวาดองค์ประกอบ UI ที่ไม่ควรถูกแปลง

ในการตรวจสอบว่าการแปลงเป็น เอกลักษณ์ (ไม่เปลี่ยนพิกัด) หรือไม่ ให้ใช้คุณสมบัติ isIdentity การแปลงเอกลักษณ์คือเมทริกซ์หน่วย — การคูณด้วยมันจะไม่เปลี่ยนพิกัดของจุด วัตถุ NSAffineTransform ใหม่ถูกสร้างขึ้นเป็นการแปลงเอกลักษณ์ คุณสมบัตินี้มีประโยชน์สำหรับการปรับให้เหมาะสม: หากการแปลงเป็นเอกลักษณ์ สามารถข้ามการประยุกต์ใช้ได้

การประยุกต์ใช้กับวัตถุและบริบท

NSAffineTransform สามารถประยุกต์ใช้กับวัตถุสี่ชนิด: NSPoint, NSSize, NSBezierPath และบริบทกราฟิก NSGraphicsContext แต่ละเป้าหมายมีเมธอดแยก: transformPoint:, transformSize:, transformBezierPath: และ set

การแปลงจุดและขนาด

เมธอด transformPoint: คูณเมทริกซ์การแปลงด้วยเวกเตอร์พิกัดของจุด (x, y, 1) และคืนค่าตำแหน่งใหม่ของจุด transformSize: ทำงานคล้ายกันแต่ไม่คำนึงถึงส่วนประกอบ tX และ tY — การเลื่อนไม่ถูกนำไปใช้ มีเพียงการปรับขนาด การหมุน และการเฉือน ซึ่งมีประโยชน์สำหรับการแปลงเวกเตอร์และขนาดที่ไม่ควรถูกเลื่อน

การแปลงเส้นทาง NSBezierPath

เมธอด transformBezierPath: สร้างวัตถุ NSBezierPath ใหม่ ซึ่งแต่ละจุดถูกแปลงตามเมทริกซ์ NSAffineTransform เส้นทางเดิมไม่ถูกแก้ไข — สำเนาที่มีพิกัดแปลงแล้วถูกสร้างขึ้น นี่เป็นการดำเนินการที่แพงสำหรับเส้นทางที่ซับซ้อนที่มีโหนดจำนวนมาก

การประยุกต์ใช้กับบริบทกราฟิก

เมธอด set ประยุกต์ใช้การแปลงกับบริบทกราฟิกปัจจุบัน (NSGraphicsContext) โดยแก้ไข CTM (Current Transformation Matrix) ของมัน หลังจากเรียก set การวาดทั้งหมดที่ตามมาในบริบทนี้จะถูกแปลง สำหรับการแปลงชั่วคราว ให้ใช้ saveGraphicsState / restoreGraphicsState ก่อนและหลัง set

ตัวอย่างโค้ด Swift

มาดู ตัวอย่างเชิงปฏิบัติ ของการใช้ NSAffineTransform ในแอปพลิเคชัน macOS เพื่อแปลงวัตถุกราฟิก

การสร้างและรวมการแปลง

ตัวอย่างนี้สร้าง NSAffineTransform ที่รวมการเลื่อน การหมุน และการปรับขนาด ขั้นแรก วัตถุถูกเลื่อนโดย (100, 50) จากนั้นหมุน 45 องศา และสุดท้ายขยาย 1.5 เท่า ลำดับมีความสำคัญ: การหมุนหลังการเลื่อนจะหมุนเทียบกับจุดกำเนิดใหม่

swift
import AppKit

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

// ประยุกต์ใช้กับจุด
let point = NSPoint(x: 10, y: 20)
let transformedPoint = transform.transform(point)

// ประยุกต์ใช้กับขนาด
let size = NSSize(width: 100, height: 50)
let transformedSize = transform.transform(size)

การแปลงบริบทสำหรับการวาด

ตัวอย่างนี้สาธิตการประยุกต์ใช้ NSAffineTransform กับบริบทกราฟิกผ่าน set และ concat หลังจากใช้การแปลง การวาดทั้งหมดที่ตามมาจะดำเนินการในระบบพิกัดที่แปลงแล้ว การบันทึกสถานะกราฟิกผ่าน saveGraphicsState ช่วยให้กลับไปยังเมทริกซ์เดิม

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

    // การวาดในระบบพิกัดที่แปลงแล้ว
    let path = NSBezierPath(roundedRect: NSRect(
        x: -50, y: -50,
        width: 100, height: 100
    ), xRadius: 10, yRadius: 10)
    NSColor.blue.setFill()
    path.fill()

    ctx.restoreGraphicsState()
}

การแปลง NSBezierPath

ตัวอย่างนี้สาธิต การสร้างสำเนา ของ NSBezierPath ด้วยพิกัดที่แปลงแล้ว เส้นทางเดิมไม่เปลี่ยนแปลง และสำเนาที่แปลงแล้วสามารถวาดแยกต่างหากได้ — ซึ่งมีประโยชน์สำหรับการสร้างองค์ประกอบที่ซ้ำกันในตำแหน่งต่างๆ

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
}

คำถามที่พบบ่อย

NSAffineTransform และ CGAffineTransform ต่างกันอย่างไร?

NSAffineTransform เป็นคลาสจาก AppKit (เฉพาะ macOS) ในขณะที่ CGAffineTransform เป็นโครงสร้างจาก Core Graphics (iOS และ macOS) NSAffineTransform เป็นตัวห่อหุ้มเชิงวัตถุและให้เมธอดสำหรับทำงานกับ NSBezierPath CGAffineTransform เป็นโครงสร้างชนิดค่าแบบเบาที่ใช้กับ CGPath

จะหมุนวัตถุรอบศูนย์กลางของมันได้อย่างไร?

ในการหมุนรอบศูนย์กลาง ให้ทำ สามขั้นตอน: 1) เลื่อนไปยังศูนย์กลางของวัตถุ (ย้ายจุดกำเนิดไปยังศูนย์กลาง), 2) หมุนด้วยมุมที่ต้องการ, 3) เลื่อนกลับด้วยเวกเตอร์ศูนย์กลางที่เป็นลบ การรวมกันเลื่อน—หมุน—เลื่อนให้การหมุนรอบจุดใดก็ได้ แทนที่จะหมุนรอบจุดกำเนิด

ฉันสามารถใช้ NSAffineTransform บน iOS ได้หรือไม่?

ไม่ NSAffineTransform มีเฉพาะบน macOS เท่านั้นในส่วนของ AppKit บน iOS ใช้โครงสร้าง CGAffineTransform จาก Core Graphics ซึ่งให้ความสามารถคล้ายกัน: CGAffineTransformMakeTranslation, CGAffineTransformMakeScale, CGAffineTransformMakeRotation และ CGAffineTransformConcat

จะยกเลิกการแปลงได้อย่างไร?

ใช้เมธอด invert ซึ่งคืนค่าการแปลงกลับด้าน หากคุณคูณการแปลงต้นฉบับด้วยการกลับด้าน คุณจะได้เมทริกซ์หน่วย (การแปลงเอกลักษณ์) สำหรับการประยุกต์ใช้ชั่วคราว ให้เรียก saveGraphicsState ก่อน set และ restoreGraphicsState หลัง

จะสร้างภาพสะท้อนได้อย่างไร?

ใช้ การปรับขนาดติดลบ: transform.scaleXBy(-1, yBy: 1) สร้างภาพสะท้อนแนวนอน ในขณะที่ scaleXBy(1, yBy: -1) สร้างภาพสะท้อนแนวตั้ง สำหรับการสะท้อนเทียบกับแกนใดก็ได้ ให้รวม translate (เลื่อนไปยังแกน), scale ด้วย -1 และ translate กลับด้าน

สรุป

  • NSAffineTransform เป็นคลาส AppKit สำหรับการแปลงแบบ affine ด้วยเมทริกซ์ 3×3 บน macOS
  • สี่ชนิดพื้นฐาน: translate (การเลื่อน), scale (การปรับขนาด), rotate (การหมุน) และ shear (การเฉือน)
  • เมทริกซ์ 3×3 ประกอบด้วยส่วนประกอบสำคัญหกส่วน: m11, m12, m21, m22, tX, tY
  • ลำดับการรวมการแปลงส่งผลต่อผลลัพธ์ — การคูณเมทริกซ์ไม่สลับที่
  • ประยุกต์ใช้กับ NSPoint, NSSize, NSBezierPath และบริบทกราฟิกผ่าน CTM
  • การกลับด้าน ผ่านเมธอด invert ยกเลิกการแปลงแบบ affine ใดๆ
  • บน iOS สิ่งที่เทียบเท่าคือโครงสร้าง CGAffineTransform จาก Core Graphics

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม