module Kernel

Public Instance Methods

Quaternion(*args) click to toggle source

Returns a quaternion.

This function accepts various arguments except polar form. Strings are parsed to Numeric.

@overload Quaternion(w, x, y, z)

@param w [Numeric]
@param x [Numeric]
@param y [Numeric]
@param z [Numeric]
@return [Quaternion] w+xi+yj+zk

@overload Quaternion(a, b)

@param a [Numeric]
@param b [Numeric]
@return [Quaternion] a+bj

@overload Quaternion(s, v)

@param s [Numeric]    scalar part
@param v [Enumerable] vector part
@return [Quaternion] $s+\\vec!{v}$

@overload Quaternion(str)

@param str [String]
@return [Quaternion] +str.to_q+
@raise [ArgumentError] if its format is inexact.

@example

Quaternion(1)            #=> (1+0i+0j+0k)
Quaternion(1, 2)         #=> (1+0i+2j+0k) # not (1+2i+0j+0k)
Quaternion(1, 2, 3, 4)   #=> (1+2i+3j+4k)
Quaternion(1, [2, 3, 4]) #=> (1+2i+3j+4k)
Quaternion('1+2i+3j+4k') #=> (1+2i+3j+4k)
# File lib/quaternion_c2/conversion.rb, line 242
def Quaternion(*args)
        argc = args.size

        unless (1..4).cover?(argc)
                raise ArgumentError,
                      "wrong number of arguments (given #{argc}, expected 1..4)"
        end

        if args.any?(&:nil?)
                raise TypeError, "can't convert nil into Quaternion"
        end

        # convert String into Numeric (strictly)
        args.collect! do |arg|
                case arg
                when String
                        Quaternion.send(:parse, arg, true)
                else
                        arg
                end
        end

        case argc
        when 1
                arg = args[0]
                if arg.kind_of?(Numeric)
                        # a quaternion (or an octonion, etc.)
                        return arg.complex? ? arg.to_q : arg
                else
                        raise TypeError,
                              "can't convert #{arg.class} into Quaternion"
                end
        when 2
                if args[1].kind_of?(Enumerable)
                        # scalar and 3-D vector -> expand
                        if args[1].size != 3
                                raise TypeError, "not a 3-D vector"
                        end
                        args.flatten!(1)
                elsif args.all? { |x| x.kind_of?(Numeric) && x.complex? }
                        # a pair of complex numbers
                        return Quaternion.send(:new, *args)
                else
                        return args[0] + args[1] * Quaternion::J
                end
        end

        w, x, y, z = args
        z ||= 0
        if args.all? { |x| x.kind_of?(Numeric) && x.real? }
                # 3 or 4 real numbers
                a = Complex.rect(w, x)
                b = Complex.rect(y, z)
                Quaternion.send(:new, a, b)
        else
                a = Complex(w, x)
                b = Complex(y, z)
                if [a, b].all? { |x| x.kind_of?(Numeric) && x.complex? }
                        Quaternion.send(:new, a, b)
                else
                        a + b * Quaternion::J
                end
        end
end