From 150f2a75d6e7dcbefbad3ec7044545cdc64dee0d Mon Sep 17 00:00:00 2001 From: Umut Soysal Date: Thu, 16 Jan 2025 17:24:56 -0600 Subject: [PATCH 1/6] matrix operations --- src/ansys/geometry/core/math/matrix.py | 35 ++++++++++++++++++++++++++ src/ansys/geometry/core/math/vector.py | 16 ++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/ansys/geometry/core/math/matrix.py b/src/ansys/geometry/core/math/matrix.py index fc5b90d195..4e3d5d7cfb 100644 --- a/src/ansys/geometry/core/math/matrix.py +++ b/src/ansys/geometry/core/math/matrix.py @@ -26,6 +26,8 @@ from beartype import beartype as check_input_types import numpy as np +from ansys.geometry.core.math.frame import Frame +from ansys.geometry.core.math.vector import Vector3D from ansys.geometry.core.misc.checks import check_ndarray_is_float_int from ansys.geometry.core.typing import Real, RealSequence @@ -129,3 +131,36 @@ def __new__(cls, input: np.ndarray | RealSequence | Matrix = DEFAULT_MATRIX44): raise ValueError("Matrix44 should only be a 2D array of shape (4,4).") return obj + + @staticmethod + def create_matrix_from_rotation(direction_x: Vector3D, direction_y: Vector3D) -> "Matrix44": + """Matrix44 helper method -- create_matrix_from_rotation.""" + matrix = Matrix44( + [ + [direction_x.x, direction_x.y, direction_x.z, 0], + [direction_y.x, direction_y.y, direction_y.z, 0], + [0, 0, 1, 0], + [0, 0, 0, 1], + ] + ) + return matrix + + @staticmethod + def create_matrix_from_translation(origin: Vector3D) -> "Matrix44": + """Matrix44 helper method -- create_matrix_from_translation.""" + matrix = Matrix44( + [ + [1, 0, 0, origin.x], + [0, 1, 0, origin.y], + [0, 0, 1, origin.z], + [0, 0, 0, 1], + ] + ) + return matrix + + @staticmethod + def create_matrix_from_mapping(frame: Frame) -> "Matrix44": + """Matrix44 helper method -- create_matrix_from_mapping.""" + translation_matrix = Matrix44.create_matrix_from_translation(frame.origin) + rotation_matrix = Matrix44.create_matrix_from_rotation(frame.direction_x, frame.direction_y) + return translation_matrix * rotation_matrix diff --git a/src/ansys/geometry/core/math/vector.py b/src/ansys/geometry/core/math/vector.py index b986196175..ac9e7a5d7b 100644 --- a/src/ansys/geometry/core/math/vector.py +++ b/src/ansys/geometry/core/math/vector.py @@ -28,6 +28,7 @@ import numpy as np from pint import Quantity +from ansys.geometry.core import math from ansys.geometry.core.math.matrix import Matrix44 from ansys.geometry.core.math.point import Point2D, Point3D from ansys.geometry.core.misc.accuracy import Accuracy @@ -265,6 +266,21 @@ class representing the second point. """ return Vector3D(point_b - point_a) + @staticmethod + def rotate_vector(_this: "Vector3D", vector: "Vector3D", angle: float) -> "Vector3D": + """Vector3D helper method -- rotate_vector.""" + if _this.is_zero: + raise Exception("Invalid vector operation.") + + angle_between = vector.get_angle_between(_this) + parallel = Vector3D( + vector.x * angle_between, vector.y * angle_between, vector.z * angle_between + ) + + perpendicular1 = vector - parallel + perpendicular2 = _this.cross(perpendicular1) + return parallel + perpendicular1 * math.cos(angle) + perpendicular2 * math.sin(angle) + class Vector2D(np.ndarray): """Provides for creating and managing a 2D vector. From 5457e38e01419ff699aefe5085bdaab50c53a8c7 Mon Sep 17 00:00:00 2001 From: Umut Soysal Date: Fri, 17 Jan 2025 00:07:17 -0600 Subject: [PATCH 2/6] refactrng2 --- src/ansys/geometry/core/math/matrix.py | 27 ++++++++++++++++--------- src/ansys/geometry/core/math/vector.py | 2 +- tests/test_math.py | 28 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/ansys/geometry/core/math/matrix.py b/src/ansys/geometry/core/math/matrix.py index 4e3d5d7cfb..acac700454 100644 --- a/src/ansys/geometry/core/math/matrix.py +++ b/src/ansys/geometry/core/math/matrix.py @@ -21,13 +21,15 @@ # SOFTWARE. """Provides matrix primitive representations.""" -from typing import Union +from typing import TYPE_CHECKING, Union + +if TYPE_CHECKING: + from ansys.geometry.core.math.frame import Frame # For type hints + from ansys.geometry.core.math.vector import Vector3D # For type hints from beartype import beartype as check_input_types import numpy as np -from ansys.geometry.core.math.frame import Frame -from ansys.geometry.core.math.vector import Vector3D from ansys.geometry.core.misc.checks import check_ndarray_is_float_int from ansys.geometry.core.typing import Real, RealSequence @@ -132,10 +134,12 @@ def __new__(cls, input: np.ndarray | RealSequence | Matrix = DEFAULT_MATRIX44): return obj - @staticmethod - def create_matrix_from_rotation(direction_x: Vector3D, direction_y: Vector3D) -> "Matrix44": + @classmethod + def create_matrix_from_rotation( + cls, direction_x: "Vector3D", direction_y: "Vector3D" + ) -> "Matrix44": """Matrix44 helper method -- create_matrix_from_rotation.""" - matrix = Matrix44( + matrix = cls( [ [direction_x.x, direction_x.y, direction_x.z, 0], [direction_y.x, direction_y.y, direction_y.z, 0], @@ -145,9 +149,11 @@ def create_matrix_from_rotation(direction_x: Vector3D, direction_y: Vector3D) -> ) return matrix - @staticmethod - def create_matrix_from_translation(origin: Vector3D) -> "Matrix44": + @classmethod + def create_matrix_from_translation(cls, origin: "Vector3D") -> "Matrix44": """Matrix44 helper method -- create_matrix_from_translation.""" + from ansys.geometry.core.math.matrix import Matrix44 + matrix = Matrix44( [ [1, 0, 0, origin.x], @@ -158,9 +164,10 @@ def create_matrix_from_translation(origin: Vector3D) -> "Matrix44": ) return matrix - @staticmethod - def create_matrix_from_mapping(frame: Frame) -> "Matrix44": + @classmethod + def create_matrix_from_mapping(cls, frame: "Frame") -> "Matrix44": # noqa """Matrix44 helper method -- create_matrix_from_mapping.""" translation_matrix = Matrix44.create_matrix_from_translation(frame.origin) rotation_matrix = Matrix44.create_matrix_from_rotation(frame.direction_x, frame.direction_y) + return translation_matrix * rotation_matrix diff --git a/src/ansys/geometry/core/math/vector.py b/src/ansys/geometry/core/math/vector.py index ac9e7a5d7b..9a7a9a31ef 100644 --- a/src/ansys/geometry/core/math/vector.py +++ b/src/ansys/geometry/core/math/vector.py @@ -139,7 +139,7 @@ def normalize(self) -> "Vector3D": else: raise ValueError("The norm of the 3D vector is not valid.") - def transform(self, matrix: "Matrix44") -> "Vector3D": + def transform(self, matrix: "Matrix44") -> "Vector3D": # noqa """Transform the 3D vector3D with a transformation matrix. Parameters diff --git a/tests/test_math.py b/tests/test_math.py index 12586625dd..fc567db328 100644 --- a/tests/test_math.py +++ b/tests/test_math.py @@ -752,6 +752,34 @@ def test_matrix_44(): assert "Matrix44 should only be a 2D array of shape (4,4)." in str(val.value) +def test_create_matrix_from_rotation(): + direction_x = Vector3D([1, 0, 0]) + direction_y = Vector3D([0, 1, 0]) + + expected_matrix = Matrix44([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) + rotation_matrix = Matrix44.create_matrix_from_rotation(direction_x, direction_y) + assert np.array_equal(expected_matrix, rotation_matrix) + + +def test_create_matrix_from_translation(): + origin = Vector3D([1, 2, 3]) + + expected_matrix = Matrix44([[1, 0, 0, 1], [0, 1, 0, 2], [0, 0, 1, 3], [0, 0, 0, 1]]) + translation_matrix = Matrix44.create_matrix_from_translation(origin) + assert np.array_equal(expected_matrix, translation_matrix) + + +def test_create_matrix_from_mapping(): + origin = Vector3D([1, 2, 3]) + direction_x = Vector3D([1, 0, 0]) + direction_y = Vector3D([0, 1, 0]) + frame = Frame(origin, direction_x, direction_y) + + expected_matrix = Matrix44([[1, 0, 0, 1], [0, 1, 0, 2], [0, 0, 1, 3], [0, 0, 0, 1]]) + mapping_matrix = Matrix44.create_matrix_from_mapping(frame) + assert np.array_equal(expected_matrix, mapping_matrix) + + def test_frame(): """``Frame`` construction and equivalency.""" origin = Point3D([42, 99, 13]) From e973c204abe26b032430fe18410075f477878e8d Mon Sep 17 00:00:00 2001 From: Umut Soysal Date: Fri, 17 Jan 2025 00:09:24 -0600 Subject: [PATCH 3/6] refactrng3 --- src/ansys/geometry/core/math/vector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/geometry/core/math/vector.py b/src/ansys/geometry/core/math/vector.py index 9a7a9a31ef..ac9e7a5d7b 100644 --- a/src/ansys/geometry/core/math/vector.py +++ b/src/ansys/geometry/core/math/vector.py @@ -139,7 +139,7 @@ def normalize(self) -> "Vector3D": else: raise ValueError("The norm of the 3D vector is not valid.") - def transform(self, matrix: "Matrix44") -> "Vector3D": # noqa + def transform(self, matrix: "Matrix44") -> "Vector3D": """Transform the 3D vector3D with a transformation matrix. Parameters From 1147a97dc196bdf3091a9d705ff058f455ff515c Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Mon, 20 Jan 2025 09:09:06 +0000 Subject: [PATCH 4/6] chore: adding changelog file 1649.added.md [dependabot-skip] --- doc/changelog.d/1649.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/1649.added.md diff --git a/doc/changelog.d/1649.added.md b/doc/changelog.d/1649.added.md new file mode 100644 index 0000000000..6098988cbd --- /dev/null +++ b/doc/changelog.d/1649.added.md @@ -0,0 +1 @@ +matrix operations \ No newline at end of file From 697be2e98fe07af988d661967db5688ca0664458 Mon Sep 17 00:00:00 2001 From: Umut Soysal Date: Wed, 22 Jan 2025 08:38:57 -0600 Subject: [PATCH 5/6] getting dimensionless value --- src/ansys/geometry/core/math/matrix.py | 18 +++++++++--------- tests/test_math.py | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/ansys/geometry/core/math/matrix.py b/src/ansys/geometry/core/math/matrix.py index acac700454..c7727670fb 100644 --- a/src/ansys/geometry/core/math/matrix.py +++ b/src/ansys/geometry/core/math/matrix.py @@ -25,6 +25,7 @@ if TYPE_CHECKING: from ansys.geometry.core.math.frame import Frame # For type hints + from ansys.geometry.core.math.point import Point3D # For type hints from ansys.geometry.core.math.vector import Vector3D # For type hints from beartype import beartype as check_input_types @@ -150,15 +151,14 @@ def create_matrix_from_rotation( return matrix @classmethod - def create_matrix_from_translation(cls, origin: "Vector3D") -> "Matrix44": + def create_matrix_from_translation(cls, origin: "Point3D") -> "Matrix44": """Matrix44 helper method -- create_matrix_from_translation.""" - from ansys.geometry.core.math.matrix import Matrix44 - - matrix = Matrix44( + print(origin) + matrix = cls( [ - [1, 0, 0, origin.x], - [0, 1, 0, origin.y], - [0, 0, 1, origin.z], + [1, 0, 0, origin.x.m], + [0, 1, 0, origin.y.m], + [0, 0, 1, origin.z.m], [0, 0, 0, 1], ] ) @@ -167,7 +167,7 @@ def create_matrix_from_translation(cls, origin: "Vector3D") -> "Matrix44": @classmethod def create_matrix_from_mapping(cls, frame: "Frame") -> "Matrix44": # noqa """Matrix44 helper method -- create_matrix_from_mapping.""" - translation_matrix = Matrix44.create_matrix_from_translation(frame.origin) - rotation_matrix = Matrix44.create_matrix_from_rotation(frame.direction_x, frame.direction_y) + translation_matrix = cls.create_matrix_from_translation(frame.origin) + rotation_matrix = cls.create_matrix_from_rotation(frame.direction_x, frame.direction_y) return translation_matrix * rotation_matrix diff --git a/tests/test_math.py b/tests/test_math.py index fc567db328..d75dfc254d 100644 --- a/tests/test_math.py +++ b/tests/test_math.py @@ -776,6 +776,7 @@ def test_create_matrix_from_mapping(): frame = Frame(origin, direction_x, direction_y) expected_matrix = Matrix44([[1, 0, 0, 1], [0, 1, 0, 2], [0, 0, 1, 3], [0, 0, 0, 1]]) + mapping_matrix = Matrix44.create_matrix_from_mapping(frame) assert np.array_equal(expected_matrix, mapping_matrix) From a761012a863d6d4917652e2a8a89c35a08fe762a Mon Sep 17 00:00:00 2001 From: Umut Soysal Date: Wed, 22 Jan 2025 09:02:18 -0600 Subject: [PATCH 6/6] rename variable --- tests/test_math.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_math.py b/tests/test_math.py index d75dfc254d..3d26eeb4f2 100644 --- a/tests/test_math.py +++ b/tests/test_math.py @@ -762,7 +762,7 @@ def test_create_matrix_from_rotation(): def test_create_matrix_from_translation(): - origin = Vector3D([1, 2, 3]) + origin = Point3D([1, 2, 3]) expected_matrix = Matrix44([[1, 0, 0, 1], [0, 1, 0, 2], [0, 0, 1, 3], [0, 0, 0, 1]]) translation_matrix = Matrix44.create_matrix_from_translation(origin)