# Examples from pyvista.Transform.decompose
# =========================================

# Create a transform by composing scaling, rotation, and translation
# matrices.
import numpy as np
import pyvista as pv
transform = pv.Transform()
_ = transform.scale(1, 2, 3)
_ = transform.rotate_z(90)
_ = transform.translate(4, 5, 6)
transform

# Decompose the matrix.
T, R, N, S, K = transform.decompose()

# Since the input has no shear this component is the identity matrix.
# Similarly, there are no reflections so its value is `1`. All other components
# are recovered perfectly and match the input.
K  # shear

S  # scale

N  # reflection

R  # rotation

T  # translation

# Compose a shear component using pre-multiplication so that shearing is
# the first transformation.
shear = np.eye(4)
shear[0, 1] = 0.1  # xy shear
_ = transform.compose(shear, multiply_mode='pre')

# Repeat the decomposition and show its components. Note how the decomposed shear
# does not perfectly match the input shear matrix values. The values of the
# scaling and rotation components are also affected and do not exactly match the
# input. This is expected, because the shear can be partially factored as a
# combination of rotation and scaling.
T, R, N, S, K = transform.decompose()

K  # shear

S  # scale

N  # reflection

R  # rotation

T  # translation

# Although the values may not match the input exactly, the decomposition is
# nevertheless valid and can be used to re-compose the original transformation.
T, R, N, S, K = transform.decompose(homogeneous=True)
T @ R @ N @ S @ K

# Alternatively, re-compose the transformation as a new
# `Transform` with pre-multiplication.
recomposed = pv.Transform([T, R, N, S, K], multiply_mode='pre')
np.allclose(recomposed.matrix, transform.matrix)

# Compose a reflection and decompose the transform again.
_ = transform.flip_x()
T, R, N, S, K = transform.decompose()

# The reflection component is now `-1`.
N  # reflection

# The decomposition may be simplified to a `TRSK` decomposition by combining
# the reflection component with either the rotation or the scaling term.
# Multiplying the reflection with the rotation will make it a left-handed rotation
# with negative determinant:
R = R * N
np.linalg.det(R) < 0

# Alternatively, keep the rotation right-handed but make the scaling factors negative:
S = S * N
S  # scale

# ----------------------------------------------------------------------
# Generated by sphinx-examples-as-code https://github.com/pyvista/sphinx-examples-as-code

