diff --git a/pyproject.toml b/pyproject.toml index fa29cc7..f2ac542 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,6 +2,7 @@ name = "matrixmania" version = "0.1.0" dependencies = ["tabulate", "ruff"] + [project.optional-dependencies] dev = ["pytest", "ruff", "pytest-cov"] diff --git a/src/matrixmania/compute.py b/src/matrixmania/compute.py index 7a09f52..2a11f7a 100644 --- a/src/matrixmania/compute.py +++ b/src/matrixmania/compute.py @@ -104,6 +104,65 @@ def rot_2D(winkel): ] def rot_3D(angle: float, axis: str) -> list[list[float]]: + """Gibt die Rotationsmatrix für einen Winkel in Radiant um die x-, y- oder z-Achse zurück. + + Parameters + ---------- + angle : float + Rotationswinkel in Radiant. + axis : str + Rotationsachse: ``"x"``, ``"y"`` oder ``"z"``. + + Returns + ------- + list[list[float]] + Die entsprechende 3x3-Rotationsmatrix. + + Raises + ------ + ValueError + Wenn ``axis`` nicht ``"x"``, ``"y"`` oder ``"z"`` ist. + + Formeln + ------- + Rx(theta) = + [[1, 0, 0], + [0, cos(theta), -sin(theta)], + [0, sin(theta), cos(theta)]] + + Ry(theta) = + [[cos(theta), 0, sin(theta)], + [0, 1, 0], + [-sin(theta), 0, cos(theta)]] + + Rz(theta) = + [[cos(theta), -sin(theta), 0], + [sin(theta), cos(theta), 0], + [0, 0, 1]] + """ + if axis == "x": + return [ + [1.0, 0.0, 0.0], + [0.0, math.cos(angle), -math.sin(angle)], + [0.0, math.sin(angle), math.cos(angle)], + ] + + if axis == "y": + return [ + [math.cos(angle), 0.0, math.sin(angle)], + [0.0, 1.0, 0.0], + [-math.sin(angle), 0.0, math.cos(angle)], + ] + + if axis == "z": + return [ + [math.cos(angle), -math.sin(angle), 0.0], + [math.sin(angle), math.cos(angle), 0.0], + [0.0, 0.0, 1.0], + ] + + raise ValueError("axis must be 'x', 'y' or 'z'") + def transpose(a: list[list[float]]) -> list[list[float]]: """Gibt die transponierte Matrix a zurück.""" return [ diff --git a/test/test_matrixmania/__init__.py b/test/test_matrixmania/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/test_matrixmania/test_rot.py b/test/test_matrixmania/test_rot.py new file mode 100644 index 0000000..84a8969 --- /dev/null +++ b/test/test_matrixmania/test_rot.py @@ -0,0 +1,30 @@ +import math +import pytest + +from matrixmania.compute import rot_2D, rot_3D + +def test_rot2D_90_grad(): # dreht es sich wirklich um 90 grad? + #Arrange + angle = math.pi/2 + expected = [ + [math.cos(angle), -math.sin(angle)], + [math.sin(angle), math.cos(angle)] + ] + + #Act + result = rot_2D(angle) + #Assert + assert result == expected + +def test_rot3D_drehen(): #dreht sich um 90 grad? + #Arrange + angle = math.pi/2 + achse = "z" + expected = [ + [math.cos(angle), -math.sin(angle), 0.0], + [math.sin(angle), math.cos(angle), 0.0], + [0.0, 0.0, 1.0], + ] + + result = rot_3D(angle, achse) + assert result == expected \ No newline at end of file