projection & 3Drot
This commit is contained in:
1 parent
87feb62121
commit
e4d36ad733
4 files changed
+106
No files matched your search
@@ -120,6 +120,64 @@ def matmul(A: Matrix, B: Matrix) -> Matrix:
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def rot_3D(angle: float, axis: str) -> list[list[float]]:
|
||||||
|
"""Berechnet die 3D-Rotationsmatrix für einen gegebenen Winkel und eine Achse.
|
||||||
|
|
||||||
|
Die Rotationsmatrizen lauten:
|
||||||
|
|
||||||
|
Rotation um die x-Achse:
|
||||||
|
R_x(θ) = [[1, 0, 0],
|
||||||
|
[0, cos(θ), -sin(θ)],
|
||||||
|
[0, sin(θ), cos(θ)]]
|
||||||
|
|
||||||
|
Rotation um die y-Achse:
|
||||||
|
R_y(θ) = [[ cos(θ), 0, sin(θ)],
|
||||||
|
[ 0, 1, 0],
|
||||||
|
[-sin(θ), 0, cos(θ)]]
|
||||||
|
|
||||||
|
Rotation um die z-Achse:
|
||||||
|
R_z(θ) = [[cos(θ), -sin(θ), 0],
|
||||||
|
[sin(θ), cos(θ), 0],
|
||||||
|
[ 0, 0, 1]]
|
||||||
|
|
||||||
|
Args:
|
||||||
|
angle (float): Der Rotationswinkel in Bogenmaß (Radians).
|
||||||
|
axis (str): Die Rotationsachse ('x', 'y' oder 'z').
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[list[float]]: Die 3x3-Rotationsmatrix als geschachtelte Liste.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: Wenn ein ungültiger Achsenwert übergeben wird.
|
||||||
|
"""
|
||||||
|
cos_a = math.cos(angle)
|
||||||
|
sin_a = math.sin(angle)
|
||||||
|
|
||||||
|
if axis == "x":
|
||||||
|
return [[1.0, 0.0, 0.0], [0.0, cos_a, -sin_a], [0.0, sin_a, cos_a]]
|
||||||
|
elif axis == "y":
|
||||||
|
return [[cos_a, 0.0, sin_a], [0.0, 1.0, 0.0], [-sin_a, 0.0, cos_a]]
|
||||||
|
elif axis == "z":
|
||||||
|
return [[cos_a, -sin_a, 0.0], [sin_a, cos_a, 0.0], [0.0, 0.0, 1.0]]
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
f"Ungültige Achse '{axis}'. Gültige Achsen sind 'x', 'y' oder 'z'."
|
||||||
|
)
|
||||||
|
|
||||||
|
def project_ortho(point: tuple[float, float, float], scale: float = 1) -> tuple[float, float]:
|
||||||
|
"""Projiziert einen 3D-Punkt (x, y, z) orthogonal auf eine 2D-Fläche (x, y),
|
||||||
|
indem die z-Koordinate ignoriert und der Punkt mit scale multipliziert wird.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
point (tuple[float, float, float]): Der 3D-Punkt als (x, y, z).
|
||||||
|
scale (float, optional): Skalierungsfaktor für die Ausgabe. Standard ist 1.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple[float, float]: Der 2D-Punkt als (x * scale, y * scale).
|
||||||
|
"""
|
||||||
|
x, y, _ = point
|
||||||
|
return (x * scale, y * scale)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Test für rot_2D (z. B. Rotation um 90 Grad = pi / 2)
|
# Test für rot_2D (z. B. Rotation um 90 Grad = pi / 2)
|
||||||
theta = math.pi / 2
|
theta = math.pi / 2
|
||||||
|
|||||||
Whitespace-only changes.
@@ -0,0 +1,16 @@
|
|||||||
|
import pytest
|
||||||
|
from matrixmania.compute import project_ortho
|
||||||
|
|
||||||
|
|
||||||
|
def test_project_ortho_default_scale():
|
||||||
|
# Test ohne Angabe von scale (Standardwert = 1)
|
||||||
|
point = (1.0, 2.0, 3.0)
|
||||||
|
result = project_ortho(point)
|
||||||
|
assert result == (1.0, 2.0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_project_ortho_with_scale():
|
||||||
|
# Test mit scale = 100
|
||||||
|
point = (1.0, 2.0, 3.0)
|
||||||
|
result = project_ortho(point, scale=100)
|
||||||
|
assert result == (100.0, 200.0)
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import math
|
||||||
|
import pytest
|
||||||
|
from matrixmania.compute import rot_3D
|
||||||
|
|
||||||
|
|
||||||
|
def test_rot_3D_x_axis():
|
||||||
|
# Test bei 0 Radian (Identitätsmatrix)
|
||||||
|
res = rot_3D(0.0, "x")
|
||||||
|
assert res == [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
|
||||||
|
|
||||||
|
# Test bei 90 Grad (PI / 2)
|
||||||
|
res_90 = rot_3D(math.pi / 2, "x")
|
||||||
|
assert pytest.approx(res_90[1][1]) == 0.0
|
||||||
|
assert pytest.approx(res_90[1][2]) == -1.0
|
||||||
|
assert pytest.approx(res_90[2][1]) == 1.0
|
||||||
|
assert pytest.approx(res_90[2][2]) == 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_rot_3D_y_axis():
|
||||||
|
res = rot_3D(0.0, "y")
|
||||||
|
assert res == [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
|
||||||
|
|
||||||
|
|
||||||
|
def test_rot_3D_z_axis():
|
||||||
|
res = rot_3D(0.0, "z")
|
||||||
|
assert res == [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
|
||||||
|
|
||||||
|
|
||||||
|
def test_rot_3D_invalid_axis():
|
||||||
|
# Prüft, ob bei ungültiger Achse ein ValueError geworfen wird
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
rot_3D(1.0, "w")
|
||||||
Reference in new issue
Block a user