Geometry

3D geometry calculations and coordinate utilities.

Geometry utilities for 3D calculations in eye tracking.

This module provides geometric functions for: - 3D coordinate conversions and transformations - Ray-surface intersection calculations - Vector and matrix utilities - Eye rotation calculations (Listing’s law) - Plane detection for calibration

Conversions

Coordinate and gaze conversion utilities for eye tracking simulation.

Implements conversions between gaze direction, rotation angles, and observer/screen coordinates.

pyetsimul.geometry.conversions.gaze2angle(gaze, rest_pos=None)[source]

Convert gaze direction to eye rotation angles.

Calculates horizontal and vertical rotation angles from a 3D gaze direction relative to the eye’s rest position. Uses Listing’s law coordinate system.

Parameters:
  • gaze (Direction3D) – 3D gaze direction vector

  • rest_pos (RotationMatrix | None) – Optional 3x3 rotation matrix for eye rest position. Defaults to [[-1,0,0], [0,0,1], [0,1,0]]

Return type:

Point2D

Returns:

Point2D containing [horizontal_angle, vertical_angle] in radians

pyetsimul.geometry.conversions.angle2gaze(angles, rest_pos=None)[source]

Convert eye rotation angles to gaze direction.

Calculates gaze direction from horizontal and vertical rotation angles using Euler rotation matrices. Applies rotations in Listing’s law order.

Parameters:
  • angles (Point2D) – 2D point containing rotation angles [horizontal, vertical] in radians

  • rest_pos (RotationMatrix | None) – Optional 3x3 rotation matrix for eye rest position. Defaults to [[-1,0,0], [0,0,1], [0,1,0]]

Return type:

Direction3D

Returns:

Direction3D representing the gaze direction vector

pyetsimul.geometry.conversions.calculate_angular_error_degrees(actual_point, predicted_point, observer_pos)[source]

Calculate angular error between actual and predicted gaze points.

Creates 3D gaze vectors from observer to each point and computes the angle between them using the dot product formula. Handles numerical precision issues.

Parameters:
  • actual_point (Point3D) – Actual target point [x, y, z] in mm

  • predicted_point (Point3D) – Predicted gaze point [x, y, z] in mm

  • observer_pos (Position3D) – Observer position [x, y, z] in mm

Return type:

float

Returns:

Angular error in degrees

Plane Detection

Automatic 2D plane detection for calibration targets.

This module provides utilities to automatically detect which 2D plane calibration points lie in and extract appropriate coordinate mappings for polynomial fitting.

class pyetsimul.geometry.plane_detection.PlaneInfo(plane_type, primary_axis, secondary_axis, constant_axis, constant_value)[source]

Bases: object

Information about detected calibration plane.

Represents a 2D plane in 3D space for coordinate mapping and polynomial fitting. Automatically determines which axis is constant and which two axes vary.

Parameters:
  • plane_type (str)

  • primary_axis (str)

  • secondary_axis (str)

  • constant_axis (str)

  • constant_value (float)

plane_type: str
primary_axis: str
secondary_axis: str
constant_axis: str
constant_value: float
extract_2d_coords(position)[source]

Extract 2D coordinates for polynomial fitting.

Maps 3D position to 2D coordinates based on plane orientation.

Return type:

tuple[float, float]

Parameters:

position (Position3D)

reconstruct_3d_point(coord1, coord2)[source]

Reconstruct 3D point from 2D polynomial prediction.

Maps 2D polynomial output back to 3D space using plane information.

Return type:

Point3D

Parameters:
serialize()[source]

Serialize plane info to dictionary.

Return type:

dict

classmethod deserialize(data)[source]

Deserialize from dictionary representation.

Return type:

PlaneInfo

Parameters:

data (dict)

pyetsimul.geometry.plane_detection.detect_calibration_plane(calib_points, tolerance=1e-06)[source]

Automatically detect which 2D plane the calibration points lie in.

Uses variance analysis to determine which axis is constant and which two axes vary. Supports standard orthogonal planes (xy, xz, yz) for polynomial gaze models.

Parameters:
  • calib_points (list[Position3D]) – List of calibration target positions

  • tolerance (float) – Variance threshold for considering an axis constant

Returns:

Information about the detected plane and coordinate mappings

Return type:

PlaneInfo

Raises:

ValueError – If points don’t lie in exactly one of the standard 2D planes

pyetsimul.geometry.plane_detection.summarize_plane_detection(calib_points, plane_info)[source]

Create a human-readable summary of the plane detection results.

Generates formatted output showing plane type, coordinate mapping, and coverage area for logging and display purposes.

Parameters:
  • calib_points (list[Position3D]) – List of calibration target positions

  • plane_info (PlaneInfo) – Information about the detected plane

Returns:

Formatted summary for logging/display

Return type:

str

Intersections

Ray-surface intersection and geometric calculation utilities for eye tracking simulation.

Provides functions for intersecting rays with spheres, circles, planes, and conic surfaces, as well as related geometric operations.

pyetsimul.geometry.intersections.intersect_ray_sphere(ray, sphere_center, sphere_radius)[source]

Find intersection points between ray and sphere.

Uses quadratic equation to find intersection points. Returns both intersection points ordered by distance from ray origin (closer first).

Parameters:
  • ray (Ray) – Ray with origin and direction

  • sphere_center (Position3D) – Sphere center position

  • sphere_radius (float) – Sphere radius

Return type:

tuple[IntersectionResult | None, IntersectionResult | None]

Returns:

Tuple of (closer_result, farther_result) where closer_result is closer intersection, farther_result is farther. Returns (None, None) if no intersection.

pyetsimul.geometry.intersections.intersect_ray_circle(ray, circle_center, circle_radius)[source]

Find intersection between ray and circle in 2D plane.

Uses quadratic equation to find intersection points in x-y plane. Returns the closest intersection point to ray origin.

Parameters:
  • ray (Ray) – Ray with origin and direction

  • circle_center (Point3D) – Circle center (2D using x,y components)

  • circle_radius (float) – Circle radius

Return type:

IntersectionResult | None

Returns:

Intersection result with closest point to ray origin, or None if no intersection

pyetsimul.geometry.intersections.intersect_ray_plane(ray, plane_point, plane_normal)[source]

Find intersection between ray and plane.

Solves the parametric ray equation with the plane equation using dot product. Returns intersection point with surface normal.

Parameters:
  • ray (Ray) – Ray with origin and direction

  • plane_point (Position3D) – Point on plane

  • plane_normal (Direction3D) – Plane normal vector

Return type:

IntersectionResult | None

Returns:

Intersection result, or None if ray is parallel to plane

pyetsimul.geometry.intersections.intersect_ray_conic(ray, conic_center, radius, conic_constant)[source]

Find intersection between ray and conic section.

Uses quadratic equation derived from conic surface equation. Returns both intersection points ordered by distance from ray origin.

Parameters:
  • ray (Ray) – Ray with origin and direction

  • conic_center (Position3D) – Conic center position

  • radius (float) – Radius parameter (R in the formula, mm)

  • conic_constant (float) – Conic constant (k < 0 for prolate, k = 0 for sphere, k > 0 for oblate)

Returns:

Intersection results closer and farther from ray origin. Returns (None, None) if no intersection.

Return type:

Tuple (closer_result, farther_result)

pyetsimul.geometry.intersections.conic_surface_normal(point, conic_center, radius, conic_constant)[source]

Calculate surface normal at a point on conic section surface.

Uses gradient of conic equation to compute normal vector. Handles degenerate case at conic apex.

Parameters:
  • point (Point3D) – Point on conic surface

  • conic_center (Position3D) – Conic center position

  • radius (float) – Radius parameter (R in the formula, mm)

  • conic_constant (float) – Conic constant (k < 0 for prolate, k = 0 for sphere, k > 0 for oblate)

Return type:

Direction3D

Returns:

Unit normal vector pointing outward from conic surface

pyetsimul.geometry.intersections.point_on_conic_surface(conic_center, direction, radius, conic_constant)[source]

Calculate point on conic surface given direction from start point.

Uses quadratic equation to find intersection of ray with conic surface. Chooses best intersection point based on direction alignment.

Parameters:
  • conic_center (Position3D) – Starting point of the ray

  • direction (Vector3D) – Direction vector (will be normalized)

  • radius (float) – Radius parameter of the conic (R)

  • conic_constant (float) – Shape parameter of the conic (k)

Return type:

Point3D | None

Returns:

Point on conic surface, or None if no intersection

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.

pyetsimul.geometry.listings_law.calculate_eye_rotation(out_rest, out_new)[source]

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.

Parameters:
  • out_rest (Vector3D) – Direction of optical axis in rest position (3D vector)

  • out_new (Vector3D) – Direction of optical axis in new position (3D vector)

Return type:

RotationMatrix

Returns:

3x3 rotation matrix A representing the eye rotation

Utilities

Geometric utility functions for eye tracking simulation.

Provides line-line closest point, 2D line intersection, and other basic geometric operations.

pyetsimul.geometry.utils.lines_closest_point(p1, d1, p2, d2)[source]

Find the closest points between two lines in 3D space.

Uses the minimum distance approach to find points on each line that are closest to each other. For parallel lines, returns NaN points.

Parameters:
  • p1 (Point3D) – Point on first line

  • d1 (Vector3D) – Direction vector of first line

  • p2 (Point3D) – Point on second line

  • d2 (Vector3D) – Direction vector of second line

Return type:

tuple[Point3D, Point3D]

Returns:

Tuple of (x1, x2) where x1 is closest point on first line, x2 is closest point on second line. Returns (NaN point, NaN point) if lines are parallel.

pyetsimul.geometry.utils.line_intersect_2d(p11, p12, p21, p22)[source]

Find the intersection point of two 2D lines.

Uses parametric line equations to solve for the intersection point. Returns NaN point if lines are parallel.

Parameters:
  • p11 (Point2D) – First point on first line

  • p12 (Point2D) – Second point on first line

  • p21 (Point2D) – First point on second line

  • p22 (Point2D) – Second point on second line

Return type:

Point2D

Returns:

Intersection point. Returns Point2D(nan, nan) if lines are parallel.