diff --git a/apollo.py b/apollo.py new file mode 100644 index 0000000..ed34b06 --- /dev/null +++ b/apollo.py @@ -0,0 +1,53 @@ +from __future__ import annotations + +import pygame + +from compute import rot_2D, matmul +from moon import Moon + +# Apollo visual parameters +APOLLO_RADIUS = 2 +APOLLO_COLOR = (255, 0, 0) + +class Apollo(Moon): + + def __init__(self, title: str = "Apollo", fps: int = 60, size: tuple[int, int] = (640, 400)) -> None: + super().__init__(title=title, fps=fps, size=size) + + # Apollo starts on the positive x‑axis relative to the moon + self.offsetap: tuple[float, float] = (40.0, 0.0) + # Apollo moves twice as fast and opposite direction + self.delta_thetaap: float = -0.05 + self.thetaap: float = 0.0 + self.rot_apollo: list[list[float]] = rot_2D(self.theta) + + def update_game(self) -> bool: + # Update moon first + super().update_game() + # Advance Apollo + self.thetaap += self.delta_thetaap + self.rot_apollo = rot_2D(self.thetaap) + point = [[self.offsetap[0]], [self.offsetap[1]]] + rel_pos = matmul(self.rot_apollo, point) + # Apollo's world position is moon's position plus relative vector + moon_pos = self.position_moon + self.position_apollo = ( + moon_pos[0] + rel_pos[0][0], + moon_pos[1] + rel_pos[1][0], + ) + return True + + def draw_game(self) -> None: + # Draw base moon graphics + super().draw_game() + # Draw Apollo on the screen + pygame.draw.circle( + self.screen, + APOLLO_COLOR, + (int(self.position_apollo[0]), int(self.position_apollo[1])), + APOLLO_RADIUS, + ) + +if __name__ == "__main__": + apollo = Apollo() + apollo.run() diff --git a/compute.py b/compute.py index d466f8c..8e374de 100644 --- a/compute.py +++ b/compute.py @@ -53,20 +53,12 @@ def matmul(left: Matrix, right: Matrix) -> list[list[float]]: result.append(row) return result - - - - # Helper to validate a matrix is non‑empty and rectangular. def rot_2D(theta: float) -> list[list[float]]: """Return the 2‑D rotation matrix for a given angle. - Parameters - ---------- theta Rotation angle in radians. - Returns - ------- list[list[float]] 2×2 rotation matrix ``[[cosθ, -sinθ], [sinθ, cosθ]]``. """ @@ -76,12 +68,10 @@ def rot_2D(theta: float) -> list[list[float]]: def _validate(matrix: Matrix, name: str) -> None: """Check that *matrix* is a non‑empty, rectangular 2D sequence. - Validation rules: * The outer sequence must contain at least one row. * Every row must have the same number of columns. * No empty rows are allowed. - Raises: ValueError: If the matrix is empty, has zero columns, or is ragged. """ @@ -98,10 +88,7 @@ def _validate(matrix: Matrix, name: str) -> None: ) def transpose(matrix: Matrix) -> list[list[float]]: - """Transponiere die gegebene Matrix. - - Alle Zeilen werden zu Spalten und alle Spalten zu Zeilen. - + """Transponieren: Alle Zeilen werden zu Spalten und alle Spalten zu Zeilen. Parameters matrix Matrix in Form ``Sequence[Sequence[float]]``.