Source code for pyetsimul.geometry.listings_law

"""Listing's law implementation for eye rotation calculations.

This module implements Listing's law, which describes how the eye rotates
when changing fixation direction. Extracted from the Eye class for better
modularity and testability.
"""

import numpy as np

from ..types import RotationMatrix, Vector3D


[docs] def calculate_eye_rotation(out_rest: Vector3D, out_new: Vector3D) -> RotationMatrix: """Calculate eye rotation matrix using Listing's law. Computes rotation matrix for eye movement from rest position to new position using Listing's law coordinate system approach. Args: out_rest: Direction of optical axis in rest position (3D vector) out_new: Direction of optical axis in new position (3D vector) Returns: 3x3 rotation matrix A representing the eye rotation """ # Normalize input vectors out_rest_norm = out_rest.normalize() out_new_norm = out_new.normalize() # Calculate rotation axis as cross product axis = out_new_norm.cross(out_rest_norm) # Check if vectors are parallel (no rotation needed) if axis.magnitude() == 0: return np.eye(3) # Normalize the rotation axis axis = axis.normalize() # Calculate third vectors for coordinate system third_rest = out_rest_norm.cross(axis) third_new = out_new_norm.cross(axis) # Build rotation matrix using coordinate system approach left_matrix = np.column_stack([np.array(axis), np.array(out_new_norm), np.array(third_new)]) right_matrix = np.vstack([np.array(axis), np.array(out_rest_norm), np.array(third_rest)]) return RotationMatrix(left_matrix @ right_matrix)