reb Class QH

Object reb:QH

class
Object:QH

Functions for Quaternion and Hypercomplex operations.

For quaternions, multiplication is not commutative and division is always defined.

For hypercomplex, multiplication is commutative and division is not always defined. The inverses which are not defined lieon two orthogonal 4D hyperplanes.

The hypercomplex code is based upon the complex number methods of Clyde Davenport using his complex/complex model.

H1 = [a1,a2]

where a1 and a2 are both complex numbers. This is the method used in Fractint. a1 and a2 are converted to two new complex numbers:

fa1 = a1 - conj(flip(a2))
fa2 = a1 + conj(flip(a2))

These new complex numbers (and correspondingly fb1 and fb2) can be used for ordinary complex math, including multiplication, division, trancendental functions, powers, etc. For example, sqrt:

fa1 = sqrt(fa1)
fa2 = sqrt(fa2)

A second conversion is done at the end of the operation(s):

c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))

H2 = [c1, c2]

Ultra Fractal Source
Class QH {
import "common.ulb"
; Functions for Quaternion and Hypercomplex operations. <br>
; <p>
; For quaternions, multiplication is not commutative and division is always
; defined.
; <p>
; For hypercomplex, multiplication is commutative and division is not always
; defined. The inverses which are not defined lieon two orthogonal
; 4D hyperplanes.
; <p>
; The hypercomplex code is based upon the complex number methods of Clyde
; Davenport using his complex/complex model.
; <p>
;   <a href="http://home.comcast.net/~cmdaven/bhyprcpx.htm">Davenport's Website</a><br>
; <p>
;   H1 = [a1,a2] <br>
; <p>
; where a1 and a2 are both complex numbers.  This is the method used in Fractint.
; a1 and a2 are converted to two new complex numbers:
; <p>
;   fa1 = a1 - conj(flip(a2)) <br>
;   fa2 = a1 + conj(flip(a2)) <br>
; <p>
; These new complex numbers (and correspondingly fb1 and fb2) can be used for
; ordinary complex math, including multiplication, division, trancendental
; functions, powers, etc. For example, sqrt:
; <p>
;   fa1 = sqrt(fa1) <br>
;   fa2 = sqrt(fa2) <br>
; <p>
; A second conversion is done at the end of the operation(s):
;  <p>
;   c1 = 0.5*(fa1+fa2)<br>
;   c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))<br>
;  <p>
;   H2 = [c1, c2] <br>
; public:

; Quaternian multiplication
static func Qmul(Vector a, Vector b, Vector c)
; Q1*Q2 = [r1*r2 - V1.V2, r2*V1 + r1*V2 + V1xV2]
; calc V . V
float dot = a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w
; calc V x V
c.m_y = a.m_z*b.m_w - b.m_z*a.m_w
c.m_z = -(a.m_y*b.m_w - b.m_y*a.m_w)
c.m_w = a.m_y*b.m_z - b.m_y*a.m_z

c.m_x = a.m_x*b.m_x-dot
c.m_y = c.m_y + a.m_x*b.m_y + b.m_x*a.m_y
c.m_z = c.m_z + a.m_x*b.m_z + b.m_x*a.m_z
c.m_w = c.m_w + a.m_x*b.m_w + b.m_x*a.m_w
endfunc

; Quaternian division calculated as Q2*(1/Q1)
static func Qdiv(Vector a, Vector b, Vector c)
; 1/Q = [r, -V]/(r*r + V.V)
; then calculate Q2*(1/Q1) as for QMul
float denom = 1/(b.m_x*b.m_x + b.m_y*b.m_y + b.m_z*b.m_z + b.m_w*b.m_w)
; calc V . V
float dot = -(a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w)
; calc V x V
c.m_y = -a.m_z*b.m_w + b.m_z*a.m_w
c.m_z = a.m_y*b.m_w - b.m_y*a.m_w
c.m_w = -a.m_y*b.m_z + b.m_y*a.m_z

c.m_x = (a.m_x*b.m_x-dot)*denom
c.m_y = (c.m_y - a.m_x*b.m_y + b.m_x*a.m_y)*denom
c.m_z = (c.m_z - a.m_x*b.m_z + b.m_x*a.m_z)*denom
c.m_w = (c.m_w - a.m_x*b.m_w + b.m_x*a.m_w)*denom
endfunc

; Quaternian division calculated as 1/Q1)*Q2
static func Qdiv2(Vector a, Vector b, Vector c)
; 1/Q = [r, -V]/(r*r + V.V)
; then calculate (1/Q1)*Q2 as for QMul
float denom = 1/(b.m_x*b.m_x + b.m_y*b.m_y + b.m_z*b.m_z + b.m_w*b.m_w)
; calc V . V
float dot = -(a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w)
; calc V x V
c.m_y = -b.m_z*a.m_w + a.m_z*b.m_w
c.m_z = b.m_y*a.m_w - a.m_y*b.m_w
c.m_w = -b.m_y*a.m_z + a.m_y*b.m_z

c.m_x = (a.m_x*b.m_x-dot)*denom
c.m_y = (c.m_y + b.m_x*a.m_y - a.m_x*b.m_y)*denom
c.m_z = (c.m_z + b.m_x*a.m_z - a.m_x*b.m_z)*denom
c.m_w = (c.m_w + b.m_x*a.m_w - a.m_x*b.m_w)*denom
endfunc

; Quaternian square
static func Qsqr(Vector a, Vector b)
; Q*Q = [r*r-V.V, 2*r*V]
; calc V . V
float dot = a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w
if dot == 0
dot = 1e-100
endif
b.m_x = a.m_x*a.m_x-dot
b.m_y = 2*a.m_x*a.m_y
b.m_z = 2*a.m_x*a.m_z
b.m_w = 2*a.m_x*a.m_w
endfunc

; Quaternian square root
static func Qsqrt(Vector a, Vector b)
; derived from the inverse of the equations for Qsqr
float sdot = a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w
if sdot == 0
sdot = 1e-100
endif
b.m_x = sqrt((a.m_x + sqrt(a.m_x^2 + sdot))/2)
float factor = 1/(2*b.m_x)
b.m_y = a.m_y*factor
b.m_z = a.m_z*factor
b.m_w = a.m_w*factor
endfunc

; Quaternian reciprocal or inverse
static func Qrecip(Vector a, Vector b)
; 1/Q = [r, -V]/(r*r + V.V)
float denom = 1/(a.m_x*a.m_x + a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
b.m_x = a.m_x*denom
b.m_y = -a.m_y*denom
b.m_z = -a.m_z*denom
b.m_w = -a.m_w*denom
endfunc

; Quaternian natural log
static func Qlog(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = log(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian exponential
static func Qexp(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = exp(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian power calculated as exp(ln(Q1)*Q2)
static func Qpower(Vector a, Vector b, Vector c)
;    Q1^Q2 = exp(ln(Q1)*Q2)
;   Find the log of Q1
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = log(z)
float at = imag(z)/norm
float x1 = real(z)
float y1 = at*a.m_y
float z1 = at*a.m_z
float w1 = at*a.m_w
;   Multiply log by Q2
float dot = y1*b.m_y + z1*b.m_z + w1*b.m_w
; calc V x V
float y2 = z1*b.m_w - b.m_z*w1
float z2 = -(y1*b.m_w - b.m_y*w1)
float w2 = y1*b.m_z - b.m_y*z1

float x2 = x1*b.m_x-dot
y2 = y2 + x1*b.m_y + b.m_x*y1
z2 = z2 + x1*b.m_z + b.m_x*z1
w2 = w2 + x1*b.m_w + b.m_x*w1
;   Take the exponential
norm = sqrt(y2*y2 + z2*z2 + w2*w2)
if norm == 0
norm = 1e-100
endif
z = x2 + flip(norm)
z = exp(z)
at = imag(z)/norm
c.m_x = real(z)
c.m_y = at*y2
c.m_z = at*z2
c.m_w = at*w2
endfunc

; Quaternian power calculated as exp(Q2*ln(Q1))
static func Qpower2(Vector a, Vector b, Vector c)
;    Q1^Q2 = exp(Q2*ln(Q1))
;   Find the log of Q1
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = log(z)
float at = imag(z)/norm
float x1 = real(z)
float y1 = at*a.m_y
float z1 = at*a.m_z
float w1 = at*a.m_w
;   Multiply log by Q2
float dot = y1*b.m_y + z1*b.m_z + w1*b.m_w
; calc V x V
float y2 = -z1*b.m_w + b.m_z*w1
float z2 = (y1*b.m_w - b.m_y*w1)
float w2 = -y1*b.m_z + b.m_y*z1

float x2 = x1*b.m_x-dot
y2 = y2 + x1*b.m_y + b.m_x*y1
z2 = z2 + x1*b.m_z + b.m_x*z1
w2 = w2 + x1*b.m_w + b.m_x*w1

;   Take the exponential
norm = sqrt(y2*y2 + z2*z2 + w2*w2)
if norm == 0
norm = 1e-100
endif
z = x2 + flip(norm)
z = exp(z)
at = imag(z)/norm
c.m_x = real(z)
c.m_y = at*y2
c.m_z = at*z2
c.m_w = at*w2
endfunc

; Quaternian sine
static func Qsin(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = sin(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian arcsine
static func Qasin(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = asin(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian cosine
static func Qcos(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = cos(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian arccosine
static func Qacos(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = acos(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian tangent
static func Qtan(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = tan(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic tangent
static func Qtanh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = tanh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic arctangent
static func Qatanh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = atanh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian arctangent
static func Qatan(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = atan(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian conjugate
static func Qconj(Vector a, Vector b)
; conj(Q) = [r,-V]
b.m_x = a.m_x
b.m_y = -a.m_y
b.m_z = -a.m_z
b.m_w = -a.m_w
endfunc

; Quaternian hyperbolic sine
static func Qsinh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = sinh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic cosine
static func Qcosh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = cosh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic arcsine
static func Qasinh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = asinh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic arccosine
static func Qacosh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = acosh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian cotangent
static func Qcotan(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = cotan(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic cotangent
static func Qcotanh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = cotanh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Hypercomplex multiplication
static func Hmul(Vector a, Vector b, Vector c)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex b1 = b.m_x + flip(b.m_y)
complex b2 = b.m_z + flip(b.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
complex fb1 = b1 - conj(flip(b2))
complex fb2 = b1 + conj(flip(b2))
fa1 = fa1*fb1
fa2 = fa2*fb2
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
c.m_x = real(c1)
c.m_y = imag(c1)
c.m_z = real(c2)
c.m_w = imag(c2)
endfunc

; Hypercomplex division
static func Hdiv(Vector a, Vector b, Vector c)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex b1 = b.m_x + flip(b.m_y)
complex b2 = b.m_z + flip(b.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
complex fb1 = b1 - conj(flip(b2))
complex fb2 = b1 + conj(flip(b2))
fa1 = fa1/fb1
fa2 = fa2/fb2
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
c.m_x = real(c1)
c.m_y = imag(c1)
c.m_z = real(c2)
c.m_w = imag(c2)
endfunc

; Hypercomplex square
static func Hsqr(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = fa1*fa1
fa2 = fa2*fa2
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex square root
static func Hsqrt(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = sqrt(fa1)
fa2 = sqrt(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex reciprocal or inverse
static func Hrecip(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = 1/fa1
fa2 = 1/fa2
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex natural log
static func Hlog(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = log(fa1)
fa2 = log(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex exponential
static func Hexp(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = exp(fa1)
fa2 = exp(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex power
static func Hpower(Vector a, Vector b, Vector c)
;    Q1^Q2 = exp(ln(Q1)*Q2)
;
; Find the log of Q1
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex b1 = b.m_x + flip(b.m_y)
complex b2 = b.m_z + flip(b.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
complex fb1 = b1 - conj(flip(b2))
complex fb2 = b1 + conj(flip(b2))
fa1 = log(fa1)
fa2 = log(fa2)
;
; Multiply log by Q2
fa1 =  fa1*fb1
fa2 =  fa2*fb2
;
; Take exponential
fa1 = exp(fa1)
fa2 = exp(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
c.m_x = real(c1)
c.m_y = imag(c1)
c.m_z = real(c2)
c.m_w = imag(c2)
endfunc

static func Hsin(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = sin(fa1)
fa2 = sin(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex cosine
static func Hcos(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = cos(fa1)
fa2 = cos(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic sine
static func Hsinh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = sinh(fa1)
fa2 = sinh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic cosine
static func Hcosh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = cosh(fa1)
fa2 = cosh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex conjugate
static func Hconj(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = conj(fa1)
fa2 = conj(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex tangent
static func Htan(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = tan(fa1)
fa2 = tan(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex arcsine
static func Hasin(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = asin(fa1)
fa2 = asin(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex arccosine
static func Hacos(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = acos(fa1)
fa2 = acos(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex arctangent
static func Hatan(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = atan(fa1)
fa2 = atan(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic tangent
static func Htanh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = tanh(fa1)
fa2 = tanh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic arcsine
static func Hasinh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = asinh(fa1)
fa2 = asinh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic arccosine
static func Hacosh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = acosh(fa1)
fa2 = acosh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic arctangent
static func Hatanh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = atanh(fa1)
fa2 = atanh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex cotangent
static func Hcotan(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = cotan(fa1)
fa2 = cotan(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic cotangent
static func Hcotanh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = cotanh(fa1)
fa2 = cotanh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

default:
title = "Quat Hyper Methods"
int param v_quathyper
caption = "Version (Quat Hyper Methods)"
default = 100
hint = "This version parameter is used to detect when a change has been made to the formula that is incompatible with the previous version. When that happens, this field will reflect the old version number to alert you to the fact that an alternate rendering is being used."
visible = @v_quathyper < 100
endparam
}

Constructor Summary
QH()

Method Summary
static void Hacos(Vector a, Vector b)
Hypercomplex arccosine
static void Hacosh(Vector a, Vector b)
Hypercomplex hyperbolic arccosine
static void Hasin(Vector a, Vector b)
Hypercomplex arcsine
static void Hasinh(Vector a, Vector b)
Hypercomplex hyperbolic arcsine
static void Hatan(Vector a, Vector b)
Hypercomplex arctangent
static void Hatanh(Vector a, Vector b)
Hypercomplex hyperbolic arctangent
static void Hconj(Vector a, Vector b)
Hypercomplex conjugate
static void Hcos(Vector a, Vector b)
Hypercomplex cosine
static void Hcosh(Vector a, Vector b)
Hypercomplex hyperbolic cosine
static void Hcotan(Vector a, Vector b)
Hypercomplex cotangent
static void Hcotanh(Vector a, Vector b)
Hypercomplex hyperbolic cotangent
static void Hdiv(Vector a, Vector b, Vector c)
Hypercomplex division
static void Hexp(Vector a, Vector b)
Hypercomplex exponential
static void Hlog(Vector a, Vector b)
Hypercomplex natural log
static void Hmul(Vector a, Vector b, Vector c)
Hypercomplex multiplication
static void Hpower(Vector a, Vector b, Vector c)
Hypercomplex power
static void Hrecip(Vector a, Vector b)
Hypercomplex reciprocal or inverse
static void Hsin(Vector a, Vector b)

static void Hsinh(Vector a, Vector b)
Hypercomplex hyperbolic sine
static void Hsqr(Vector a, Vector b)
Hypercomplex square
static void Hsqrt(Vector a, Vector b)
Hypercomplex square root
static void Htan(Vector a, Vector b)
Hypercomplex tangent
static void Htanh(Vector a, Vector b)
Hypercomplex hyperbolic tangent
static void Qacos(Vector a, Vector b)
Quaternian arccosine
static void Qacosh(Vector a, Vector b)
Quaternian hyperbolic arccosine
static void Qasin(Vector a, Vector b)
Quaternian arcsine
static void Qasinh(Vector a, Vector b)
Quaternian hyperbolic arcsine
static void Qatan(Vector a, Vector b)
Quaternian arctangent
static void Qatanh(Vector a, Vector b)
Quaternian hyperbolic arctangent
static void Qconj(Vector a, Vector b)
Quaternian conjugate
static void Qcos(Vector a, Vector b)
Quaternian cosine
static void Qcosh(Vector a, Vector b)
Quaternian hyperbolic cosine
static void Qcotan(Vector a, Vector b)
Quaternian cotangent
static void Qcotanh(Vector a, Vector b)
Quaternian hyperbolic cotangent
static void Qdiv(Vector a, Vector b, Vector c)
Quaternian division calculated as Q2*(1/Q1)
static void Qdiv2(Vector a, Vector b, Vector c)
Quaternian division calculated as 1/Q1)*Q2
static void Qexp(Vector a, Vector b)
Quaternian exponential
static void Qlog(Vector a, Vector b)
Quaternian natural log
static void Qmul(Vector a, Vector b, Vector c)
Quaternian multiplication
static void Qpower(Vector a, Vector b, Vector c)
Quaternian power calculated as exp(ln(Q1)*Q2)
static void Qpower2(Vector a, Vector b, Vector c)
Quaternian power calculated as exp(Q2*ln(Q1))
static void Qrecip(Vector a, Vector b)
Quaternian reciprocal or inverse
static void Qsin(Vector a, Vector b)
Quaternian sine
static void Qsinh(Vector a, Vector b)
Quaternian hyperbolic sine
static void Qsqr(Vector a, Vector b)
Quaternian square
static void Qsqrt(Vector a, Vector b)
Quaternian square root
static void Qtan(Vector a, Vector b)
Quaternian tangent
static void Qtanh(Vector a, Vector b)
Quaternian hyperbolic tangent

Methods inherited from class Object

Constructor Detail

public QH()
Method Detail

Qmul

public static void Qmul(Vector a,
Vector b,
Vector c)
Quaternian multiplication

Qdiv

public static void Qdiv(Vector a,
Vector b,
Vector c)
Quaternian division calculated as Q2*(1/Q1)

Qdiv2

public static void Qdiv2(Vector a,
Vector b,
Vector c)
Quaternian division calculated as 1/Q1)*Q2

Qsqr

public static void Qsqr(Vector a,
Vector b)
Quaternian square

Qsqrt

public static void Qsqrt(Vector a,
Vector b)
Quaternian square root

Qrecip

public static void Qrecip(Vector a,
Vector b)
Quaternian reciprocal or inverse

Qlog

public static void Qlog(Vector a,
Vector b)
Quaternian natural log

Qexp

public static void Qexp(Vector a,
Vector b)
Quaternian exponential

Qpower

public static void Qpower(Vector a,
Vector b,
Vector c)
Quaternian power calculated as exp(ln(Q1)*Q2)

Qpower2

public static void Qpower2(Vector a,
Vector b,
Vector c)
Quaternian power calculated as exp(Q2*ln(Q1))

Qsin

public static void Qsin(Vector a,
Vector b)
Quaternian sine

Qasin

public static void Qasin(Vector a,
Vector b)
Quaternian arcsine

Qcos

public static void Qcos(Vector a,
Vector b)
Quaternian cosine

Qacos

public static void Qacos(Vector a,
Vector b)
Quaternian arccosine

Qtan

public static void Qtan(Vector a,
Vector b)
Quaternian tangent

Qtanh

public static void Qtanh(Vector a,
Vector b)
Quaternian hyperbolic tangent

Qatanh

public static void Qatanh(Vector a,
Vector b)
Quaternian hyperbolic arctangent

Qatan

public static void Qatan(Vector a,
Vector b)
Quaternian arctangent

Qconj

public static void Qconj(Vector a,
Vector b)
Quaternian conjugate

Qsinh

public static void Qsinh(Vector a,
Vector b)
Quaternian hyperbolic sine

Qcosh

public static void Qcosh(Vector a,
Vector b)
Quaternian hyperbolic cosine

Qasinh

public static void Qasinh(Vector a,
Vector b)
Quaternian hyperbolic arcsine

Qacosh

public static void Qacosh(Vector a,
Vector b)
Quaternian hyperbolic arccosine

Qcotan

public static void Qcotan(Vector a,
Vector b)
Quaternian cotangent

Qcotanh

public static void Qcotanh(Vector a,
Vector b)
Quaternian hyperbolic cotangent

Hmul

public static void Hmul(Vector a,
Vector b,
Vector c)
Hypercomplex multiplication

Hdiv

public static void Hdiv(Vector a,
Vector b,
Vector c)
Hypercomplex division

Hsqr

public static void Hsqr(Vector a,
Vector b)
Hypercomplex square

Hsqrt

public static void Hsqrt(Vector a,
Vector b)
Hypercomplex square root

Hrecip

public static void Hrecip(Vector a,
Vector b)
Hypercomplex reciprocal or inverse

Hlog

public static void Hlog(Vector a,
Vector b)
Hypercomplex natural log

Hexp

public static void Hexp(Vector a,
Vector b)
Hypercomplex exponential

Hpower

public static void Hpower(Vector a,
Vector b,
Vector c)
Hypercomplex power

Hsin

public static void Hsin(Vector a,
Vector b)

Hcos

public static void Hcos(Vector a,
Vector b)
Hypercomplex cosine

Hsinh

public static void Hsinh(Vector a,
Vector b)
Hypercomplex hyperbolic sine

Hcosh

public static void Hcosh(Vector a,
Vector b)
Hypercomplex hyperbolic cosine

Hconj

public static void Hconj(Vector a,
Vector b)
Hypercomplex conjugate

Htan

public static void Htan(Vector a,
Vector b)
Hypercomplex tangent

Hasin

public static void Hasin(Vector a,
Vector b)
Hypercomplex arcsine

Hacos

public static void Hacos(Vector a,
Vector b)
Hypercomplex arccosine

Hatan

public static void Hatan(Vector a,
Vector b)
Hypercomplex arctangent

Htanh

public static void Htanh(Vector a,
Vector b)
Hypercomplex hyperbolic tangent

Hasinh

public static void Hasinh(Vector a,
Vector b)
Hypercomplex hyperbolic arcsine

Hacosh

public static void Hacosh(Vector a,
Vector b)
Hypercomplex hyperbolic arccosine

Hatanh

public static void Hatanh(Vector a,
Vector b)
Hypercomplex hyperbolic arctangent

Hcotan

public static void Hcotan(Vector a,
Vector b)
Hypercomplex cotangent

Hcotanh

public static void Hcotanh(Vector a,
Vector b)
Hypercomplex hyperbolic cotangent