Rendering package

ephemeris_tools.rendering

PostScript and matplotlib rendering for viewer and tracker outputs.

escl07(hmin: int, hmax: int, vmin: int, vmax: int, state: EscherState) None[source]

Clear a region of the page or end the page (port of ESCL07).

If the region equals the full page (MINX, MAXX, MINY, MAXY), writes showpage and closes the file (unless external_stream is True). Otherwise draws a white filled rectangle over the region.

Parameters:
  • hmin – Horizontal pixel bounds.

  • hmax – Horizontal pixel bounds.

  • vmin – Vertical line bounds.

  • vmax – Vertical line bounds.

  • state – Escher state (file may be closed on full-page clear).

esdr07(nsegs: int, segs: list[int], state: EscherState) None[source]

Draw buffered segments to PostScript (port of ESDR07).

Groups connected segments with the same color into paths and strokes them. Opens the output file on first call if not already open.

Parameters:
  • nsegs – Number of integers in segs (must be multiple of 5).

  • segs – Flat list of (BP, BL, EP, EL, COLOR) per segment: begin pixel/line, end pixel/line, color code.

  • state – Escher state (file written, xsave/ysave/oldcol updated).

esfile(filename: str, creator: str, fonts: str, state: EscherState) None[source]

Set PostScript output filename, creator, and document fonts (port of ESFILE).

Does not open the file; opening happens on first write (esopen or esdr07). Resets state (drawn flag, stream handle).

Parameters:
  • filename – Output path for the PostScript file.

  • creator – Creator string for %%Creator.

  • fonts – Document fonts for %%DocumentFonts.

  • state – Escher state (modified in place).

eslwid(points: float, state: EscherState) None[source]

Set line width in points for PostScript output (port of ESLWID).

Writes setlinewidth only when the width changes from the previous call.

Parameters:
  • points – Line width in points (scaled by 10 for internal units).

  • state – Escher state (oldwidth updated).

esmove(state: EscherState) None[source]

Emit PostScript moveto to the end of the last stroked path (port of ESMOVE).

Used to continue drawing from the current point (e.g. for labels).

Parameters:

state – Escher state (xsave, ysave are the last point).

espl07() tuple[int, int, int, int][source]

Return graphics device boundaries in pixel/line (port of ESPL07).

Returns:

Tuple (MINX, MAXX, MINY, MAXY) for the device.

eswrit(string: str, state: EscherState) None[source]

Write a raw string to the PostScript file (port of ESWRIT).

Adds a newline if the string does not end with one.

Parameters:
  • string – Text to write (e.g. PostScript commands).

  • state – Escher state (outuni must be open).

eubody(body: int, merids: int, latcir: int, srcreq: int, bright: int, dark: int, term: int, euclid_state: EuclidState, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw one ellipsoid body with terminator and optional grid (port of EUBODY).

Draws the body specified by index (1..nbods from eugeom). Meridians and latitude circles form a coordinate grid; lit/dark/terminator use the given color codes. SRCREQ is the number of lights required to consider a point lit.

Parameters:
  • body – Body index (1-based, must be in range from last eugeom call).

  • merids – Number of meridian circles.

  • latcir – Number of latitude circles.

  • srcreq – Number of light sources required for a point to be lit.

  • bright – Color for lit regions.

  • dark – Color for unlit regions.

  • term – Color for terminator (lit/dark boundary).

  • euclid_state – Euclid state from eugeom/euview.

  • view_state – Escher view state.

  • escher_state – Escher output state.

euclr(device: int, hmin: float, hmax: float, vmin: float, vmax: float, escher_state: EscherState) None[source]

Clear a region of the display (port of EUCLR).

Same argument meanings as EUVIEW. Used for multi-exposure or inset images.

Parameters:
  • device – Display device number.

  • hmin – Horizontal limits of region to clear (must differ, in [0,1]).

  • hmax – Horizontal limits of region to clear (must differ, in [0,1]).

  • vmin – Vertical limits of region to clear (must differ, in [0,1]).

  • vmax – Vertical limits of region to clear (must differ, in [0,1]).

  • escher_state – Escher output state.

eugeom(nlites: int, source: list[list[float]], srcrad: list[float], obsrve: list[float], camfrm: list[list[float]], nbods: int, bodies: list[list[float]], axes: list[list[list[float]]], euclid_state: EuclidState) None[source]

Set scene geometry: lights, camera, bodies; compute limbs/terminators (port of EUGEOM).

Defines illumination sources (positions and radii), camera position and orientation (obsrve, camfrm), and ellipsoid bodies (positions and principal axes). Computes limb ellipses and terminator/eclipse geometry per body/light.

Parameters:
  • nlites – Number of light sources.

  • source – Light positions (list of 3-vectors).

  • srcrad – Light radii.

  • obsrve – Camera (pinhole) position.

  • camfrm – 3x3 camera frame (columns = x, y, z in image plane and toward scene).

  • nbods – Number of bodies.

  • bodies – Body center positions.

  • axes – Body principal axes; axes[i][j] is j-th axis of body i (length = semi-axis).

  • euclid_state – Euclid state (modified in place).

euinit(state: EuclidState) None[source]

Initialize Euclid: compute trig tables and constants (port of EUINIT).

Call once before any other Euclid entry points. Repeated calls have no effect after the first.

Parameters:

state – EuclidState to initialize (modified in place).

euring(ring_center: list[float], major: list[float], minor: list[float], srcreq: int, bright: int, dark: int, euclid_state: EuclidState, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw an elliptical ring (port of EURING).

Ring is a curve only; it does not cast shadows. Lit and dark portions use the given color codes. MAJOR and MINOR are assumed orthogonal (semi-axes).

Parameters:
  • ring_center – Center of the ring (e.g. planet center).

  • major – Semi-major axis vector (direction and length).

  • minor – Semi-minor axis vector (direction and length).

  • srcreq – Number of light sources required to consider a point lit.

  • bright – Color code for lit portion.

  • dark – Color code for unlit portion.

  • euclid_state – Euclid state (from eugeom/euview).

  • view_state – Escher view state.

  • escher_state – Escher output state.

eustar(strpos: tuple[float, float, float], nstars: int, font: list[tuple[tuple[float, float], tuple[float, float]]], fntsiz: int, fntscl: float, color: int, euclid_state: EuclidState, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw star/point markers with a line-segment font (port of EUSTAR).

Characters are scaled by fntscl times the display size so they do not scale with zoom. Font is a list of ((x1,y1),(x2,y2)) segment endpoints.

Parameters:
  • strpos – Position of the point (e.g. star) in scene coordinates.

  • nstars – Number of points (unused; single point drawn).

  • font – Segment list for the marker; font[i] = ((x1,y1), (x2,y2)).

  • fntsiz – Number of segments to use.

  • fntscl – Scale factor (0-1) for marker size vs display.

  • color – Color code for drawing.

  • euclid_state – Euclid state.

  • view_state – Escher view state.

  • escher_state – Escher output state.

eutemp(xbegin: list[float], ybegin: list[float], xend: list[float], yend: list[float], nsegs: int, color: int, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw line-segment overlay on the image plane (port of EUTEMP).

Draws reference marks (e.g. angle scale) in image-plane coordinates. Segment i has start (xbegin[i], ybegin[i]) and end (xend[i], yend[i]).

Parameters:
  • xbegin – x-coordinates of segment starts.

  • ybegin – y-coordinates of segment starts.

  • xend – x-coordinates of segment ends.

  • yend – y-coordinates of segment ends.

  • nsegs – Number of segments.

  • color – Color code for drawing.

  • view_state – Escher view state.

  • escher_state – Escher output state.

euview(device: int, h1: float, h2: float, v1: float, v2: float, x1: float, x2: float, y1: float, y2: float, euclid_state: EuclidState, view_state: EscherViewState, escher_state: EscherState) None[source]

Set display region and field of view (port of EUVIEW).

Describes where the image goes (device, h1-h2, v1-v2) and what portion of the image plane is displayed (x1-x2, y1-y2). Image plane is at distance 1 from pinhole; e.g. x1=-tan(A/2), x2=tan(A/2) for FOV A radians.

Parameters:
  • device – Display device number recognized by Escher.

  • h1 – Horizontal limits of display region.

  • h2 – Horizontal limits of display region.

  • v1 – Vertical limits of display region.

  • v2 – Vertical limits of display region.

  • x1 – x-coordinate bounds in image plane.

  • x2 – x-coordinate bounds in image plane.

  • y1 – y-coordinate bounds in image plane.

  • y2 – y-coordinate bounds in image plane.

  • euclid_state – Euclid state (initialized if needed).

  • view_state – Escher view state (updated).

  • escher_state – Escher output state (updated).

write_ps_header(state: EscherState) None[source]

Write the PS file header to state.outuni.

Use when output stream is already set (e.g. by caller).

ephemeris_tools.rendering.geometry3d

3D geometry for viewer/tracker.

Ported from euclid: ELLIPS, ECLPMD, FOVCLP, PLELSG, etc.

class EclipseCone(apex: tuple[float, float, float], axis: tuple[float, float, float], half_angle: float)[source]

Bases: object

Eclipse/shadow cone from ellipsoid occulting a spherical source (port of ECLPMD).

apex: tuple[float, float, float]
axis: tuple[float, float, float]
half_angle: float
class EllipseLimb(normal: tuple[float, float, float], major: tuple[float, float, float], minor: tuple[float, float, float], midpt: tuple[float, float, float], can_see: bool)[source]

Bases: object

Observed limb ellipse of a triaxial ellipsoid (port of ELLIPS output).

can_see: bool
major: tuple[float, float, float]
midpt: tuple[float, float, float]
minor: tuple[float, float, float]
normal: tuple[float, float, float]
disk_overlap(center1: Sequence[float], r1: float, center2: Sequence[float], r2: float) bool[source]

Return True if two disks in the plane overlap (port of OVRLAP).

Disks are in the xy-plane; z is ignored. Overlap when distance < r1 + r2.

Parameters:
  • center1 – Center of first disk (x, y [, z]).

  • r1 – Radius of first disk.

  • center2 – Center of second disk.

  • r2 – Radius of second disk.

Returns:

True if disks overlap.

eclipse_model(axes: Sequence[float], center: Sequence[float], source: Sequence[float], radius: float) EclipseCone[source]

Eclipse cone from occulting triaxial ellipsoid and spherical source (port of ECLPMD).

Parameters:
  • axes – Ellipsoid semi-axes (axis1, axis2, axis3) as 3-vectors.

  • center – Center of ellipsoid.

  • source – Position of light source.

  • radius – Radius of spherical source.

Returns:

EclipseCone with apex, axis (unit vector toward dark side), and half_angle.

ellipsoid_limb(axis1: Sequence[float], axis2: Sequence[float], axis3: Sequence[float], center: Sequence[float], view_from: Sequence[float]) EllipseLimb[source]

Limb ellipse of triaxial ellipsoid as seen from view_from (port of ELLIPS).

Parameters:
  • axis1 – Principal axes from center (length = semi-axis length).

  • axis2 – Principal axes from center (length = semi-axis length).

  • axis3 – Principal axes from center (length = semi-axis length).

  • center – Center of ellipsoid.

  • view_from – Viewpoint position.

Returns:

EllipseLimb with normal, major, minor, midpt, and can_see.

fov_clip(x: float, y: float, z: float, cos_fov: float) tuple[float, float, float] | None[source]

Test if point is inside FOV cone about z-axis (port of FOVCLP).

Parameters:
  • x – Point coordinates.

  • y – Point coordinates.

  • z – Point coordinates.

  • cos_fov – Cosine of half-angle of cone.

Returns:

(x, y, z) if point is inside cone (z/r >= cos_fov), else None.

ray_plane_intersect(refpt: Sequence[float], normal: Sequence[float], direction: Sequence[float], origin: Sequence[float] | None = None) tuple[float, float, float] | None[source]

Intersection of ray from origin in direction with plane (port of PLNRAY).

Plane: <normal, x - refpt> = 0.

Parameters:
  • refpt – Point on the plane.

  • normal – Plane normal.

  • direction – Ray direction (need not be unit).

  • origin – Ray origin (default (0,0,0)).

Returns:

Intersection point or None if ray is parallel or hits behind origin.

segment_ellipse_intersect(p1: Sequence[float], p2: Sequence[float], center: Sequence[float], major: Sequence[float], minor: Sequence[float]) list[tuple[float, float, float]][source]

Intersection of segment p1-p2 with ellipse in 3D (port of PLELSG).

Ellipse lies in the plane through center with semi-axes major and minor.

Parameters:
  • p1 – Segment endpoints.

  • p2 – Segment endpoints.

  • center – Center of ellipse.

  • major – Semi-major axis vector.

  • minor – Semi-minor axis vector.

Returns:

List of 0, 1, or 2 intersection points.

ephemeris_tools.rendering.planet_grid

Planet lat/lon grid for viewer (port of Euclid EUBODY meridian/lat curves).

compute_planet_grid(et: float, planet_id: int, center_ra_rad: float, center_dec_rad: float, scale: float, n_meridians: int = 12, n_lats: int = 11) tuple[float, list[tuple[list[tuple[float, float]], Literal['lit', 'dark', 'terminator']]]][source]

Compute limb radius and latitude/longitude grid segments for the planet.

No direct Fortran equivalent; used by viewer to draw planet grid in plot coordinates. Meridians and latitude circles; lit=black, dark=light gray, terminator=black.

Parameters:
  • et – Ephemeris time.

  • planet_id – SPICE planet ID.

  • center_ra_rad – View center (radians).

  • center_dec_rad – View center (radians).

  • scale – Scale factor (plot units per radian).

  • n_meridians – Number of meridian circles.

  • n_lats – Number of latitude circles.

Returns:

(limb_radius_plot, segments). Each segment is (points, line_type) with points in plot coordinates (origin at view center).

ephemeris_tools.rendering.postscript

PostScript output (ported from escher ESDV07, ESCLIP, ESMAP, ESMOVE, ESWRIT).

clip_line(xmin: float, xmax: float, ymin: float, ymax: float, x1: float, y1: float, x2: float, y2: float) tuple[float, float, float, float, bool][source]

Clip line segment to axis-aligned rectangle (port of ESCLIP).

Interior is strict: xmin < x < xmax, ymin < y < ymax.

Parameters:
  • xmin – Rectangle bounds.

  • xmax – Rectangle bounds.

  • ymin – Rectangle bounds.

  • ymax – Rectangle bounds.

  • x1 – First endpoint of segment.

  • y1 – First endpoint of segment.

  • x2 – Second endpoint of segment.

  • y2 – Second endpoint of segment.

Returns:

Tuple (clipped_x1, clipped_y1, clipped_x2, clipped_y2, inside). inside is True if the (possibly clipped) segment has a portion inside the rectangle.

ephemeris_tools.rendering.euclid

Euclid 3D rendering engine (port of FORTRAN Euclid). Public API is exposed from the package; internals are split into submodules: constants, vec_math, ellipse, segment_plane, state, init_geom, body, ring, star_temp, clear.

Euclid 3D rendering engine — Python port of FORTRAN Euclid toolkit.

Introduction

Euclid renders the appearance of a collection of solid ellipsoids illuminated by a number of light sources. The scene is realistic: bodies partially or completely behind others are properly obscured, and shadows cast by bodies onto other bodies are portrayed accurately. In addition to ellipsoids, Euclid can draw elliptical rings, stars, and figures overlaid onto the image plane.

To use Euclid you must have a working copy of Escher — the subroutine package that draws vectors on the display device (here, PostScript via the Escher layer).

Overview

Euclid is an umbrella for entry points that give freedom in composing pictures, analogous to composing a still photograph with a pinhole camera. Main entry points:

  • euinit Turn on the camera (call once per program).

  • euview Choose lens/zoom and film (field of view, device, viewport).

  • eugeom Place camera, subjects, and lighting.

  • euclr Advance the film (clear the drawing region).

  • eubody Shoot and develop one body at a time.

Additional entry points eustar, euring, eutemp allow stars, rings, and temperature/illumination refinements in the image.

Typical usage (single picture):

euinit()
euview(...)
euclr(...)
eugeom(...)
for each body:
    eubody(...)

This package produces segment arrays for the Escher layer (ESDRAW/ESDUMP) so that viewer PostScript matches FORTRAN byte-for-byte.

class EuclidState[source]

Bases: object

Geometry and view state for Euclid (replaces FORTRAN saved variables).

Holds trig tables (from euinit), viewport/FOV (from euview), and scene geometry including limb and terminator data (from eugeom). Passed through eubody, euring, eustar, etc.

eubody(body: int, merids: int, latcir: int, srcreq: int, bright: int, dark: int, term: int, euclid_state: EuclidState, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw one ellipsoid body with terminator and optional grid (port of EUBODY).

Draws the body specified by index (1..nbods from eugeom). Meridians and latitude circles form a coordinate grid; lit/dark/terminator use the given color codes. SRCREQ is the number of lights required to consider a point lit.

Parameters:
  • body – Body index (1-based, must be in range from last eugeom call).

  • merids – Number of meridian circles.

  • latcir – Number of latitude circles.

  • srcreq – Number of light sources required for a point to be lit.

  • bright – Color for lit regions.

  • dark – Color for unlit regions.

  • term – Color for terminator (lit/dark boundary).

  • euclid_state – Euclid state from eugeom/euview.

  • view_state – Escher view state.

  • escher_state – Escher output state.

euclr(device: int, hmin: float, hmax: float, vmin: float, vmax: float, escher_state: EscherState) None[source]

Clear a region of the display (port of EUCLR).

Same argument meanings as EUVIEW. Used for multi-exposure or inset images.

Parameters:
  • device – Display device number.

  • hmin – Horizontal limits of region to clear (must differ, in [0,1]).

  • hmax – Horizontal limits of region to clear (must differ, in [0,1]).

  • vmin – Vertical limits of region to clear (must differ, in [0,1]).

  • vmax – Vertical limits of region to clear (must differ, in [0,1]).

  • escher_state – Escher output state.

eugeom(nlites: int, source: list[list[float]], srcrad: list[float], obsrve: list[float], camfrm: list[list[float]], nbods: int, bodies: list[list[float]], axes: list[list[list[float]]], euclid_state: EuclidState) None[source]

Set scene geometry: lights, camera, bodies; compute limbs/terminators (port of EUGEOM).

Defines illumination sources (positions and radii), camera position and orientation (obsrve, camfrm), and ellipsoid bodies (positions and principal axes). Computes limb ellipses and terminator/eclipse geometry per body/light.

Parameters:
  • nlites – Number of light sources.

  • source – Light positions (list of 3-vectors).

  • srcrad – Light radii.

  • obsrve – Camera (pinhole) position.

  • camfrm – 3x3 camera frame (columns = x, y, z in image plane and toward scene).

  • nbods – Number of bodies.

  • bodies – Body center positions.

  • axes – Body principal axes; axes[i][j] is j-th axis of body i (length = semi-axis).

  • euclid_state – Euclid state (modified in place).

euinit(state: EuclidState) None[source]

Initialize Euclid: compute trig tables and constants (port of EUINIT).

Call once before any other Euclid entry points. Repeated calls have no effect after the first.

Parameters:

state – EuclidState to initialize (modified in place).

euring(ring_center: list[float], major: list[float], minor: list[float], srcreq: int, bright: int, dark: int, euclid_state: EuclidState, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw an elliptical ring (port of EURING).

Ring is a curve only; it does not cast shadows. Lit and dark portions use the given color codes. MAJOR and MINOR are assumed orthogonal (semi-axes).

Parameters:
  • ring_center – Center of the ring (e.g. planet center).

  • major – Semi-major axis vector (direction and length).

  • minor – Semi-minor axis vector (direction and length).

  • srcreq – Number of light sources required to consider a point lit.

  • bright – Color code for lit portion.

  • dark – Color code for unlit portion.

  • euclid_state – Euclid state (from eugeom/euview).

  • view_state – Escher view state.

  • escher_state – Escher output state.

eustar(strpos: tuple[float, float, float], nstars: int, font: list[tuple[tuple[float, float], tuple[float, float]]], fntsiz: int, fntscl: float, color: int, euclid_state: EuclidState, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw star/point markers with a line-segment font (port of EUSTAR).

Characters are scaled by fntscl times the display size so they do not scale with zoom. Font is a list of ((x1,y1),(x2,y2)) segment endpoints.

Parameters:
  • strpos – Position of the point (e.g. star) in scene coordinates.

  • nstars – Number of points (unused; single point drawn).

  • font – Segment list for the marker; font[i] = ((x1,y1), (x2,y2)).

  • fntsiz – Number of segments to use.

  • fntscl – Scale factor (0-1) for marker size vs display.

  • color – Color code for drawing.

  • euclid_state – Euclid state.

  • view_state – Escher view state.

  • escher_state – Escher output state.

eutemp(xbegin: list[float], ybegin: list[float], xend: list[float], yend: list[float], nsegs: int, color: int, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw line-segment overlay on the image plane (port of EUTEMP).

Draws reference marks (e.g. angle scale) in image-plane coordinates. Segment i has start (xbegin[i], ybegin[i]) and end (xend[i], yend[i]).

Parameters:
  • xbegin – x-coordinates of segment starts.

  • ybegin – y-coordinates of segment starts.

  • xend – x-coordinates of segment ends.

  • yend – y-coordinates of segment ends.

  • nsegs – Number of segments.

  • color – Color code for drawing.

  • view_state – Escher view state.

  • escher_state – Escher output state.

euview(device: int, h1: float, h2: float, v1: float, v2: float, x1: float, x2: float, y1: float, y2: float, euclid_state: EuclidState, view_state: EscherViewState, escher_state: EscherState) None[source]

Set display region and field of view (port of EUVIEW).

Describes where the image goes (device, h1-h2, v1-v2) and what portion of the image plane is displayed (x1-x2, y1-y2). Image plane is at distance 1 from pinhole; e.g. x1=-tan(A/2), x2=tan(A/2) for FOV A radians.

Parameters:
  • device – Display device number recognized by Escher.

  • h1 – Horizontal limits of display region.

  • h2 – Horizontal limits of display region.

  • v1 – Vertical limits of display region.

  • v2 – Vertical limits of display region.

  • x1 – x-coordinate bounds in image plane.

  • x2 – x-coordinate bounds in image plane.

  • y1 – y-coordinate bounds in image plane.

  • y2 – y-coordinate bounds in image plane.

  • euclid_state – Euclid state (initialized if needed).

  • view_state – Escher view state (updated).

  • escher_state – Escher output state (updated).

ephemeris_tools.rendering.escher

Escher PostScript output layer (port of FORTRAN Escher). Public API is exposed from the package; internals are split into submodules: constants, state, ps_output, view.

Escher PostScript output layer — Python port of FORTRAN Escher library.

Abstract

Draw segments generated by Euclid. Escher is the device handler for Euclid: it accepts segments (two endpoints and a color) from Euclid, clips them, buffers them internally to reduce I/O, and draws them on the target graphics device (here, PostScript).

Particulars

Escher has several entry points: esview, esdraw, esdump, esclr (and esfile, esopen, esdr07, eslwid, eswrit, esmove, escl07, espl07 for PostScript output). Each is documented in its module. Escher is never called directly as a single routine; call the entry points instead.

This package replicates the exact PostScript output from the FORTRAN esdv07.f, esfile.f, eslwid.f, eswrit.f, esmove.f so that Python viewer output can match FORTRAN byte-for-byte. Coordinate system: 0.1 0.1 scale (1 unit = 0.1 points); all coordinates are integers in this scaled space.

class EscherState[source]

Bases: object

Mutable state for Escher PostScript output (replaces FORTRAN ESCOMM common block).

Holds output file path, stream, last-drawn point (xsave, ysave), and current line width/color for grouping strokes.

class EscherViewState[source]

Bases: object

Viewport, FOV, and segment buffer for Escher (ESVIEW/ESMAP1 state).

Holds device, view (0-1), FOV rectangle, mapping parameters (_ux, _uy, _xcen, _ycen, _pcen, _lcen), and the segment buffer for esdraw/esdump.

escl07(hmin: int, hmax: int, vmin: int, vmax: int, state: EscherState) None[source]

Clear a region of the page or end the page (port of ESCL07).

If the region equals the full page (MINX, MAXX, MINY, MAXY), writes showpage and closes the file (unless external_stream is True). Otherwise draws a white filled rectangle over the region.

Parameters:
  • hmin – Horizontal pixel bounds.

  • hmax – Horizontal pixel bounds.

  • vmin – Vertical line bounds.

  • vmax – Vertical line bounds.

  • state – Escher state (file may be closed on full-page clear).

esclr(device: int, region: tuple[float, float, float, float], escher_state: EscherState) None[source]

Clear a region of the display (port of ESCLR).

Region is (Hmin, Hmax, Vmin, Vmax) in 0-1. Full page clear writes showpage and may close the file (unless external_stream is set).

Parameters:
  • device – Graphics device (unused; kept for API compatibility).

  • region – (Hmin, Hmax, Vmin, Vmax) in 0-1.

  • escher_state – Escher output state.

esdr07(nsegs: int, segs: list[int], state: EscherState) None[source]

Draw buffered segments to PostScript (port of ESDR07).

Groups connected segments with the same color into paths and strokes them. Opens the output file on first call if not already open.

Parameters:
  • nsegs – Number of integers in segs (must be multiple of 5).

  • segs – Flat list of (BP, BL, EP, EL, COLOR) per segment: begin pixel/line, end pixel/line, color code.

  • state – Escher state (file written, xsave/ysave/oldcol updated).

esdraw(begin: tuple[float, float, float], end: tuple[float, float, float], color: int, view_state: EscherViewState, escher_state: EscherState) None[source]

Draw a 3D line segment: project to 2D, clip to FOV, map to device, buffer (port of ESDRAW).

Segments are buffered; when buffer is full they are flushed to PostScript via esdr07. Call esdump to flush remaining segments.

Parameters:
  • begin – Start point (x, y, z) in projection space (z > 0 visible).

  • end – End point (x, y, z).

  • color – Color code for the segment.

  • view_state – View state from esview.

  • escher_state – Escher output state.

esdump(view_state: EscherViewState, escher_state: EscherState) None[source]

Flush segment buffer to PostScript (port of ESDUMP).

Writes all buffered segments via esdr07 and clears the buffer.

Parameters:
  • view_state – View state (segbuf cleared).

  • escher_state – Escher output state.

esfile(filename: str, creator: str, fonts: str, state: EscherState) None[source]

Set PostScript output filename, creator, and document fonts (port of ESFILE).

Does not open the file; opening happens on first write (esopen or esdr07). Resets state (drawn flag, stream handle).

Parameters:
  • filename – Output path for the PostScript file.

  • creator – Creator string for %%Creator.

  • fonts – Document fonts for %%DocumentFonts.

  • state – Escher state (modified in place).

eslwid(points: float, state: EscherState) None[source]

Set line width in points for PostScript output (port of ESLWID).

Writes setlinewidth only when the width changes from the previous call.

Parameters:
  • points – Line width in points (scaled by 10 for internal units).

  • state – Escher state (oldwidth updated).

esmove(state: EscherState) None[source]

Emit PostScript moveto to the end of the last stroked path (port of ESMOVE).

Used to continue drawing from the current point (e.g. for labels).

Parameters:

state – Escher state (xsave, ysave are the last point).

esopen(state: EscherState) None[source]

Open the output file and write PostScript header (port of first-call in ESDR07).

Call after esfile. File is opened on first write if not already open.

Parameters:

state – Escher state (outfil, creator, fonts must be set).

espl07() tuple[int, int, int, int][source]

Return graphics device boundaries in pixel/line (port of ESPL07).

Returns:

Tuple (MINX, MAXX, MINY, MAXY) for the device.

esview(device: int, view: tuple[float, float, float, float], fov: tuple[float, float, float, float], view_state: EscherViewState, escher_state: EscherState) None[source]

Set display device, viewport, and FOV; set up projection mapping (ESVIEW + ESMAP1).

VIEW is the region of the device (0-1 in H and V). FOV is the field of view rectangle in projection space (xmin, xmax, ymin, ymax). Scaling preserves aspect ratio (squares in projection map to squares on device).

Parameters:
  • device – Graphics device number.

  • view – (Hmin, Hmax, Vmin, Vmax) in 0-1.

  • fov – (Xmin, Xmax, Ymin, Ymax) in projection space.

  • view_state – Updated with mapping and segment buffer cleared.

  • escher_state – Escher output state (unused but required for API).

Raises:

ValueError – If FOV has zero width or height.

eswrit(string: str, state: EscherState) None[source]

Write a raw string to the PostScript file (port of ESWRIT).

Adds a newline if the string does not end with one.

Parameters:
  • string – Text to write (e.g. PostScript commands).

  • state – Escher state (outuni must be open).

write_ps_header(state: EscherState) None[source]

Write the PS file header to state.outuni.

Use when output stream is already set (e.g. by caller).

ephemeris_tools.rendering.draw_tracker

Moon tracker PostScript rendering: byte-for-byte identical to rspk_trackmoons.f.

draw_moon_tracks(output: TextIO, planet_num: int, ntimes: int, time1_tai: float, time2_tai: float, dt: float, xrange: float, xscaled: bool, moon_arcsec: list[list[float]], limb_arcsec: list[float], moon_names: list[str], nrings: int, ring_flags: list[bool], ring_rads_km: list[float], ring_grays: list[float], planet_gray: float, rplanet_km: float, title: str, ncaptions: int, lcaptions: list[str], rcaptions: list[str], align_loc: float, filename: str, use_doy_format: bool = False) None[source]

Generate PostScript and table of east-west moon offsets (port of RSPK_TrackMoons).

Time increases downward; west is toward the right. Moon positions are solid lines; rings and planet are gray zones. Title and captions supported.

Parameters:
  • output – PostScript output stream.

  • planet_num – Planet index (4=Mars, 5=Jupiter, etc.).

  • ntimes – Number of time steps.

  • time1_tai – Start and stop TAI (seconds).

  • time2_tai – Start and stop TAI (seconds).

  • dt – Time step (seconds).

  • xrange – Half-range of x-axis (arcsec or planet radii).

  • xscaled – True to use planet radii on x-axis.

  • moon_arcsec – [moon][time] offset in arcsec.

  • limb_arcsec – Limb offset per time.

  • moon_names – Name per moon.

  • nrings – Ring data.

  • ring_flags – Ring data.

  • ring_rads_km – Ring data.

  • ring_grays – Ring data.

  • planet_gray – Planet gray level and radius (km).

  • rplanet_km – Planet gray level and radius (km).

  • title – Title and captions.

  • ncaptions – Title and captions.

  • lcaptions – Title and captions.

  • rcaptions – Title and captions.

  • align_loc – Title and captions.

  • filename – Output filename (for PostScript comments).

  • use_doy_format – True for YYYY-DDD HHh on y-axis (spacecraft).

draw_moon_tracks_arcsec(output: TextIO, planet_num: int, times: list[float], moon_offsets: list[list[float]], limb_rad: float) None[source]

Draw moon tracks with x-axis in arcsec (port of RSPK_TrackMoons in arcsec mode).

Convenience wrapper: builds limb_arcsec from single limb_rad and calls draw_moon_tracks with xscaled=False.

Parameters:
  • output – PostScript output stream.

  • planet_num – Planet index.

  • times – List of TAI times (seconds).

  • moon_offsets – [moon][time] offset in radians (converted to arcsec).

  • limb_rad – Limb radius in radians (used for all times).

draw_moon_tracks_degree(output: TextIO, planet_num: int, times: list[float], moon_offsets: list[list[float]], limb_rad: float) None[source]

Draw moon tracks with x-axis in degrees (port of RSPK_TrackMoonC).

Same as draw_moon_tracks_arcsec but x-axis in degrees; suitable for Cassini-style plots.

ephemeris_tools.rendering.draw_view

Planet viewer PostScript rendering (port of rspk_drawview.f).

Generates PostScript via the Escher/Euclid pipeline to produce output identical to the FORTRAN viewer. The rendering flow mirrors rspk_drawview.f exactly:

  1. PS preamble (font macros, label macros)

  2. Title, captions, credit, axis labels

  3. Camera matrix and EUVIEW

  4. SPICE geometry: observer, planet, Sun, bodies, rings

  5. EUGEOM + EUBODY + EURING drawing

  6. Border box, tick marks, labels

  7. Moon labels, stars

  8. EUCLR

class DrawPlanetaryViewOptions(obs_time: float, fov: float, center_ra: float, center_dec: float, planet_name: str, blank_disks: bool = False, prime_pts: float = 0.0, nmoons: int = 0, moon_flags: list[bool] = <factory>, moon_ids: list[int] = <factory>, moon_names: list[str] = <factory>, moon_labelpts: float = 0.0, moon_diampts: float = 0.0, nrings: int = 0, ring_flags: list[bool] = <factory>, ring_rads: list[float] = <factory>, ring_elevs: list[float] = <factory>, ring_eccs: list[float] = <factory>, ring_incs: list[float] = <factory>, ring_peris: list[float] = <factory>, ring_nodes: list[float] = <factory>, ring_offsets: list[list[float]] = <factory>, ring_opaqs: list[bool] = <factory>, ring_dashed: list[bool] = <factory>, ring_method: int = 0, narcs: int = 0, arc_flags: list[bool] = <factory>, arc_rings: list[int] = <factory>, arc_minlons: list[float] = <factory>, arc_maxlons: list[float] = <factory>, arc_width: float = 4.0, nstars: int = 0, star_ras: list[float] = <factory>, star_decs: list[float] = <factory>, star_names: list[str] = <factory>, star_labels: bool = False, star_diampts: float = 24.0, title: str = '', ncaptions: int = 0, lcaptions: list[str] = <factory>, rcaptions: list[str] = <factory>, align_loc: float = 108.0)[source]

Bases: object

Options for draw_planetary_view (geometry, moons, rings, stars, captions).

align_loc: float = 108.0
arc_flags: list[bool]
arc_maxlons: list[float]
arc_minlons: list[float]
arc_rings: list[int]
arc_width: float = 4.0
blank_disks: bool = False
center_dec: float
center_ra: float
fov: float
lcaptions: list[str]
moon_diampts: float = 0.0
moon_flags: list[bool]
moon_ids: list[int]
moon_labelpts: float = 0.0
moon_names: list[str]
narcs: int = 0
ncaptions: int = 0
nmoons: int = 0
nrings: int = 0
nstars: int = 0
obs_time: float
planet_name: str
prime_pts: float = 0.0
rcaptions: list[str]
ring_dashed: list[bool]
ring_eccs: list[float]
ring_elevs: list[float]
ring_flags: list[bool]
ring_incs: list[float]
ring_method: int = 0
ring_nodes: list[float]
ring_offsets: list[list[float]]
ring_opaqs: list[bool]
ring_peris: list[float]
ring_rads: list[float]
star_decs: list[float]
star_diampts: float = 24.0
star_labels: bool = False
star_names: list[str]
star_ras: list[float]
title: str = ''
camera_matrix(center_ra_rad: float, center_dec_rad: float) list[list[float]][source]

Camera orientation matrix for center (ra, dec) in J2000 (port of RSPK_DrawView).

draw_planetary_view(output: TextIO, options: DrawPlanetaryViewOptions) None[source]

Generate PostScript showing planetary system at a time.

Ported from RSPK_DrawView. Renders planet and moons as triaxial ellipsoids with terminators, optional rings (with vertical offsets and opacity), arcs, and stars. Frame is J2000 (dec up, RA left). Title and captions supported.

Parameters:
  • output – Open text stream for PostScript output.

  • options – Geometry and display options (obs_time, fov, center, planet, moons, rings, arcs, stars, title, captions). See DrawPlanetaryViewOptions.

radec_to_plot(ra_rad: float, dec_rad: float, center_ra_rad: float, center_dec_rad: float, fov_rad: float, cmat: list[list[float]] | None = None) tuple[float, float] | None[source]

Convert (ra, dec) to plot coordinates (x, y) in points. Returns None if behind camera.