Sunday, September 3, 2023

Python: Basic Functions with Quaternions

 Python:   Basic Functions with Quaternions   



Calculating with Quaternions



Quaternions are four-dimensional hypercomplex numbers that is written as the form:


r = a * i + b * j + c * k + d


We can also write quaternions as a four dimensional vector [a, b, c, d].


In computer graphics, quaternions are used to draw, display, move, and rotate 3D objects.  The constant term, d, is a mass-point, while the other three terms describe the location of vector point.



Some Mathematical Properties of Quaternions



The conjugate of a quaternion is similar to what a conjugate of a regular complex number would look like:


r* =  - a * i - b * j - c * k + d  


Similarly, the norm of a quaternion works in a familiar fashion:


| r | = abs(r) = √(a^2 + b^2 + c^2 + d^2)


We can multiply a quaternion by any scalar, s, as follows:


s * r = s*  a * i + s * b * j + a* r3 * k + a* r4  


To find the unit vector (unit quaternion), multiply the quaternion by the scalar 1/|r|.


Adding quaternions is communicative and associative.  However, multiplying quaternions is associative, but not communicative.  In short, when it comes to multiplying quaternions, order matters.  


For the complex coefficients:


i^2 = j^2 = k^2 = -1


i * j =  k,    j * i = -k 


j * k = i,   k * j = -i


k * i = j,  i * k = -j




List of Functions Included in QUAT.py



Quaternions are entered as vectors:


r = a * i + b * j + c * k + d -> [a, b, c, d]


qplus(r, q):   addition, r + q

qminus(r, q):  subtraction, r - q

qtimes(r,q):  multiplication,  r * q

qdivide(r,q):   division (multiply by the reciprocal):  r / q  = r * q^-1

qnorm(r):  norm or magnitude

qconj(r):  conjugate

qscale(r, a):   multiply quaternion r by a scalar a

qinv(r):  inverse or reciprocal of a quaternion,  1/r = r* / |r|

qsquare(r):  r^2


qhelp():  brings up the list of functions in QUAT plus.  


To use these functions on other Python scripts:


from QUAT import *


Important QUAT should also import the math module.  




Python:  Quaternions


This should work on all Python platforms since only the math module is used.  This was programmed on a TI-84 Plus CE Python calculator.




Python Code:  QUAT.py


# arithmetic with quaternions

# ews 2023-06-20


from math import *


# help

def qhelp():

  s="Quaternions - qhelp()"

  # add \n for new lines

  s+="\nEnter r=ai+bj+ck+d as [a,b,c,d]."

  s+="\nqplus(r,q) +  qminus(r,q) -"

  s+="\nqtimes(r,q) *  qdivide(r,q) /"

  s+="\nqnorm(r) magnitude \nqconj(r) conjugate \nqscalar(r,a) scalar mult. by a"

  s+="\nqinv(r) r**-1 qsquare(r) r**2"

  # need print to look nice

  return print(s)


# add

def qplus(r,q):

  return [r[i]+q[i] for i in range(4)]


# subtract

def qminus(r,q):

  q=[-i for i in q]

  return qplus(r,q)


# conjugate

def qconj(r):

  return [-r[i] for i in range(3)]+[r[3]]


# norm

def qnorm(r):

  s=sum([i**2 for i in r])

  return sqrt(s)


# inverse/reciprocal

def qinv(r):

  r=qconj(r)

  s=qnorm(r)

  s*=s

  return [i/s for i in r]


# scalar multiplication

def qscalar(r,a):

  return [a*i for i in r]


# multiplication

def qtimes(r,q):

  s=[0,0,0,0]

  s[0]=r[0]*q[3]+r[1]*q[2]-r[2]*q[1]+r[3]*q[0]

  s[1]=-r[0]*q[2]+r[1]*q[3]+r[2]*q[0]+r[3]*q[1]

  s[2]=r[0]*q[1]-r[1]*q[0]+r[2]*q[3]+r[3]*q[2]

  s[3]=r[3]*q[3]-r[0]*q[0]-r[1]*q[1]-r[2]*q[2]

  return s


# division

def qdivide(r,q):

  q=qinv(q)

  return qtimes(r,q)


# qsquare

def qsquare(r):

  return qtimes(r,r)


qhelp()



Download the script here:  https://drive.google.com/file/d/1iNDxw82Gm1nOVJ7jDHdnIIxA4tcaV0p3/view?usp=sharing



Source


Ron Goldman,

Understanding quaternions,

Graphical Models,

Volume 73, Issue 2,

2011,

Pages 21-49,

ISSN 1524-0703,

https://doi.org/10.1016/j.gmod.2010.10.004.

(https://www.sciencedirect.com/science/article/pii/S1524070310000172)


Science Direct requires a paid subscription or access through a university.


Alternate source:  https://www.researchgate.net/publication/220632454_Understanding_quaternions




All original content copyright, © 2011-2023.  Edward Shore.   Unauthorized use and/or unauthorized distribution for commercial purposes without express and written permission from the author is strictly prohibited.  This blog entry may be distributed for noncommercial purposes, provided that full credit is given to the author.