# Normalize / Create a unit quaternion number / calculation using Python and Blender

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

## 1 Answer

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)
• Would edit to if mag2 > tolerance: only zero length vectors are an issue. Apr 26, 2020 at 10:07
• 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. Apr 26, 2020 at 14:00