Skip to content

Commit

Permalink
Add a mirror transformation to functions
Browse files Browse the repository at this point in the history
  • Loading branch information
FranzBangar committed Jan 22, 2024
1 parent 7c594c4 commit d7b13a6
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/classy_blocks/util/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,41 @@ def arc_mid(axis: VectorType, center: PointType, radius: float, point_1: PointTy
sec_ort = np.cross(sec, axis)

return center + unit_vector(sec_ort) * radius


def mirror(point: PointType, normal: VectorType, origin: PointType):
"""Mirror a point around a plane, given by a normal and origin"""
# brainlessly copied from https://gamemath.com/book/matrixtransforms.html
point = np.asarray(point)
normal = unit_vector(normal)
origin = np.asarray(origin)

n_x = normal[0]
n_y = normal[1]
n_z = normal[2]

matrix = np.array(
[
[
1 - 2 * n_x**2,
-2 * n_x * n_y,
-2 * n_x * n_z,
],
[
-2 * n_x * n_y,
1 - 2 * n_y**2,
-2 * n_y * n_z,
],
[
-2 * n_x * n_z,
-2 * n_y * n_z,
1 - 2 * n_z**2,
],
]
)

point -= origin
rotated = point.dot(matrix)
rotated += origin

return rotated
48 changes: 48 additions & 0 deletions tests/test_util/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,51 @@ def test_arc_length_3point_zero(self):

with self.assertRaises(ValueError):
self.assertAlmostEqual(f.arc_length_3point(a, b, c), 0)

def test_mirror_yz(self):
point = [2, 0, 0]
mirrored = f.mirror(point, [1, 0, 0], [0, 0, 0])

np.testing.assert_almost_equal(mirrored, [-2, 0, 0])

def test_mirror_yz_origin(self):
point = [2, 0, 0]
mirrored = f.mirror(point, [1, 0, 0], [1, 1, 1])

np.testing.assert_almost_equal(mirrored, [0, 0, 0])

def test_mirror_xz(self):
point = [0, 2, 0]
mirrored = f.mirror(point, [0, 1, 0], [0, 0, 0])

np.testing.assert_almost_equal(mirrored, [0, -2, 0])

def test_mirror_xz_origin(self):
point = [0, 2, 0]
mirrored = f.mirror(point, [0, 1, 0], [0, 1, 0])

np.testing.assert_almost_equal(mirrored, [0, 0, 0])

def test_mirror_xy(self):
point = [0, 0, 2]
mirrored = f.mirror(point, [0, 0, 1], [0, 0, 0])

np.testing.assert_almost_equal(mirrored, [0, 0, -2])

def test_mirror_xy_origin(self):
point = [0, 0, 2]
mirrored = f.mirror(point, [0, 0, 1], [0, 0, 1])

np.testing.assert_almost_equal(mirrored, [0, 0, 0])

def test_mirror_arbitrary(self):
point = [2, 2, 2]
mirrored = f.mirror(point, [1, 1, 1], [0, 0, 0])

np.testing.assert_almost_equal(mirrored, [-2, -2, -2])

def test_mirror_arbitrary_origin(self):
point = [2, 2, 2]
mirrored = f.mirror(point, [1, 1, 1], [1, 1, 1])

np.testing.assert_almost_equal(mirrored, [0, 0, 0])

0 comments on commit d7b13a6

Please sign in to comment.