0
$\begingroup$

I'm trying to work with quaternion math in Blender 2.82a and Python I need to normalize a quaternion number in Blender 2.82a using Python before I do calculations on it but I'm getting an error.

TypeError: unsupported operand type(s) for /: 'Quaternion' and 'float' for the line
quat1_norm = quat1 / math.sqrt(ww**2 + ii**2 + jj**2 + kk**2)

The code below is:

import math
import mathutils
import numpy as np

new_angle_rad = np.deg2rad(10)
ww = np.cos(new_angle_rad/2)
ii = np.sin(new_angle_rad/2)*0
jj = np.sin(new_angle_rad/2)*1
kk = np.sin(new_angle_rad/2)*0

quat1 = mathutils.Quaternion((ww, ii, jj, kk))

#Normalize quaternion to length 1 (unit quaternion). 
quat1_norm = quat1 / math.sqrt(ww**2 + ii**2 + jj**2 + kk**2) 

print(ww,ii,jj,kk)
print(quat1)

I'm trying to convert Octave code to work in Python and Blender https://octave.sourceforge.io/quaternion/function/@quaternion/unit.html

Here's the Octave math code I'm trying to convert.

Function File: qn = unit (q)

    Normalize quaternion to length 1 (unit quaternion).

              q = w + x*i + y*j + z*k
              unit (q) = q ./ sqrt (w.^2 + x.^2 + y.^2 + z.^2)

Package: quaternion

I did try:

quat1_norm=mathutils.Quaternion.normalize(mathutils.Quaternion((1, 2, 3, 4)))
print(quat1_norm)

it comes back with None.

When a similar command is done in Octave I get this

unit(quaternion(1,2,3,4))
ans = 0.1826 + 0.3651i + 0.5477j + 0.7303k
$\endgroup$
0
$\begingroup$

This can be done making and using the function below:

Original:

def normalize(v, tolerance=0.00001):
    mag2 = sum(n * n for n in v)
    if abs(mag2 - 1.0) > tolerance:
        mag = math.sqrt(mag2)
        v = tuple(n / mag for n in v)
    return np.array(v)

Updated Version using batFINGER suggestion: April 26 2020

def normalize(v, tolerance=0.00001):
    mag2 = sum(n * n for n in v)
    if mag2 > tolerance:
        mag = math.sqrt(mag2)
        v = tuple(n / mag for n in v)
    return np.array(v)

Or using the built in Function

import mathutils
quat1 = mathutils.Quaternion((1, 2, 3, 4))
quat1_norm = quat1.normalized()
print(quat1_norm)
| improve this answer | |
$\endgroup$
  • $\begingroup$ Would edit to if mag2 > tolerance: only zero length vectors are an issue. $\endgroup$ – batFINGER Apr 26 at 10:07
  • $\begingroup$ Trying methods above on Quaternion((0, 0, 0, 0)) deliver a zero division error, (0, 0, 0, 0) and (0, 1, 0, 0). Not sure why the zero quat result normalizes to x=1 whereas default (Quaternion()) is w=1. If using numpy no need to loop normalized_v = v / np.sqrt(np.sum(v ** 2)) and check for all zeros. $\endgroup$ – batFINGER Apr 26 at 14:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.