๐Ÿ…ฟ๏ธComplexNumber

swift โŸฉ type โŸฉ custom โŸฉ package โŸฉ GeometryKit โŸฉ ComplexNumber

// History:
// โ€ข 2024.12.09 - draft
// โ€ข 2024.12.11 - version 1.0

// Protocol Inheritance Hierarchy
// โ€ข MetricSpace -> Vector -> Vector2D -> ComplextNumber

// ---------------------------
//      ๐Ÿ…ฟ๏ธ ComplexNumber
// ---------------------------

/// ๅปฃ็พฉ็š„ใ€Œ่ค‡ๆ•ธใ€ๅ”ๅฎš
///
/// ่ฎ“ไธ€่ˆฌๅž‹ๅˆฅ(ๅฆ‚๏ผšCGPoint)ๅฏ้ตๅพช ComplexNumber ๅ”่ญฐ๏ผŒ
/// ่ฎ“ๅฎƒๅ€‘ๆ“ๆœ‰่ค‡ๆ•ธ็š„่จˆ็ฎ—่ƒฝๅŠ›๏ผˆๅฆ‚๏ผš่ค‡ๆ•ธไน˜ๆณ•ไปฃ่กจๆ—‹่ฝ‰่ˆ‡็ธฎๆ”พ๏ผ‰
///
/// ```swift
/// import CoreGraphics
///
/// // ๐ŸŒ€CGSize + ComplexNumber
/// extension CGSize: ComplexNumber {
///
///     public typealias Scalar = CGFloat
///
///     // required properties
///     public var x: CGFloat { width }
///     public var y: CGFloat { height }
///
///     // required initializer
///     public init(x: CGFloat, y: CGFloat) {
///         self.init(width: x, height: y)
///     }
/// }
/// ```
public protocol ComplexNumber: Vector2D {
    
    // default behavior provided by Vector2D
    // โ€ข ๅŠ ๆณ•ๅๅ…ƒ็ด : -v
    // โ€ข ่ค‡ๆ•ธๅŠ ๆณ•๏ผšu + v
    // โ€ข ่ค‡ๆ•ธๆธ›ๆณ•๏ผšu - v
    // โ€ข ็ด”้‡็ฉ๏ผšv * a, a * v, v / a
    
    // โญ๏ธ ่ค‡ๆ•ธ้‹็ฎ—
    
    /// ่ค‡ๆ•ธไน˜ๆณ•๏ผšu * v
    static func * (u: Self, v: Self) -> Self
    
    /// ่ค‡ๆ•ธ้™คๆณ•๏ผšu / v
    static func / (u: Self, v: Self) -> Self
    
    /// ่ค‡ๆ•ธ้™คๆณ•๏ผša / v
    static func / (a: Scalar, v: Self) -> Self
    
}

// ----------------------------------------------
//      ๐ŸŒ€ ComplexNumber (default behaviors)
// ----------------------------------------------

public extension ComplexNumber {
    
    // default behavior provided by Vector2D
    // โ€ข u + v, u += v
    // โ€ข u - v, u -= v
    // โ€ข u * a, u *= a
    // โ€ข u / a, u /= a
    // ่ค‡ๆ•ธ้•ทๅบฆ๏ผš
    // โ€ข normSqaured ( |z|ยฒ = xยฒ + yยฒ   )
    // โ€ข magnitude   ( |z| = โˆš(xยฒ + yยฒ) )
    // โ€ข norm        ( = magnitude      )
    
    
    /// ๅ…ฑ่ป›่ค‡ๆ•ธ๏ผš a - bi
    var conjugate: Self {
        Self.init(x: x, y: -y)
    }
    
    /* ------- u + v, u - v ------- */
    
    /// ่ค‡ๆ•ธๅŠ ๆณ•๏ผša + v
    @inlinable    // ๆธ›ๅฐ‘้‹็ฎ—้ ป็น่ชฟ็”จ็š„้–‹้Šท
    static func + (a: Scalar, v: Self) -> Self {
        Self.init(x: a + v.x, y: v.y)
    }
    
    /// ่ค‡ๆ•ธๅŠ ๆณ•๏ผšv + a
    @inlinable    // ๆธ›ๅฐ‘้‹็ฎ—้ ป็น่ชฟ็”จ็š„้–‹้Šท
    static func + (v: Self, a: Scalar) -> Self {
        Self.init(x: a + v.x, y: v.y)
    }
    
    // u += a
    static func += (u: inout Self, a: Scalar) {
        u = u + a
    }
    
    /// ่ค‡ๆ•ธๆธ›ๆณ•๏ผša - v
    @inlinable    // ๆธ›ๅฐ‘้‹็ฎ—้ ป็น่ชฟ็”จ็š„้–‹้Šท
    static func - (a: Scalar, v: Self) -> Self {
        Self.init(x: a - v.x, y: -v.y)
    }
        
    /// ่ค‡ๆ•ธๆธ›ๆณ•๏ผšv - a
    @inlinable    // ๆธ›ๅฐ‘้‹็ฎ—้ ป็น่ชฟ็”จ็š„้–‹้Šท
    static func - (v: Self, a: Scalar) -> Self {
        Self.init(x: v.x - a, y: v.y)
    }
    
    // u -= a
    static func -= (u: inout Self, a: Scalar) {
        u = u - a
    }
    
    /* ------- u * v, u *= v ------- */
    
    // ่ค‡ๆ•ธไน˜ๆณ•๏ผšu * v
    // u = a + bi
    // v = c + di
    // u * v = (ac-bd) + (ad+bc)i
    @inlinable    // ๆธ›ๅฐ‘้‹็ฎ—้ ป็น่ชฟ็”จ็š„้–‹้Šท
    static func * (u: Self, v: Self) -> Self {
        let (a,b,c,d) = (u.x, u.y, v.x, v.y)
        return Self.init(x: a * c - b * d, y: a * d + b * c)
    }
    
    // u *= v
    static func *= (u: inout Self, v: Self) {
        u = u * v
    }
    
    
    /* ------- u / v, u /= v ------- */
    
    /// ่ค‡ๆ•ธ้™คๆณ•๏ผša / v
    @inlinable    // ๆธ›ๅฐ‘้‹็ฎ—้ ป็น่ชฟ็”จ็š„้–‹้Šท
    static func / (a: Scalar, v: Self) -> Self {
        
        precondition(v.normSquared != 0,
             "โ›” Division by zero is not allowed."
        )
        
        return Self.init(x: a, y: 0) / v
    }
    
    // ่ค‡ๆ•ธ้™คๆณ•๏ผšu / v
    // u = a + bi
    // v = c + di
    // u / v = (a + bi)(c - di) / (cยฒ + dยฒ)
    @inlinable    // ๆธ›ๅฐ‘้‹็ฎ—้ ป็น่ชฟ็”จ็š„้–‹้Šท
    static func / (u: Self, v: Self) -> Self {
        
        precondition(v.normSquared != 0,
                     "โ›” Division by zero is not allowed."
        )
        
        return (u * v.conjugate) / v.normSquared
    }
    
    /// ่ค‡ๆ•ธ้™คๆณ•๏ผšu /= v
    /// u = u / v
    static func /= (u: inout Self, v: Self) {
        precondition(v != Self.zero, "โ›” Division by zero is not allowed.")
        u = u / v
    }
    
}

Last updated