Skip to content

Commit e333b56

Browse files
rhamel3drycwo
authored andcommitted
xform: Add new utility
1 parent d7f5219 commit e333b56

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

metafold/utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from numpy.typing import ArrayLike
2+
from scipy.spatial.transform import Rotation as R
3+
from typing import Optional
4+
import numpy as np
5+
6+
7+
def xform(
8+
translation: Optional[ArrayLike] = None,
9+
rotation: Optional[ArrayLike] = None,
10+
scale: Optional[ArrayLike] = None,
11+
) -> np.array:
12+
"""Compose transformation matrix.
13+
14+
Args:
15+
translation: Translation in the x, y, and z directions.
16+
rotation: Euler angles in degrees. Rotation is applied in the order Rz, Ry, Rx.
17+
scale: Scale factor applied in the x, y, z directions before rotation.
18+
19+
Returns:
20+
4 x 4 affine transformation matrix.
21+
"""
22+
translation = translation or np.array([0.0, 0.0, 0.0])
23+
rotation = rotation or np.array([0.0, 0.0, 0.0])
24+
scale = scale or np.array([1.0, 1.0, 1.0])
25+
26+
r = R.from_euler("xyz", rotation, degrees=True).as_matrix()
27+
m = np.eye(4)
28+
m[:3, :3] = np.diag(scale) @ r
29+
m[3, :3] = translation
30+
return m

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
attrs~=23.2
22
auth0-python~=4.7
3+
numpy ~= 1.23
34
requests~=2.31
5+
scipy ~= 1.11

tests/test_utils.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from metafold.utils import xform
2+
from numpy.testing import assert_allclose
3+
4+
5+
def test_xform():
6+
m = xform([1.0, 2.0, 3.0]) # T
7+
assert_allclose(m, [
8+
[1.0, 0.0, 0.0, 0.0],
9+
[0.0, 1.0, 0.0, 0.0],
10+
[0.0, 0.0, 1.0, 0.0],
11+
[1.0, 2.0, 3.0, 1.0],
12+
], atol=1.0e-7)
13+
14+
m = xform(
15+
[1.0, 2.0, 3.0], # T
16+
[180.0, -90.0, 0.0]) # R
17+
assert_allclose(m, [
18+
[0.0, 0.0, 1.0, 0.0],
19+
[0.0, -1.0, 0.0, 0.0],
20+
[1.0, 0.0, 0.0, 0.0],
21+
[1.0, 2.0, 3.0, 1.0],
22+
], atol=1.0e-7)
23+
24+
m = xform(
25+
[1.0, 2.0, 3.0], # T
26+
scale=[2.0, 1.0, 1.0]) # S
27+
assert_allclose(m, [
28+
[2.0, 0.0, 0.0, 0.0],
29+
[0.0, 1.0, 0.0, 0.0],
30+
[0.0, 0.0, 1.0, 0.0],
31+
[1.0, 2.0, 3.0, 1.0],
32+
], atol=1.0e-7)
33+
34+
m = xform(
35+
rotation=[180.0, -90.0, 0.0], # R
36+
scale=[2.0, 1.0, 1.0]) # S
37+
assert_allclose(m, [
38+
[0.0, 0.0, 2.0, 0.0],
39+
[0.0, -1.0, 0.0, 0.0],
40+
[1.0, 0.0, 0.0, 0.0],
41+
[0.0, 0.0, 0.0, 1.0],
42+
], atol=1.0e-7)
43+
44+
m = xform(
45+
[1.0, 2.0, 3.0], # T
46+
[180.0, -90.0, 0.0], # R
47+
[2.0, 1.0, 1.0]) # S
48+
assert_allclose(m, [
49+
[0.0, 0.0, 2.0, 0.0],
50+
[0.0, -1.0, 0.0, 0.0],
51+
[1.0, 0.0, 0.0, 0.0],
52+
[1.0, 2.0, 3.0, 1.0],
53+
], atol=1.0e-7)

0 commit comments

Comments
 (0)