On this page:
19.1 The Basic Visual Protocol
visual-path?
visual-target-path
gen:  visual
visual?
visual-id
visual-position
visual-with-position
19.2 Whole-Visual Affine Maps
affine-map
affine-map-visual?
affine-map-visual-content
affine-map-visual-map
19.3 The Affine-Visual Protocol
gen:  affine-visual
affine-visual?
visual-transform
visual-with-transform
visual-rotation
visual-scale
visual-with-rotation
visual-with-scale
19.4 The Opacity-Visual Protocol
opacity?
gen:  opacity-visual
opacity-visual?
visual-opacity
visual-with-opacity
19.5 The Stroke-Width-Visual Protocol
stroke-width?
gen:  stroke-width-visual
stroke-width-visual?
visual-stroke-width
visual-with-stroke-width
19.6 Fill-Color and Stroke-Color Visual Protocols
gen:  fill-color-visual
fill-color-visual?
visual-fill-color
visual-with-fill-color
gen:  stroke-color-visual
stroke-color-visual?
visual-stroke-color
visual-with-stroke-color
19.7 Circle Visuals
circle
circle-visual?
circle-visual-radius
circle-visual-fill
circle-visual-stroke
circle-visual-stroke-width
19.8 Rectangle Visuals
rectangle
rectangle-visual?
rectangle-visual-width
rectangle-visual-height
rectangle-visual-fill
rectangle-visual-stroke
rectangle-visual-stroke-width
19.9 Plain, Multiline, and Rich Text Visuals
text-font-family?
text-font-style?
text-font-weight?
text-horizontal-alignment?
text-vertical-alignment?
text-span
text-span?
text-span-content
text-span-font-size
text-span-font-face
text-span-font-family
text-span-font-style
text-span-font-weight
text-span-color
plain-text
paragraph
rich-text
text-visual?
text-visual-content
text-visual-spans
text-visual-font-size
text-visual-font-face
text-visual-font-family
text-visual-font-style
text-visual-font-weight
text-visual-color
text-visual-horizontal-alignment
text-visual-vertical-alignment
text-visual-width
text-visual-line-spacing
text-visual-line-alignment
text-visual-with-content
text-visual-with-spans
19.10 Numeric Displays
numeric-display-anchor?
format-integer
format-decimal
unit
numeric-unit?
unit-product
format-unit
format-scientific
format-significant
format-rational
format-complex
integer
decimal-number
scientific-number
significant-number
rational-number
complex-number
numeric-label
parameter-display
rolling-number-display
19.11 Matrices and Tables
matrix
matrix-row-id
matrix-column-id
matrix-row-path
matrix-entry-path
matrix-bracket-path
table
table-row-id
table-column-id
table-row-path
table-cell-path
19.12 Deterministic Traced Paths
traced-path
19.13 La  Te  X Formula Visuals
formula-mode?
latex-option?
latex-formula
19.13.1 Making latex-pict Available
formula-visual?
formula-visual-source
formula-visual-mode
formula-visual-font-size
formula-visual-preamble
formula-visual-document-class-options
formula-visual-preview-options
formula-visual-horizontal-alignment
formula-visual-vertical-alignment
formula-visual-with-source
19.14 Tagged Formula Layouts
formula-fragment
tagged-formula
math-tex
glyph-tex
19.15 Source-Addressable Formulas
source-span
source-occurrence
source-part
source-selector?
formula-source-match?
visual-selection?
formula-source
formula-find
formula-source-select
formula-source-select-one
plan-matching-strings
string-match
string-copy
string-match?
string-copy?
string-match-plan?
string-match-plan->datum
transform-matching-strings
formula-part-path
formula-part-copy
formula-part-path?
formula-part-copy?
formula-route?
formula-arc
formula-relative-path
tagged-formula-fragment-visual?
tagged-formula-fragment-visual-svg-source
transform-matching-parts
transform-matching-glyphs
rewrite-formula
formula-step
formula-derivation-step?
formula-derivation
19.16 Named Formula Parts and Correspondence
formula-part
latex-formula-part
formula-assembly
formula-assembly-visual?
formula-assembly-visual-parts
formula-assembly-visual-with-parts
formula-assembly-visual-part-names
formula-assembly-visual-has-part?
formula-assembly-visual-ref
formula-select
formula-style
formula-color
formula-color-map
formula-part-match
formula-correspondence
formula-correspondence-auto
formula-correspondence-unmatched-source-names
formula-correspondence-unmatched-destination-names
19.17 Path Visuals
make-path-visual
path-visual?
path-visual-path
path-visual-fill
path-visual-stroke
path-visual-stroke-width
path-visual-with-path
line
polygon
19.18 Bitmap Images
image
image-visual?
image-visual-source
image-visual-width
image-visual-height
19.19 Full-Fidelity SVG Images
svg-image
svg-image-visual?
svg-image-visual-source
svg-image-visual-width
svg-image-visual-height
19.20 Semantic SVG Import
svg->visual
19.21 Arrow and Cartesian Axes Visuals
19.21.1 Arrows
arrow
arrow-visual?
arrow-visual-length
arrow-visual-stroke
arrow-visual-stroke-width
arrow-visual-tip-length
arrow-visual-tip-width
arrow-visual-start-tip?
arrow-visual-end-tip?
arrow-visual-start
arrow-visual-end
arrow-visual-point-at
19.21.2 Dynamic Endpoint Geometry
anchor-of
line-between
segment-between
arrow-between
ray-from
19.21.3 Mathematical Annotations
arc
dashed-path
dashed-line
angle
right-angle
angle-between
right-angle-between
brace-between
brace
brace-label
curved-arrow-between
surrounding-rectangle
19.21.4 Mathematical Shape Catalogue
ellipse
annulus
sector
regular-polygon
star
rounded-rectangle
arc-between-points
curved-arrow
double-arrow
labeled-point
19.21.5 Axis Ranges
axis-range
axis-range-contains?
axis-range-tick-values
axis-scale?
19.21.6 Cartesian Axes
axes
axes-visual?
axes-visual-x-range
axes-visual-y-range
axes-visual-x-scale
axes-visual-y-scale
axes-visual-x-log-base
axes-visual-y-log-base
axes-visual-x-length
axes-visual-y-length
axes-visual-stroke
axes-visual-stroke-width
axes-visual-tick-size
axes-visual-tip-length
axes-visual-tip-width
axes-visual-x-tip?
axes-visual-y-tip?
axes-x-unit-length
axes-y-unit-length
axes-coordinates->point
axes-point->coordinates
19.22 Linear-Algebra Diagrams
number-plane
number-plane-grid-path
number-plane-axes-path
number-plane-labels-path
vector-arrow
vector-coordinates
vector-label
basis-vectors
linear-transformation-diagram
19.23 Complex and Polar Coordinates
complex->point
point->complex
complex-domain-color
complex-domain-coloring
complex-plane
apply-complex-function
apply-complex-homotopy
polar-coordinate?
polar-coordinate-radius
polar-coordinate-angle
polar->point
point->polar
polar-plane
polar-graph
19.24 Coordinate and Calculus Helpers
graph-point
graph-label
vertical-line-to-graph
horizontal-line-to-graph
tangent-line
secant-line
secant-slope-group
area-under-graph
area-between-curves
riemann-rectangles
19.25 Coordinate Curves and Plots
19.25.1 Interpolation Modes
curve-interpolation?
19.25.2 Sampled Curves and Fields
sample-implicit-path
implicit-curve
vector-field
19.26 Deterministic ODE Flow and Streamlines
ode-state-space
real-ode-state-space
vec2-ode-state-space
vec3-ode-state-space
numeric-vector-ode-state-space
ode-flow-position
adaptive-rk45
adaptive-rk45?
ode-event
ode-event?
ode-trajectory?
prepare-ode-trajectory
ode-trajectory-time-range
ode-trajectory-step-size
ode-trajectory-checkpoint-every
ode-trajectory-solver
ode-trajectory-diagnostics
ode-trajectory-diagnostics?
ode-trajectory-position
streamline-points
streamline
streamlines
flow-particle
sample-function-path
function-graph
sample-adaptive-function-path
adaptive-function-graph
derived-function-graph
19.26.1 Parametric Curves
parameter-range
sample-parametric-path
parametric-curve
19.26.2 Ordered Data Plots
data-series-path
data-plot
19.27 Group Visuals
group
group-visual?
group-visual-children
group-visual-with-children
19.28 First-Class Relation Visuals
relation-visual
relation-context-layout-box
relation-visual?
relation-visual-dependencies
relation-visual-cacheability
relation-dependency?
relation-context?
relation-context-anchor-ref
value-dependency
visual-dependency
anchor-dependency
selection-dependency
scene-validate-relations
scene-relation-report
scene-relation-sample-report
follow-anchor
19.28.1 Acyclic Live Layout
follow-above
follow-below
follow-left-of
follow-right-of
9.3

19 Visuals🔗ℹ

19.1 The Basic Visual Protocol🔗ℹ

procedure

(visual-path? value)  boolean?

  value : any/c
Returns #t for a nonempty list of symbol identities used to address a nested built-in group child, such as '(scatter marker). The first symbol identifies a top-level Visual and each remaining symbol names one child.

procedure

(visual-target-path target)  visual-path?

  target : (or/c visual? symbol? visual-path?)
Converts a top-level Visual or symbol to its one-element path, and returns an existing nested path unchanged.

generic interface

gen:visual : any/c

The generic interface for semantic Visual values. A structure type implements this interface with #:methods in its struct definition. It must implement visual-id, visual-position, and visual-with-position.

procedure

(visual? value)  boolean?

  value : any/c
Returns #t when value implements gen:visual.

procedure

(visual-id visual)  symbol?

  visual : visual?
Returns the stable identity of visual. Scene lookup and animation targeting use this symbol.

A custom Visual implementation must always return a symbol. Immutable update methods must preserve the symbol.

procedure

(visual-position visual)  vec2?

  visual : visual?
Returns the reference position of visual in its containing coordinate system. A top-level Visual uses world coordinates. A child of a group uses coordinates local to that group. For the built-in affine Visuals, the result is the translation component of the affine transform.

procedure

(visual-with-position visual position)  visual?

  visual : visual?
  position : vec2?
Returns a new Visual with position as its reference position in the same containing coordinate system. The result must preserve identity. Built-in Visuals also preserve geometry, style, rotation, scale, opacity, and child order when applicable.

A minimal position-only Visual can be defined as follows:

(struct marker (id position)
  #:transparent
  #:methods gen:visual
  [(define (visual-id value)
     (marker-id value))
   (define (visual-position value)
     (marker-position value))
   (define (visual-with-position value position)
     (struct-copy marker value [position position]))])

Such a Visual can use move-to, but it cannot use rotation or scale animations.

19.2 Whole-Visual Affine Maps🔗ℹ

procedure

(affine-map content map)  affine-map-visual?

  content : visual?
  map : affine2?
Wraps an affine Visual in a general affine map while preserving its stable identity. The Pict adapter applies map’s complete linear component to the semantic subtree; normal scene placement uses its mapped reference point. This makes a group shear or reflect as one coherent diagram.

The wrapper is itself an affine-visual?. It retains a canonical local copy of the subtree plus its full local-to-parent map, which lets ordinary group composition preserve the map and lets descendants remain addressable. This is the semantic bridge used by nested apply-affine requests.

procedure

(affine-map-visual? value)  boolean?

  value : any/c
Returns #t when value is a semantic affine-map wrapper.

procedure

(affine-map-visual-content visual)  visual?

  visual : affine-map-visual?
Returns the canonical local semantic content of visual. Its ordinary decomposed transform is neutral; affine-map-visual-map contains the complete local-to-parent placement.

procedure

(affine-map-visual-map visual)  affine2?

  visual : affine-map-visual?
Returns the current outer general affine map.

19.3 The Affine-Visual Protocol🔗ℹ

generic interface

gen:affine-visual : any/c

The optional generic interface for Visuals that support complete affine transforms. A structure type implementing this interface must provide visual-transform and visual-with-transform. It normally also implements gen:visual.

procedure

(affine-visual? value)  boolean?

  value : any/c
Returns #t when value implements gen:affine-visual.

procedure

(visual-transform visual)  affine-transform?

  visual : affine-visual?
Returns the complete affine transform of visual. Its translation must agree with visual-position. Custom implementations must return an affine-transform? value.

procedure

(visual-with-transform visual transform)  affine-visual?

  visual : affine-visual?
  transform : affine-transform?
Returns a new affine Visual with transform installed. A correct implementation preserves the Visual’s identity, geometry, style, child order, and opacity when those fields apply. The result’s visual-position, visual-rotation, and visual-scale results must agree with the installed transform.

procedure

(visual-rotation visual)  finite-real?

  visual : affine-visual?
Returns the counter-clockwise rotation of visual in radians.

procedure

(visual-scale visual)  vec2?

  visual : affine-visual?
Returns the positive x and y scale factors of visual.

procedure

(visual-with-rotation visual rotation)  affine-visual?

  visual : affine-visual?
  rotation : finite-real?
Returns a new affine Visual with rotation installed. Position, scale, geometry, style, and opacity are preserved.

procedure

(visual-with-scale visual scale)  affine-visual?

  visual : affine-visual?
  scale : scale-factor?
Returns a new affine Visual with scale installed. Position, rotation, geometry, style, child order, and opacity are preserved.

A built-in group or formula assembly accepts only a uniform scale, so its x and y components must be equal. Other built-in affine Visuals, including arrows and axes, accept non-uniform scale.

19.4 The Opacity-Visual Protocol🔗ℹ

procedure

(opacity? value)  boolean?

  value : any/c
Returns #t when value is a finite real number in the closed interval from 0 through 1. Exact and inexact values are accepted. Negative values, values greater than one, infinities, NaN values, and non-real values are rejected.

generic interface

gen:opacity-visual : any/c

The optional generic interface for Visuals that support global opacity. A structure type implementing this interface must provide visual-opacity and visual-with-opacity. It normally also implements gen:visual.

Opacity is semantic model data. Renderers should draw the Visual normally. The Pict adapter applies global opacity after it selects and runs a renderer.

procedure

(opacity-visual? value)  boolean?

  value : any/c
Returns #t when value implements gen:opacity-visual. Implementing this protocol does not require implementing gen:affine-visual.

procedure

(visual-opacity visual)  opacity?

  visual : opacity-visual?
Returns the global opacity of visual. A custom implementation must return a value accepted by opacity?. Animation and rendering adapters validate this result at their boundaries.

procedure

(visual-with-opacity visual opacity)  opacity-visual?

  visual : opacity-visual?
  opacity : opacity?
Returns a new opacity Visual with opacity installed. A correct implementation preserves Visual identity, reference position, geometry, affine transform, style, child order when applicable, and every other semantic field. It must return the requested opacity exactly.

The built-in circle, rectangle, path, arrow, axes, plain-text, formula, formula-assembly, and group Visuals implement this protocol.

A position-only custom Visual can implement opacity as follows:

(struct marker (id position opacity)
  #:transparent
  #:methods gen:visual
  [(define (visual-id value)
     (marker-id value))
   (define (visual-position value)
     (marker-position value))
   (define (visual-with-position value position)
     (struct-copy marker value [position position]))]
  #:methods gen:opacity-visual
  [(define (visual-opacity value)
     (marker-opacity value))
   (define (visual-with-opacity value opacity)
     (struct-copy marker value [opacity opacity]))])

19.5 The Stroke-Width-Visual Protocol🔗ℹ

procedure

(stroke-width? value)  boolean?

  value : any/c
Returns #t when value is a nonnegative finite real number. Exact and inexact values are accepted, including zero. Negative values, infinities, NaN values, and non-real values are rejected. This semantic domain is renderer-independent: alternate renderers may support widths outside the narrower range accepted by the default Pict backend.

generic interface

gen:stroke-width-visual : any/c

The optional generic interface for Visuals with one semantic cosmetic stroke width. A structure type implementing this interface must provide visual-stroke-width and visual-with-stroke-width. It normally also implements gen:visual.

The protocol is renderer-independent model data. Built-in renderers read the stored widths of the Visual types they support; third-party renderers decide how to interpret the width exposed by their own Visual implementations.

procedure

(stroke-width-visual? value)  boolean?

  value : any/c
Returns #t when value implements gen:stroke-width-visual. Implementing this protocol does not require implementing gen:affine-visual or gen:opacity-visual.

procedure

(visual-stroke-width visual)  (and/c finite-real? (>=/c 0))

  visual : stroke-width-visual?
Returns the cosmetic stroke width of visual. A custom implementation must return a value accepted by stroke-width?. Animation compilation validates this result before constructing a stroke-width transition.

procedure

(visual-with-stroke-width visual    
  stroke-width)  stroke-width-visual?
  visual : stroke-width-visual?
  stroke-width : (and/c finite-real? (>=/c 0))
Returns a new stroke-width Visual with stroke-width installed. A correct implementation preserves Visual identity and every semantic field other than stroke width, returns a Visual that still implements the protocol, and installs the requested width exactly, including exact/inexact numeric representation.

The built-in circle, rectangle, path, arrow, axes, number-line, and point-marker Visuals implement this protocol. Coordinate plots and filled areas that are themselves path Visuals participate without a separate plot-animation mechanism. A scatter-plot result is instead a top-level group; its nested point-marker children are not independent scene-state animation targets, so the scatter group does not implement this protocol. A callout’s callout-visual-connector-width is likewise separate frame-space connector style and is not controlled by stroke-width-to.

A position-only custom Visual can opt in independently of affine transforms and opacity:

(struct width-marker (id position stroke-width)
  #:transparent
  #:methods gen:visual
  [(define (visual-id value)
     (width-marker-id value))
   (define (visual-position value)
     (width-marker-position value))
   (define (visual-with-position value position)
     (struct-copy width-marker value [position position]))]
  #:methods gen:stroke-width-visual
  [(define (visual-stroke-width value)
     (width-marker-stroke-width value))
   (define (visual-with-stroke-width value stroke-width)
     (struct-copy width-marker value [stroke-width stroke-width]))])

19.6 Fill-Color and Stroke-Color Visual Protocols🔗ℹ

generic interface

gen:fill-color-visual : any/c

The optional interface for Visuals with a replaceable fill-color slot. A structure type implementing it provides visual-fill-color and visual-with-fill-color. A current slot value may be #f to mean no fill, but SCENE-EC fill-paint interpolation requires the current value to satisfy paint?.

procedure

(fill-color-visual? value)  boolean?

  value : any/c
Returns #t when value implements gen:fill-color-visual.

procedure

(visual-fill-color visual)  any/c

  visual : fill-color-visual?
Returns the Visual’s fill style slot. Built-ins normally return a textual color, an rgba-color, a gradient or pattern paint, or #f. Animation compilation accepts a source for fill-color-to only when this result satisfies paint?.

procedure

(visual-with-fill-color visual color)  fill-color-visual?

  visual : fill-color-visual?
  color : paint?
Returns a Visual with color installed as its fill paint. Correct custom implementations preserve Visual identity and all other semantic fields and install the requested value exactly. For rgba-color endpoints, exactness includes the exact/inexact representation of every channel.

generic interface

gen:stroke-color-visual : any/c

The corresponding optional interface for a replaceable stroke-color slot. It provides visual-stroke-color and visual-with-stroke-color. A current #f stroke means no stroke and is not a SCENE-AT color interpolation source.

procedure

(stroke-color-visual? value)  boolean?

  value : any/c
Returns #t when value implements gen:stroke-color-visual.

procedure

(visual-stroke-color visual)  any/c

  visual : stroke-color-visual?
Returns the Visual’s stroke style slot. stroke-color-to requires the current result to satisfy color-spec?.

procedure

(visual-with-stroke-color visual color)  stroke-color-visual?

  visual : stroke-color-visual?
  color : color-spec?
Returns a Visual with color installed as its stroke color while preserving identity and every unrelated semantic field. The requested style must be installed exactly, including exact/inexact channel representation for rgba-color values.

Circles, rectangles, paths, and point markers implement both protocols. Arrows, axes, and number lines implement the stroke-color protocol. A scatter-plot result is a group whose nested marker children are not independent scene-state targets, so the group itself implements neither color protocol. Callout callout-visual-connector-stroke is separate frame-space connector style and is not controlled by stroke-color-to. The protocols are independent of affine transforms, opacity, and stroke width, so third-party Visuals may opt into either one separately.

19.7 Circle Visuals🔗ℹ

procedure

(circle #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:radius radius    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  circle-visual?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  radius : (and/c finite-real? positive?) = 1
  fill : any/c = "dodgerblue"
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates a semantic circle. The id argument is required and must be a symbol. center, rotation, and scale form its affine transform. The center is in the Visual’s containing coordinate system: world coordinates at the top level and group-local coordinates for a child. radius is measured in local world units before scale is applied.

The built-in Pict renderer treats fill and stroke as color values and stroke-width as a Pict border width. These style values are stored without adapter-specific validation.

Circle Visuals implement gen:visual, gen:affine-visual, gen:opacity-visual, and gen:stroke-width-visual. The opacity value multiplies the complete rendered circle after renderer dispatch.

procedure

(circle-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in circle Visual.

procedure

(circle-visual-radius circle)  (and/c finite-real? positive?)

  circle : circle-visual?
Returns the unscaled local radius in world units.

procedure

(circle-visual-fill circle)  any/c

  circle : circle-visual?
Returns the stored fill style.

procedure

(circle-visual-stroke circle)  any/c

  circle : circle-visual?
Returns the stored stroke style.

procedure

(circle-visual-stroke-width circle)

  (and/c finite-real? (>=/c 0))
  circle : circle-visual?
Returns the stored stroke width.

19.8 Rectangle Visuals🔗ℹ

procedure

(rectangle #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:width width    
  #:height height    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  rectangle-visual?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  width : (and/c finite-real? positive?) = 2
  height : (and/c finite-real? positive?) = 1
  fill : any/c = "goldenrod"
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates a semantic rectangle. The untransformed rectangle is centered at its reference position and is axis-aligned in local coordinates. The center value is in the Visual’s containing coordinate system: world coordinates at the top level and group-local coordinates for a child. Width and height are measured before scale and rotation are applied.

The id argument is required. Style values are stored for an adapter to interpret. Rectangle Visuals implement the basic, affine, opacity, and stroke-width Visual protocols. The opacity value multiplies the complete rendered rectangle.

procedure

(rectangle-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in rectangle Visual.

procedure

(rectangle-visual-width rectangle)

  (and/c finite-real? positive?)
  rectangle : rectangle-visual?
Returns the unscaled local width in world units.

procedure

(rectangle-visual-height rectangle)

  (and/c finite-real? positive?)
  rectangle : rectangle-visual?
Returns the unscaled local height in world units.

procedure

(rectangle-visual-fill rectangle)  any/c

  rectangle : rectangle-visual?
Returns the stored fill style.

procedure

(rectangle-visual-stroke rectangle)  any/c

  rectangle : rectangle-visual?
Returns the stored stroke style.

procedure

(rectangle-visual-stroke-width rectangle)

  (and/c finite-real? (>=/c 0))
  rectangle : rectangle-visual?
Returns the stored stroke width.

19.9 Plain, Multiline, and Rich Text Visuals🔗ℹ

A text Visual stores immutable Unicode content, inline style runs, and explicit font/layout anchors. plain-text preserves the original one-line API; paragraph adds explicit lines and renderer-measured wrapping; and rich-text adds styled spans. Every form implements gen:visual, gen:affine-visual, and gen:opacity-visual. Its raw structure constructor and internal transform and opacity fields are not public.

The reference position is an anchor selected on the untransformed text box. Horizontal alignment chooses its left edge, center, or right edge. Vertical alignment chooses its top edge, center, font baseline, or bottom edge. For a paragraph the baseline is the first rendered line’s baseline. Scale and rotation are applied around that anchor.

procedure

(text-font-family? value)  boolean?

  value : any/c
Returns #t when value is one of the supported portable font family symbols:

'default
'decorative
'roman
'script
'swiss
'modern
'symbol
'system

A family is a portable request, not a promise of one particular installed font face. The drawing backend chooses a suitable platform font.

procedure

(text-font-style? value)  boolean?

  value : any/c
Returns #t for 'normal, 'italic, or 'slant. These are the supported font slant styles.

procedure

(text-font-weight? value)  boolean?

  value : any/c
Returns #t for 'normal, 'bold, or 'light.

procedure

(text-horizontal-alignment? value)  boolean?

  value : any/c
Returns #t for 'left, 'center, or 'right. The value identifies the horizontal part of the text box that is placed at the Visual’s reference position.

procedure

(text-vertical-alignment? value)  boolean?

  value : any/c
Returns #t for 'top, 'center, 'baseline, or 'bottom. The 'baseline choice places the font baseline at the Visual’s reference position.

procedure

(text-span content    
  [#:font-size font-size    
  #:font-face font-face    
  #:font-family font-family    
  #:font-style font-style    
  #:font-weight font-weight    
  #:color color])  text-span?
  content : string?
  font-size : (or/c false/c (and/c finite-real? positive?)) = #f
  font-face : (or/c false/c string?) = #f
  font-family : (or/c false/c text-font-family?) = #f
  font-style : (or/c false/c text-font-style?) = #f
  font-weight : (or/c false/c text-font-weight?) = #f
  color : any/c = #f
Creates one immutable inline rich-text run. A false style keyword inherits the corresponding outer rich-text style. Spans may contain explicit line breaks. They are text only: a formula, image, or another Visual cannot be an inline span in this stage.

procedure

(text-span? value)  boolean?

  value : any/c
Returns #t when value is a built-in immutable text span.

procedure

(text-span-content span)  string?

  span : text-span?
Returns the span’s immutable Unicode source text.

procedure

(text-span-font-size span)

  (or/c false/c (and/c finite-real? positive?))
  span : text-span?
Returns the optional local font size, or #f when it inherits.

procedure

(text-span-font-face span)  (or/c false/c string?)

  span : text-span?
Returns the optional preferred face string.

procedure

(text-span-font-family span)  (or/c false/c text-font-family?)

  span : text-span?
Returns the optional portable font family.

procedure

(text-span-font-style span)  (or/c false/c text-font-style?)

  span : text-span?
Returns the optional font slant.

procedure

(text-span-font-weight span)  (or/c false/c text-font-weight?)

  span : text-span?
Returns the optional font weight.

procedure

(text-span-color span)  any/c

  span : text-span?
Returns the optional adapter colour, or #f when it inherits.

procedure

(plain-text content 
  #:id id 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:font-size font-size 
  #:font-face font-face 
  #:font-family font-family 
  #:font-style font-style 
  #:font-weight font-weight 
  #:color color 
  #:horizontal-alignment horizontal-alignment 
  #:vertical-alignment vertical-alignment]) 
  text-visual?
  content : string?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  font-size : (and/c finite-real? positive?) = 1/2
  font-face : (or/c string? #f) = #f
  font-family : text-font-family? = 'default
  font-style : text-font-style? = 'normal
  font-weight : text-font-weight? = 'normal
  color : any/c = "black"
  horizontal-alignment : text-horizontal-alignment? = 'center
  vertical-alignment : text-vertical-alignment? = 'center
Creates a semantic one-line text Visual. The required id is its stable Visual identity. center is the selected text anchor in the containing coordinate system. At the top level it is a world-space point; inside a group it is local to that group.

content may be empty and may contain arbitrary Unicode characters, but it may not contain a carriage return or newline. The constructor copies the string into immutable storage. A mutable font-face string is copied in the same way. A false font-face asks the backend to select a face from font-family. When both are supplied, the face is preferred and the family remains the fallback classification.

font-size is measured in local world units before the Visual’s scale is applied. The default is one half world unit. Non-uniform scale may stretch the rendered text independently in x and y. Rotation is counter-clockwise in radians.

color is deliberately opaque model data. The built-in Pict renderer passes it to Pict color handling. A different renderer may interpret it differently. opacity is semantic global opacity and is applied to the complete rendered line after renderer dispatch.

The alignment arguments determine which point of the original text box is at center. Alignment is resolved before scale and rotation. This makes a left-baseline label, for example, grow to the right and rotate around the start of its baseline.

procedure

(paragraph content 
  #:id id 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:font-size font-size 
  #:font-face font-face 
  #:font-family font-family 
  #:font-style font-style 
  #:font-weight font-weight 
  #:color color 
  #:horizontal-alignment horizontal-alignment 
  #:vertical-alignment vertical-alignment 
  #:width width 
  #:line-spacing line-spacing 
  #:line-alignment line-alignment]) 
  text-visual?
  content : string?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  font-size : (and/c finite-real? positive?) = 1/2
  font-face : (or/c string? #f) = #f
  font-family : text-font-family? = 'default
  font-style : text-font-style? = 'normal
  font-weight : text-font-weight? = 'normal
  color : any/c = "black"
  horizontal-alignment : text-horizontal-alignment? = 'center
  vertical-alignment : text-vertical-alignment? = 'center
  width : (or/c false/c (and/c finite-real? positive?)) = #f
  line-spacing : (and/c finite-real? positive?) = 1
  line-alignment : text-horizontal-alignment? = 'left
Creates one ordinary multiline text Visual. Carriage-return, newline, and CRLF sequences are explicit line breaks. With a false width, only those explicit breaks create lines. Otherwise, width is a positive local world-space maximum: at rendering time Animate measures text runs with the active camera/font backend and wraps at inter-word whitespace. It does not hyphenate an overlong word.

line-spacing multiplies the largest natural line height in the paragraph. line-alignment aligns every resolved line inside the widest resolved line, while horizontal-alignment selects the anchor of that complete paragraph. The first line supplies a 'baseline anchor.

procedure

(rich-text #:id id 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:font-size font-size 
  #:font-face font-face 
  #:font-family font-family 
  #:font-style font-style 
  #:font-weight font-weight 
  #:color color 
  #:horizontal-alignment horizontal-alignment 
  #:vertical-alignment vertical-alignment 
  #:width width 
  #:line-spacing line-spacing 
  #:line-alignment line-alignment] 
  piece ...) 
  text-visual?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  font-size : (and/c finite-real? positive?) = 1/2
  font-face : (or/c string? #f) = #f
  font-family : text-font-family? = 'default
  font-style : text-font-style? = 'normal
  font-weight : text-font-weight? = 'normal
  color : any/c = "black"
  horizontal-alignment : text-horizontal-alignment? = 'center
  vertical-alignment : text-vertical-alignment? = 'center
  width : (or/c false/c (and/c finite-real? positive?)) = #f
  line-spacing : (and/c finite-real? positive?) = 1
  line-alignment : text-horizontal-alignment? = 'left
  piece : (or/c string? text-span?)
Creates a paragraph layout from ordinary strings and text-span values. Strings inherit all outer font properties. A span overrides only its specified properties. The wrapping, line-spacing, and anchor rules are the same as for paragraph. Adjacent spans are separately shaped Pict runs, so a font backend cannot kern or ligate across their boundary.

procedure

(text-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in plain, paragraph, or rich text Visual.

procedure

(text-visual-content visual)  string?

  visual : text-visual?
Returns the immutable concatenation of the Visual’s source text spans. It can contain explicit line breaks; automatic wrapping does not alter this source.

procedure

(text-visual-spans visual)  (listof text-span?)

  visual : text-visual?
Returns the significant ordered immutable rich-text spans. A plain-text or paragraph Visual contains one inheriting span.

procedure

(text-visual-font-size visual)  (and/c finite-real? positive?)

  visual : text-visual?
Returns the unscaled font size in local world units.

procedure

(text-visual-font-face visual)  (or/c string? #f)

  visual : text-visual?
Returns the preferred immutable font-face string, or #f when no face was requested. Font availability and exact substitution are properties of the rendering environment, not the semantic model.

procedure

(text-visual-font-family visual)  text-font-family?

  visual : text-visual?
Returns the portable fallback font-family symbol.

procedure

(text-visual-font-style visual)  text-font-style?

  visual : text-visual?
Returns the stored font slant style.

procedure

(text-visual-font-weight visual)  text-font-weight?

  visual : text-visual?
Returns the stored font weight.

procedure

(text-visual-color visual)  any/c

  visual : text-visual?
Returns the stored adapter color value.

Returns the horizontal anchor alignment.

Returns the vertical anchor alignment.

procedure

(text-visual-width visual)

  (or/c false/c (and/c finite-real? positive?))
  visual : text-visual?
Returns the requested local world-space wrapping width, or #f when only explicit line breaks determine lines.

procedure

(text-visual-line-spacing visual)

  (and/c finite-real? positive?)
  visual : text-visual?
Returns the multiplicative resolved-line advance.

Returns the alignment used inside the resolved paragraph width.

procedure

(text-visual-with-content visual content)  text-visual?

  visual : text-visual?
  content : string?
Returns a new text Visual with content installed as one inheriting immutable span. Identity, affine transform, opacity, font data, colour, and layout options are preserved. Explicit line breaks are accepted; the original Visual is unchanged.

procedure

(text-visual-with-spans visual spans)  text-visual?

  visual : text-visual?
  spans : (listof text-span?)
Returns a new text Visual with spans installed atomically. Outer font defaults and all layout/anchor settings are preserved. The content accessor of the result is the immutable concatenation of the supplied spans.

19.10 Numeric Displays🔗ℹ

SCENE-EF provides number-shaped text and numerical transitions without introducing a mutable value tracker. Static constructors return ordinary text-visual? values. parameter-display and rolling-number-display format the current scalar scene parameter independently at each sampled frame. Both are fixed-structure relation-visual? values with an explicit scalar dependency.

procedure

(numeric-display-anchor? value)  boolean?

  value : any/c
Recognizes 'left, 'center, 'right, 'decimal, and 'sign.

procedure

(format-integer value    
  [#:grouping? grouping?    
  #:show-sign? show-sign?    
  #:unit unit])  string?
  value : exact-integer?
  grouping? : boolean? = #f
  show-sign? : boolean? = #f
  unit : string? = ""
Formats an exact integer with an optional leading plus sign, comma grouping, and trailing literal unit. For example, (format-integer -1234567 #:grouping? #t) returns "-1,234,567".

procedure

(format-decimal value    
  [#:decimal-places decimal-places    
  #:grouping? grouping?    
  #:show-sign? show-sign?    
  #:unit unit])  string?
  value : finite-real?
  decimal-places : exact-nonnegative-integer? = 2
  grouping? : boolean? = #f
  show-sign? : boolean? = #f
  unit : string? = ""
Formats a finite real with exactly decimal-places fractional digits, rounding once before the integral and fractional fields are separated. It keeps trailing zeroes. The procedure raises an exception if multiplying the magnitude by its requested decimal factor would overflow.

procedure

(unit symbol [#:power power])  numeric-unit?

  symbol : string?
  power : exact-integer? = 1
Creates one semantic upright unit factor. power must be nonzero. Negative powers represent denominator factors; for example, (unit "s" #:power -2) formats as "s⁻²".

procedure

(numeric-unit? value)  boolean?

  value : any/c
Recognizes an immutable semantic unit created by unit or unit-product.

procedure

(unit-product first rest ...)  numeric-unit?

  first : numeric-unit?
  rest : numeric-unit?
Concatenates unit factors in declared order. This is display data, not a dimension-calculation system.

procedure

(format-unit value)  string?

  value : (or/c string? numeric-unit?)
Returns a literal unit unchanged or turns semantic factors into Unicode upright text, such as "m·s⁻²".

procedure

(format-scientific value    
  [#:significant-figures figures    
  #:show-sign? show-sign?    
  #:unit unit])  string?
  value : finite-real?
  figures : exact-positive-integer? = 3
  show-sign? : boolean? = #f
  unit : (or/c string? numeric-unit?) = ""
Formats a normalized decimal mantissa and a signed ASCII e exponent. It uses ordinary text rather than typeset exponent geometry so it remains stable in every supported text renderer.

procedure

(format-significant value    
  [#:significant-figures figures    
  #:notation notation    
  #:grouping? grouping?    
  #:show-sign? show-sign?    
  #:unit unit])  string?
  value : finite-real?
  figures : exact-positive-integer? = 3
  notation : (or/c 'auto 'fixed 'scientific) = 'auto
  grouping? : boolean? = #f
  show-sign? : boolean? = #f
  unit : (or/c string? numeric-unit?) = ""
Rounds to a requested number of significant figures. 'auto selects scientific notation for large values and values below 0.001.

procedure

(format-rational value    
  [#:max-denominator maximum    
  #:mixed? mixed?    
  #:show-sign? show-sign?    
  #:unit unit])  string?
  value : finite-real?
  maximum : exact-positive-integer? = 1000
  mixed? : boolean? = #f
  show-sign? : boolean? = #f
  unit : (or/c string? numeric-unit?) = ""
Chooses the nearest fraction among positive denominators through maximum, then reduces it. This gives legible deterministic output for inexact animated samples; it is not symbolic rational arithmetic.

procedure

(format-complex value    
  [#:decimal-places decimal-places    
  #:grouping? grouping?    
  #:show-sign? show-sign?    
  #:imaginary-unit imaginary-unit    
  #:unit unit])  string?
  value : (or/c finite-real? finite-complex?)
  decimal-places : exact-nonnegative-integer? = 2
  grouping? : boolean? = #f
  show-sign? : boolean? = #f
  imaginary-unit : string? = "i"
  unit : (or/c string? numeric-unit?) = ""
Formats Cartesian components as, for example, "3.00 - 0.50i". There is deliberately no polar or symbolic simplification mode.

procedure

(integer value 
  #:id id 
  [#:center center 
  #:font-size font-size 
  #:font-family font-family 
  #:font-style font-style 
  #:font-weight font-weight 
  #:color color 
  #:horizontal-alignment horizontal-alignment 
  #:vertical-alignment vertical-alignment 
  #:grouping? grouping? 
  #:show-sign? show-sign? 
  #:unit unit]) 
  text-visual?
  value : exact-integer?
  id : symbol?
  center : vec2? = origin
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'default
  font-style : text-font-style? = 'normal
  font-weight : text-font-weight? = 'normal
  color : any/c = "black"
  horizontal-alignment : text-horizontal-alignment? = 'center
  vertical-alignment : text-vertical-alignment? = 'center
  grouping? : boolean? = #f
  show-sign? : boolean? = #f
  unit : string? = ""
Creates an ordinary one-line integer display. Its placement and text styling have the same meaning as for plain-text.

procedure

(decimal-number value 
  #:id id 
  [#:center center 
  #:font-size font-size 
  #:font-family font-family 
  #:font-style font-style 
  #:font-weight font-weight 
  #:color color 
  #:horizontal-alignment horizontal-alignment 
  #:vertical-alignment vertical-alignment 
  #:decimal-places decimal-places 
  #:grouping? grouping? 
  #:show-sign? show-sign? 
  #:unit unit]) 
  text-visual?
  value : finite-real?
  id : symbol?
  center : vec2? = origin
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'default
  font-style : text-font-style? = 'normal
  font-weight : text-font-weight? = 'normal
  color : any/c = "black"
  horizontal-alignment : text-horizontal-alignment? = 'center
  vertical-alignment : text-vertical-alignment? = 'center
  decimal-places : exact-nonnegative-integer? = 2
  grouping? : boolean? = #f
  show-sign? : boolean? = #f
  unit : string? = ""
Creates a fixed-place decimal display. In contrast to the generic numeric-label, an exact integer still receives the requested decimal point and trailing zeroes here.

procedure

(scientific-number value 
  #:id id 
  [#:center center 
  #:significant-figures figures 
  #:unit unit 
  #:font-size font-size 
  #:font-family font-family 
  #:color color]) 
  text-visual?
  value : finite-real?
  id : symbol?
  center : vec2? = origin
  figures : exact-positive-integer? = 3
  unit : (or/c string? numeric-unit?) = ""
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'default
  color : any/c = "black"
Creates a static label using format-scientific.

procedure

(significant-number value 
  #:id id 
  [#:center center 
  #:significant-figures figures 
  #:notation notation 
  #:unit unit 
  #:font-size font-size 
  #:font-family font-family 
  #:color color]) 
  text-visual?
  value : finite-real?
  id : symbol?
  center : vec2? = origin
  figures : exact-positive-integer? = 3
  notation : (or/c 'auto 'fixed 'scientific) = 'auto
  unit : (or/c string? numeric-unit?) = ""
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'default
  color : any/c = "black"
Creates a static label using format-significant.

procedure

(rational-number value    
  #:id id    
  [#:center center    
  #:max-denominator maximum    
  #:mixed? mixed?    
  #:unit unit    
  #:font-size font-size    
  #:font-family font-family    
  #:color color])  text-visual?
  value : finite-real?
  id : symbol?
  center : vec2? = origin
  maximum : exact-positive-integer? = 1000
  mixed? : boolean? = #f
  unit : (or/c string? numeric-unit?) = ""
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'default
  color : any/c = "black"
Creates a static label using format-rational.

procedure

(complex-number value    
  #:id id    
  [#:center center    
  #:decimal-places decimal-places    
  #:imaginary-unit imaginary-unit    
  #:unit unit    
  #:font-size font-size    
  #:font-family font-family    
  #:color color])  text-visual?
  value : (or/c finite-real? finite-complex?)
  id : symbol?
  center : vec2? = origin
  decimal-places : exact-nonnegative-integer? = 2
  imaginary-unit : string? = "i"
  unit : (or/c string? numeric-unit?) = ""
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'default
  color : any/c = "black"
Creates a static Cartesian-complex label using format-complex.

procedure

(numeric-label value 
  #:id id 
  [#:center center 
  #:kind kind 
  #:decimal-places decimal-places 
  #:significant-figures figures 
  #:notation notation 
  #:max-denominator maximum 
  #:mixed? mixed? 
  #:grouping? grouping? 
  #:show-sign? show-sign? 
  #:imaginary-unit imaginary-unit 
  #:unit unit 
  #:font-size font-size 
  #:font-family font-family 
  #:font-style font-style 
  #:font-weight font-weight 
  #:color color 
  #:horizontal-alignment horizontal-alignment 
  #:vertical-alignment vertical-alignment]) 
  text-visual?
  value : (or/c finite-real? finite-complex?)
  id : symbol?
  center : vec2? = origin
  kind : 
(or/c 'auto 'integer 'decimal 'scientific
      'significant 'rational 'complex)
 = 'auto
  decimal-places : exact-nonnegative-integer? = 2
  figures : exact-positive-integer? = 3
  notation : (or/c 'auto 'fixed 'scientific) = 'auto
  maximum : exact-positive-integer? = 1000
  mixed? : boolean? = #f
  grouping? : boolean? = #f
  show-sign? : boolean? = #f
  imaginary-unit : string? = "i"
  unit : (or/c string? numeric-unit?) = ""
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'default
  font-style : text-font-style? = 'normal
  font-weight : text-font-weight? = 'normal
  color : any/c = "black"
  horizontal-alignment : text-horizontal-alignment? = 'center
  vertical-alignment : text-vertical-alignment? = 'center
At 'auto, creates integer output for an exact integer, fixed decimal output for another finite real, and Cartesian output for a finite complex value. The explicit #:kind choices select every SCENE-EF formatter.

procedure

(parameter-display source 
  #:id id 
  [#:center center 
  #:kind kind 
  #:decimal-places decimal-places 
  #:significant-figures figures 
  #:notation notation 
  #:max-denominator maximum 
  #:mixed? mixed? 
  #:grouping? grouping? 
  #:show-sign? show-sign? 
  #:imaginary-unit imaginary-unit 
  #:unit unit 
  #:anchor anchor 
  #:font-size font-size 
  #:font-family font-family 
  #:font-style font-style 
  #:font-weight font-weight 
  #:color color 
  #:vertical-alignment vertical-alignment]) 
  relation-visual?
  source : (or/c symbol? scene-parameter?)
  id : symbol?
  center : vec2? = origin
  kind : 
(or/c 'integer 'decimal 'scientific 'significant
      'rational 'complex)
   = 'decimal
  decimal-places : exact-nonnegative-integer? = 2
  figures : exact-positive-integer? = 3
  notation : (or/c 'auto 'fixed 'scientific) = 'auto
  maximum : exact-positive-integer? = 1000
  mixed? : boolean? = #f
  grouping? : boolean? = #f
  show-sign? : boolean? = #f
  imaginary-unit : string? = "i"
  unit : (or/c string? numeric-unit?) = ""
  anchor : numeric-display-anchor? = 'right
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'default
  font-style : text-font-style? = 'normal
  font-weight : text-font-weight? = 'normal
  color : any/c = "black"
  vertical-alignment : text-vertical-alignment? = 'center
Reads source from each sampled scene state and formats its finite real or Cartesian-complex value. A 'decimal display has exactly its requested decimal places; an 'integer display rounds a finite real to the nearest integer. Scientific, significant, rational, and complex kinds use the correspondingly named formatter. The source must be installed with scene-set-value before the relation is resolved. Its dependency and built-in serializable specification are inspectable with relation-visual-dependencies and relation-visual-cacheability. Because the display has fixed child structure, its decimal 'whole and 'fraction paths remain addressable as its value changes.

The #:anchor choice fixes one stable reference as the text width changes. 'left, 'center, and 'right are the normal text anchors. 'sign forces a visible sign and anchors its left edge. 'decimal creates a small resolved group containing local 'whole and 'fraction children on opposite sides of the fixed decimal point. They are separate text runs, so this first release does not attempt kerning across that join.

procedure

(rolling-number-display 
  source 
  #:id id 
  [#:center center 
  #:integer-digits integer-digits 
  #:decimal-places decimal-places 
  #:show-sign? show-sign? 
  #:unit unit 
  #:anchor anchor 
  #:font-size font-size 
  #:font-family font-family 
  #:font-style font-style 
  #:font-weight font-weight 
  #:color color 
  #:vertical-alignment vertical-alignment]) 
  derived-visual?
  source : (or/c symbol? scene-parameter?)
  id : symbol?
  center : vec2? = origin
  integer-digits : exact-positive-integer? = 3
  decimal-places : exact-nonnegative-integer? = 0
  show-sign? : boolean? = #f
  unit : (or/c string? numeric-unit?) = ""
  anchor : numeric-display-anchor? = 'right
  font-size : (and/c finite-real? positive?) = 1/2
  font-family : text-font-family? = 'modern
  font-style : text-font-style? = 'normal
  font-weight : text-font-weight? = 'normal
  color : any/c = "black"
  vertical-alignment : text-vertical-alignment? = 'center
Creates a fixed-slot odometer-style display. The source must produce a nonnegative finite real smaller than (expt 10 integer-digits). Each slot clips its current and next glyphs and rolls in the last tenth of its digit interval before a carry. The result is calculated directly from the sampled number, including at a frame rendered out of order; it stores no bitmap or prior numeric state. Digit advances use a nominal monospaced width, so a font with tabular figures gives the best alignment.

19.11 Matrices and Tables🔗ℹ

matrix and table return ordinary immutable group-visual? values. Their rows and cells are regular nested groups, not a separate rendering or animation object. Existing path-addressed operations therefore work directly: (indicate (matrix-entry-path 'A 1 2)), move-to, follow-anchor, and transform-from-copy need no matrix/table variants.

Both constructors take a nonempty rectangular list of nonempty rows. Each entry must be an affine Visual. The constructor re-bases every entry at its cell centre, preserving identity, rotation, scale, opacity, style, and children but intentionally replacing its supplied reference position. Width and height can be one shared measure, one explicit per-axis list, or an 'auto construction-time measurement. The result is still an ordinary immutable group with no renderer dependency after construction.

procedure

(matrix rows    
  #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:entry-width entry-width    
  #:entry-height entry-height    
  #:entry-padding entry-padding    
  #:column-gap column-gap    
  #:row-gap row-gap    
  #:brackets? brackets?    
  #:bracket-width bracket-width    
  #:bracket-gap bracket-gap    
  #:stroke stroke    
  #:stroke-width stroke-width])  group-visual?
  rows : (listof (listof (and/c visual? affine-visual?)))
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  entry-width : 
(or/c 'auto (and/c finite-real? positive?)
      (listof (and/c finite-real? positive?)))
   = 1
  entry-height : 
(or/c 'auto (and/c finite-real? positive?)
      (listof (and/c finite-real? positive?)))
   = 1
  entry-padding : (and/c finite-real? (>=/c 0)) = 1/5
  column-gap : (and/c finite-real? (>=/c 0)) = 1/4
  row-gap : (and/c finite-real? (>=/c 0)) = 1/4
  brackets? : boolean? = #t
  bracket-width : (and/c finite-real? positive?) = 1/5
  bracket-gap : (and/c finite-real? (>=/c 0)) = 1/10
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates an immutable matrix grid. Rows are named 'row-1, 'row-2, and so on; a row’s cells are named 'col-1, 'col-2, and so on. Thus a matrix named 'A exposes its second entry in the first row at '(A row-1 col-2). Equal 'col-1 names in different rows are permitted because their complete paths differ.

When brackets? is true, the matrix has ordinary open path children named 'left-bracket and 'right-bracket. They use square brackets, stroke, and stroke-width.

For either entry dimension, a positive scalar supplies one shared cell extent; a list supplies one extent per column or row; and 'auto measures each entry with the active default Pict renderer and selects the largest visible-box extent in that column or row. entry-padding is added on both sides of each auto-sized extent. This is a snapshot: later text/formula changes do not reflow a constructed matrix.

procedure

(matrix-row-id row)  symbol?

  row : exact-positive-integer?
Returns the local row identity, such as 'row-2.

procedure

(matrix-column-id column)  symbol?

  column : exact-positive-integer?
Returns the local column identity, such as 'col-2.

procedure

(matrix-row-path matrix-id row)  visual-path?

  matrix-id : symbol?
  row : exact-positive-integer?
Returns the row’s stable nested path, such as '(A row-2).

procedure

(matrix-entry-path matrix-id row column)  visual-path?

  matrix-id : symbol?
  row : exact-positive-integer?
  column : exact-positive-integer?
Returns the cell group’s stable nested path, such as '(A row-2 col-1). It does not require a matrix value at construction time, which makes it useful in independently declared animation requests.

procedure

(matrix-bracket-path matrix-id side)  visual-path?

  matrix-id : symbol?
  side : (or/c 'left 'right)
Returns the path for the selected square-bracket child.

procedure

(table rows    
  #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:cell-width cell-width    
  #:cell-height cell-height    
  #:cell-padding cell-padding    
  #:column-gap column-gap    
  #:row-gap row-gap    
  #:stroke stroke    
  #:stroke-width stroke-width])  group-visual?
  rows : (listof (listof (and/c visual? affine-visual?)))
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  cell-width : 
(or/c 'auto (and/c finite-real? positive?)
      (listof (and/c finite-real? positive?)))
   = 1
  cell-height : 
(or/c 'auto (and/c finite-real? positive?)
      (listof (and/c finite-real? positive?)))
   = 3/4
  cell-padding : (and/c finite-real? (>=/c 0)) = 1/5
  column-gap : (and/c finite-real? (>=/c 0)) = 0
  row-gap : (and/c finite-real? (>=/c 0)) = 0
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates an immutable grid table. Its row/cell names use the same 'row-N/'col-N convention as matrix. Shared grid boundaries are ordinary child paths named 'grid-column-0, 'grid-column-1, and so on, followed by 'grid-row-0, 'grid-row-1, and so on. Each boundary is drawn once, avoiding doubled cell-border strokes.

The cell-size arguments follow the same scalar/list/'auto policy as matrix. Auto measurement adds cell-padding on all sides and does not remeasure after construction.

procedure

(table-row-id row)  symbol?

  row : exact-positive-integer?
Returns the table’s local 'row-N identity.

procedure

(table-column-id column)  symbol?

  column : exact-positive-integer?
Returns the table’s local 'col-N identity.

procedure

(table-row-path table-id row)  visual-path?

  table-id : symbol?
  row : exact-positive-integer?
Returns the row’s stable table path.

procedure

(table-cell-path table-id row column)  visual-path?

  table-id : symbol?
  row : exact-positive-integer?
  column : exact-positive-integer?
Returns the cell group’s stable table path, such as '(results row-2 col-3).

19.12 Deterministic Traced Paths🔗ℹ

procedure

(traced-path phase 
  position 
  #:id id 
  [#:start-time start-time 
  #:sample-count sample-count 
  #:trail-length trail-length 
  #:dissipate? dissipate? 
  #:minimum-opacity minimum-opacity 
  #:opacity opacity 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  derived-visual?
  phase : (or/c symbol? scene-parameter?)
  position : (-> derived-context? finite-real? vec2?)
  id : symbol?
  start-time : finite-real? = 0
  sample-count : (and/c exact-integer? (>=/c 2)) = 121
  trail-length : (or/c false/c (and/c finite-real? (>=/c 0)))
   = #f
  dissipate? : boolean? = #f
  minimum-opacity : opacity? = 0
  opacity : opacity? = 1
  stroke : any/c = "crimson"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Creates a locus from an explicit scalar scene value. At every sampled frame, Animate calls position at deterministically spaced times from start-time to the current value of phase. Therefore a frame at time t is independent of previously rendered frames; this is unlike a mutable frame-history trail. The procedure receives the same read-only derived context as other derived Visuals and must return a vec2 for every sampled time.

With trail-length, the interval instead begins at the larger of start-time and current phase minus that length. With dissipate?, the resolved trace is an ordinary group of consecutive path segments whose opacity rises from minimum-opacity to opacity; otherwise it is one ordinary path Visual. No automatic tracking of arbitrary Visual motion or adaptive/discontinuity sampling is attempted in this stage.

19.13 LaTeX Formula Visuals🔗ℹ

A formula Visual stores an immutable LaTeX mathematical snippet and explicit typesetting data. It implements gen:visual, gen:affine-visual, and gen:opacity-visual. Its raw structure constructor and internal transform and opacity fields are not public.

Formula model values are backend-independent. They do not contain Picts, PDF pages, Poppler values, process handles, or cached TeX results. The built-in adapter calls latex-pict only when a nonempty formula is rendered.

procedure

(formula-mode? value)  boolean?

  value : any/c
Returns #t when value is one of the supported formula modes:

'inline
'display
'display-environment

The 'inline mode uses ordinary inline mathematics. The 'display mode uses display-style mathematics in a tight inline box. The 'display-environment mode uses a real LaTeX display environment, which can include wider horizontal margins.

procedure

(latex-option? value)  boolean?

  value : any/c
Returns #t when value is a symbol or string accepted as one ordered LaTeX option. Mutable strings satisfy this predicate; constructors copy them into immutable model storage.

procedure

(latex-formula 
  source 
  #:id id 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:mode mode 
  #:font-size font-size 
  #:preamble preamble 
  #:document-class-options document-class-options 
  #:preview-options preview-options 
  #:horizontal-alignment horizontal-alignment 
  #:vertical-alignment vertical-alignment]) 
  formula-visual?
  source : string?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  mode : formula-mode? = 'display
  font-size : (and/c finite-real? positive?) = 1
  preamble : string? = ""
  document-class-options : (listof latex-option?) = '()
  preview-options : (listof latex-option?) = '()
  horizontal-alignment : text-horizontal-alignment? = 'center
  vertical-alignment : text-vertical-alignment? = 'center
Creates a semantic mathematical formula Visual. The required id is its stable Visual identity. center is the selected formula anchor in the containing coordinate system. At the top level it is a world-space point; inside a group it is local to that group.

source is a LaTeX mathematical snippet without surrounding dollar signs, \\( ... \\), or \\[ ... \\] delimiters. The selected mode supplies those delimiters. Formula source may contain carriage returns and newlines. It may also be empty. The constructor copies it into an immutable string.

The mode-to-typesetter mapping is:

Mode

latex-pict operation

'inline

tex-math

'display

tex-display-math

'display-environment

tex-real-display-math

The font-size value is measured in local world units before semantic scale is applied. The adapter asks latex-pict to typeset at its natural scale and then maps the selected document base of 10pt, 11pt, or 12pt to the requested world-unit size. When no standard size option is present, 10pt is assumed. Supplying more than one distinct standard size option is an error. Other document-class options and preamble commands may still change the formula’s visible metrics.

The complete visible height and width depend on the formula content. The constructor does not automatically separate two independent formula Visuals, so their rendered boxes can overlap when their anchors are placed too close together. Use visual-layout-box, visual-place-above, visual-place-below, or arrange-visuals-vertically when spacing must follow the actual rendered boxes.

preamble is inserted into the generated LaTeX document. The document-class-options and preview-options lists are passed in stored order. Their strings and preamble are copied into immutable storage. Option order is significant because a LaTeX document class or package may interpret options in order. The adapter passes these values and an extra typesetter scale of one explicitly, so process-wide latex-pict parameters do not silently change a formula Visual.

The alignment arguments select the left, center, or right horizontal point and the top, center, baseline, or bottom vertical point of the untransformed typeset Pict. That point is placed at center. Scale and rotation are then applied around the anchor.

Named parts in a formula-assembly can be styled with formula-style, formula-color, or formula-color-map. This is an assembly-level semantic operation: a bare latex-formula has no part namespace. The Pict and tagged-SVG adapters apply the selected colour at their own rendering boundaries rather than relying on a generic outer recolouring operation.

Rendering a nonempty formula requires the latex-pict package, a working pdflatex, Poppler, the requested document class, and every package named by the preamble. Model construction, scene sampling, and empty formula rendering do not run TeX. Exact output depends on those external tools and their installed versions. Formula source and preamble are trusted input; this library does not sandbox the TeX process.

19.13.1 Making latex-pict Available🔗ℹ

Use the same Racket installation for this library and for latex-pict. For example, to install the catalog package with Racket 9.3.0.2 on macOS:

"/Applications/Racket v9.3.0.2/bin/raco" pkg install \

  --auto \

  latex-pict

For a local checkout, link the checkout with that same raco executable:

"/Applications/Racket v9.3.0.2/bin/raco" pkg install \

  --auto \

  --link \

  "/Users/soegaard/Dropbox/GitHub/latex-pict"

A one-command alternative is to add the checkout root to PLTCOLLECTS:

PLTCOLLECTS="/Users/soegaard/Dropbox/GitHub/latex-pict:" \

  "/Applications/Racket v9.3.0.2/bin/racket" -c \

  examples/formula-visuals.rkt \

  frames/formula-visuals \

  formula-visuals.mp4

The trailing colon is significant. It keeps Racket’s ordinary collection paths after the added checkout. A package linked with one Racket installation is not automatically visible to another installation, so use matching racket and raco executables.

procedure

(formula-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in LaTeX formula Visual.

procedure

(formula-visual-source visual)  string?

  visual : formula-visual?
Returns the immutable LaTeX source string without surrounding mathematical delimiters.

procedure

(formula-visual-mode visual)  formula-mode?

  visual : formula-visual?
Returns the stored formula display mode.

procedure

(formula-visual-font-size visual)

  (and/c finite-real? positive?)
  visual : formula-visual?
Returns the unscaled semantic formula font size in local world units.

procedure

(formula-visual-preamble visual)  string?

  visual : formula-visual?
Returns the immutable additional LaTeX preamble string.

Returns the ordered document-class options. String options are immutable. Ordering is significant.

procedure

(formula-visual-preview-options visual)

  (listof latex-option?)
  visual : formula-visual?
Returns the ordered options passed to the LaTeX Preview package by latex-pict. String options are immutable. The mode-specific option used by latex-pict is added by that package separately.

Returns the horizontal formula-anchor alignment.

Returns the vertical formula-anchor alignment.

procedure

(formula-visual-with-source visual source)  formula-visual?

  visual : formula-visual?
  source : string?
Returns a new formula Visual with source copied into immutable model storage. Identity, affine transform, opacity, mode, font size, preamble, ordered option lists, and alignment are preserved. The original Visual is unchanged. Multiline and empty source are accepted.

19.14 Tagged Formula Layouts🔗ℹ

struct

(struct formula-fragment (name source)
    #:transparent)
  name : symbol?
  source : string?
Represents one author-declared contiguous TeX fragment. name is the local part name in a tagged-formula; source must be a nonempty string. Names must be unique within each tagged formula.

Fragments are deliberately explicit. Animate does not parse arbitrary TeX into tokens, so a fragment must be a valid piece of the complete math expression and must produce visible ink.

procedure

(tagged-formula 
  #:id id 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:mode mode 
  #:font-size font-size 
  #:preamble preamble 
  #:document-class-options document-class-options 
  #:color-map color-map] 
  fragment ...) 
  formula-assembly-visual?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  mode : formula-mode? = 'display
  font-size : (and/c finite-real? positive?) = 1
  preamble : string? = ""
  document-class-options : (listof latex-option?) = '()
  color-map : (hash/c symbol? color-spec?) = (hash)
  fragment : formula-fragment?
Builds one full-layout formula from one or more formula-fragment values. Unlike formula-assembly, the fragments are typeset together. Their positions, ordinary TeX spacing, kerning, scripts, and alignment come from the complete formula rather than from manually supplied part positions.

Construction runs the external latex and dvisvgm executables once. It wraps every fragment in a dvisvgm SVG group, measures the group, and returns an ordinary formula assembly whose parts render as the resulting SVG fragments. Those SVG fragments are renderer-cached, so sampling or rendering animation frames does not run TeX again. Both executables must be available on PATH when this constructor is called.

All keyword options have the same validation and semantic meaning as for latex-formula, except that Preview-package options and per-fragment anchors are not applicable to a formula whose layout is computed as one unit. The returned assembly can be moved, rotated, scaled, faded, addressed through nested part paths, and used with the normal formula-correspondence operations.

color-map maps declared fragment names to semantic colours. It is applied after the complete TeX layout and SVG crops have been created, so it does not alter kerning, scripts, or measurements. Every key must name a declared fragment.

procedure

(math-tex #:id id 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:mode mode 
  #:font-size font-size 
  #:preamble preamble 
  #:document-class-options document-class-options 
  #:color-map color-map 
  #:source-map source-map 
  #:parts parts] 
  source ...) 
  formula-assembly-visual?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  mode : formula-mode? = 'display
  font-size : (and/c finite-real? positive?) = 1
  preamble : string? = ""
  document-class-options : (listof latex-option?) = '()
  color-map : (hash/c symbol? color-spec?) = (hash)
  source-map : (or/c 'none 'declared 'tokens) = 'tokens
  parts : (listof source-part?) = '()
  source : string?
Source-addressable construction for one complete formula. It accepts the same layout and color-map options as tagged-formula. Use tagged-formula when the author needs explicit stable part names without source queries.

math-tex records a canonical source string and a conservative token-to-rendered-part source map by default. Use formula-find or formula-source-select to query rendered source material by a literal string, regexp, source span, or occurrence. 'none is the explicit opt-out when no source queries are required. 'declared requires #:parts, a list of named source-part declarations; it maps only those author-declared ranges. The token scanner establishes safe TeX boundaries, not algebraic meaning or a complete TeX parse: user macros, category-code changes, and source that has no visible output may not be selectable.

procedure

(glyph-tex #:id id 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:mode mode 
  #:font-size font-size 
  #:preamble preamble 
  #:document-class-options document-class-options 
  #:color-map color-map] 
  source ...) 
  formula-assembly-visual?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  mode : formula-mode? = 'display
  font-size : (and/c finite-real? positive?) = 1
  preamble : string? = ""
  document-class-options : (listof latex-option?) = '()
  color-map : (hash/c symbol? color-spec?) = (hash)
  source : string?
Typesets one complete TeX expression and exposes each visible dvisvgm glyph leaf as a formula part named 'glyph-0, 'glyph-1, and so on, in painter order. The complete expression is still typeset as one unit, so its ordinary TeX spacing, kerning, and script placement are retained. Construction has the same external latex and dvisvgm requirements as tagged-formula.

The generated glyph parts retain the complete author TeX source, but their matching identity is the referenced dvisvgm path outline together with their typesetting options. Consequently, exact unchanged glyphs can match between two separately compiled expressions despite dvisvgm assigning different local font-definition ids on each compilation. Use tagged-formula or math-tex when several glyphs need one semantic identity: glyph leaves are not TeX tokens, a superscript or accent can contain several leaves, and repeated outlines match greedily in source order.

color-map maps generated names such as 'glyph-0 to semantic colours. Generated names are positional, so explicit tagged fragments are usually preferable for durable pedagogical styling.

19.15 Source-Addressable Formulas🔗ℹ

Source selectors address character ranges in the canonical TeX source retained by math-tex. They complement named formula fragments; they do not recognize algebraic roles or prove mathematical equivalence. Source indices are Racket string-character indices in half-open ranges, so (source-span 2 5) selects characters 2 through 4.

struct

(struct source-span (start end))

  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer?
Represents one half-open source range. It is checked against the formula’s canonical source when used.

struct

(struct source-occurrence (selector index))

  selector : source-selector?
  index : exact-nonnegative-integer?
Selects the zero-based occurrence of a literal-string, regexp, or source-span selector.

struct

(struct source-part (name selector))

  name : symbol?
  selector : source-selector?
Gives a declared source selector one stable author-facing name. This is used by math-tex with #:source-map 'declared.

procedure

(source-selector? value)  boolean?

  value : any/c
Recognizes a literal string, regexp, source-span, source-occurrence, or declared source-part selector.

procedure

(formula-source-match? value)  boolean?

  value : any/c
Recognizes one immutable source-map unit. Its source span, canonical text, stable name, and mapped leaf paths can be inspected with the corresponding accessors.

procedure

(visual-selection? value)  boolean?

  value : any/c
Recognizes an immutable root-relative selection of existing Visual leaves. Selections describe semantic paths; they are not synthetic group Visuals.

procedure

(formula-source formula)  string?

  formula : formula-assembly-visual?
Returns the immutable canonical source string retained by a source-mapped formula. For several math-tex source arguments, arguments are joined by one literal space; that separator is part of the documented coordinate system. A formula constructed with #:source-map 'none raises an error.

procedure

(formula-find formula selector)  (listof formula-source-match?)

  formula : formula-assembly-visual?
  selector : source-selector?
Returns every mapped source occurrence in source order. A string matches non-overlapping occurrences from left to right; a regexp may not match an empty range. An unmatched query produces the empty list.

procedure

(formula-source-select formula selector)  visual-selection?

  formula : formula-assembly-visual?
  selector : source-selector?
Returns the immutable selection of all leaves mapped by selector. The selection is a query result, not a new scene Visual. It may therefore be used for read-only selection operations and formula styling, but not as a target for replacement, removal, or arbitrary movement. It raises an error when no mapped rendered leaf is selected.

procedure

(formula-source-select-one formula    
  selector)  visual-selection?
  formula : formula-assembly-visual?
  selector : source-selector?
Like formula-source-select, but requires exactly one matched source occurrence.

procedure

(plan-matching-strings source    
  destination    
  [#:matches matches    
  #:copies copies])  string-match-plan?
  source : formula-assembly-visual?
  destination : formula-assembly-visual?
  matches : (listof string-match?) = '()
  copies : (listof string-copy?) = '()
Plans a deterministic source-addressed correspondence without rendering it. Explicit string-match declarations take precedence; remaining equal normalized source material is matched in source order. The resulting plan can be inspected with string-match-plan->datum, then animated with transform-matching-strings. Changed material uses the requested fade or fade-transform policy; unmatched material fades. This is syntactic matching, not symbolic algebra or a general TeX parser.

procedure

(string-match 
  source 
  destination 
  [#:route route 
  #:mode mode 
  #:appearance-complete-at-x appearance-complete-at-x 
  #:appearance-duration appearance-duration]) 
  string-match?
  source : source-selector?
  destination : source-selector?
  route : (or/c #f formula-route?) = #f
  mode : (or/c 'auto 'rigid 'glyphwise 'cross-fade) = 'auto
  appearance-complete-at-x : (or/c #f source-selector?) = #f
  appearance-duration : (or/c #f (and/c finite-real? positive? (<=/c 1)))
   = #f
Declares one source-addressed correspondence. Explicit declarations take priority over automatic normalized-source matching.

When both appearance keywords are supplied, the part keeps its ordinary route, but its changed appearance completes when that route first reaches the current x-coordinate of appearance-complete-at-x. The duration is a fraction of the enclosing transition: the old and new appearances cross-fade only in the interval immediately preceding that deadline. This is useful for a moving + that should become - exactly as it passes an equality sign.

procedure

(string-copy source    
  destination    
  [#:route route    
  #:mode mode])  string-copy?
  source : source-selector?
  destination : source-selector?
  route : (or/c #f formula-route?) = #f
  mode : (or/c 'auto 'rigid 'glyphwise 'cross-fade) = 'auto
Declares a moving copy: the source remains present while an otherwise unmatched destination is introduced.

procedure

(string-match? value)  boolean?

  value : any/c
Recognizes an explicit string correspondence.

procedure

(string-copy? value)  boolean?

  value : any/c
Recognizes an explicit string copy.

procedure

(string-match-plan? value)  boolean?

  value : any/c
Recognizes an immutable deterministic match plan.

procedure

(string-match-plan->datum plan)  immutable-hash?

  plan : string-match-plan?
Returns a transparent diagnostic representation of the planner’s matches, unmatched material, routes, and decision reasons.

procedure

(transform-matching-strings 
  source 
  destination 
  [#:matches matches 
  #:key-map key-map 
  #:protect-source protect-source 
  #:protect-destination protect-destination 
  #:copies copies 
  #:on-ambiguity on-ambiguity 
  #:path-arc path-arc 
  #:mismatch-mode mismatch-mode]) 
  transform-formula-parts-request?
  source : formula-assembly-visual?
  destination : formula-assembly-visual?
  matches : (listof string-match?) = '()
  key-map : (listof string-match?) = '()
  protect-source : (listof source-selector?) = '()
  protect-destination : (listof source-selector?) = '()
  copies : (listof string-copy?) = '()
  on-ambiguity : (or/c 'left-to-right 'error) = 'left-to-right
  path-arc : finite-real? = 0
  mismatch-mode : (or/c 'fade 'fade-transform) = 'fade
Plans source-addressed formula correspondences then compiles them into the normal deterministic formula transition. It matches source structure, not algebraic meaning or arbitrary rendered glyph similarity. The compiled plan is retained for the preview String matching inspector.

procedure

(formula-part-path source-name    
  destination-name    
  route)  formula-part-path?
  source-name : symbol?
  destination-name : symbol?
  route : formula-route?
Declares an explicit route for one named formula-part correspondence.

procedure

(formula-part-copy source-name    
  destination-name    
  route)  formula-part-copy?
  source-name : symbol?
  destination-name : symbol?
  route : formula-route?
Declares a copy from one source part to an otherwise unmatched destination part.

procedure

(formula-part-path? value)  boolean?

  value : any/c
Recognizes a formula-part route declaration.

procedure

(formula-part-copy? value)  boolean?

  value : any/c
Recognizes a formula-part copy declaration.

procedure

(formula-route? value)  boolean?

  value : any/c
Recognizes a supported formula-motion route such as a circular formula-arc or a unit-chord formula-relative-path.

procedure

(formula-arc #:angle angle)  formula-route?

  angle : finite-real?
Creates a circular formula-motion route. Positive angles travel counter-clockwise in the formula’s local coordinate system; zero is straight.

procedure

(formula-relative-path geometry)  formula-route?

  geometry : path-geometry?
Creates a custom route in unit-chord coordinates. The path must start at (vec2 0 0) and end at (vec2 1 0).

procedure

(tagged-formula-fragment-visual? value)  boolean?

  value : any/c
Returns #t for a generated fragment Visual inside a tagged formula. The subtype is also a formula-visual?.

Returns the immutable SVG source used to render one generated tagged fragment. This is provided for inspection and renderer integration; construct fragments through tagged-formula, not by manufacturing this renderer detail.

procedure

(transform-matching-parts source 
  destination 
  [#:matches matches]) 
  transform-formula-parts-request?
  source : formula-assembly-visual?
  destination : formula-assembly-visual?
  matches : (listof formula-part-match?) = '()
Builds a correspondence transform in the style of Manim’s matching formula transitions. Explicit matches have priority. Animate then automatically pairs every remaining source fragment with the first still-unmatched destination fragment that has exactly the same formula source and typesetting options, in source order.

Exact matches render as one rigid SVG group that moves with its local transform. Changed explicit matches are moving cross-fades, and unmatched fragments use the normal fade-out/fade-in behavior. This operation does not infer algebraic equivalence, parse TeX tokens, choose paths/arcs for the movement, or morph glyph outlines.

procedure

(transform-matching-glyphs source 
  destination 
  [#:matches matches 
  #:path-arc path-arc 
  #:part-paths part-paths 
  #:copies copies 
  #:mismatch-mode mismatch-mode 
  #:changed-mode changed-mode]) 
  transform-formula-parts-request?
  source : formula-assembly-visual?
  destination : formula-assembly-visual?
  matches : (listof formula-part-match?) = '()
  path-arc : finite-real? = 0
  part-paths : (listof formula-part-path?) = '()
  copies : (listof formula-part-copy?) = '()
  mismatch-mode : (or/c 'fade 'fade-transform) = 'fade
  changed-mode : (or/c 'fade 'morph) = 'fade
Builds the glyph-level counterpart to transform-matching-parts. Both assemblies must have been produced by glyph-tex. Exact dvisvgm path outlines pair automatically in source order; use matches for a deliberate changed glyph, such as mapping the generated plus-sign part to the destination minus-sign part. The remaining keywords have the same meanings as for transform-matching-parts.

This matches and moves whole rendered glyph leaves. 'fade is the default: changed matches use the ordinary moving cross-fade. With #:changed-mode 'morph, a changed matched pair instead interpolates its outline only when both cropped dvisvgm SVG fragments expand to one identically painted path whose positive-length contours are all closed and compatible in count. Animate globally pairs those destination contours with the source, phase-aligns them without reversing their traversal, normalizes the resulting paths to compatible cubic segments, and uses that path geometry only for interior frames; the ordinary tagged SVG fragments remain exact endpoints. Glyphs with multiple independently painted paths, open contours, incompatible contour topology, changed paint, or unsupported geometry safely fall back to the moving cross-fade.

This operation does not derive a mathematical operation, identify TeX characters or terms, perform semantic grouping, or infer which changed glyphs should be paired.

procedure

(rewrite-formula source 
  destination 
  #:anchor anchor 
  [#:matches matches 
  #:stationary stationary 
  #:path-arc path-arc 
  #:part-paths part-paths 
  #:copies copies 
  #:mismatch-mode mismatch-mode]) 
  transform-formula-parts-request?
  source : formula-assembly-visual?
  destination : formula-assembly-visual?
  anchor : (or/c symbol? formula-part-match?)
  matches : (listof formula-part-match?) = '()
  stationary : (listof (or/c symbol? formula-part-match?)) = '()
  path-arc : finite-real? = 0
  part-paths : (listof formula-part-path?) = '()
  copies : (listof formula-part-copy?) = '()
  mismatch-mode : (or/c 'fade 'fade-transform) = 'fade
Builds a matching formula transition with one fixed named anchor. Pass a symbol such as 'equals when the part has the same name at both endpoints, or a formula-part-match when its names differ. The anchor is made an explicit match; a conflicting value in matches raises an error.

When scene-play compiles the request, Animate translates the complete destination layout so the destination anchor coincides with the corresponding part in the current source formula. Consequently, a sequence of rewrites keeps the anchor fixed even when the formula values passed as earlier templates were constructed at their own default positions. The translation preserves the target formula’s TeX spacing and baselines.

Each stationary entry names an additional matched pair: a symbol means the same source and destination part name, while a formula-part-match permits different names. The pair is made explicit, and at clip compilation the destination fragment receives the current source fragment’s exact affine transform. Thus several selected terms can remain fixed even if the rest of the destination layout moves or reflows. This is an explicit presentation choice; it does not infer which terms should remain still or maintain a general layout constraint between them.

The remaining keywords have the same meaning as in transform-matching-parts: explicit matches take priority, routes and copies select intentional term motion, and 'fade-transform cross-fades remaining unmatched parts while moving them. Like the lower-level operation, this is whole-fragment correspondence rather than TeX parsing or glyph-outline morphing.

procedure

(formula-step destination 
  [#:anchor anchor 
  #:stationary stationary 
  #:matches matches 
  #:path-arc path-arc 
  #:part-paths part-paths 
  #:copies copies 
  #:mismatch-mode mismatch-mode 
  #:duration duration 
  #:pause pause 
  #:explanation explanation]) 
  formula-derivation-step?
  destination : formula-assembly-visual?
  anchor : (or/c false/c symbol? formula-part-match?) = #f
  stationary : (listof (or/c symbol? formula-part-match?)) = '()
  matches : (listof formula-part-match?) = '()
  path-arc : finite-real? = 0
  part-paths : (listof formula-part-path?) = '()
  copies : (listof formula-part-copy?) = '()
  mismatch-mode : (or/c 'fade 'fade-transform) = 'fade
  duration : (and/c finite-real? positive?) = 1
  pause : (and/c finite-real? (>=/c 0)) = 1/2
  explanation : (or/c false/c string?) = #f
Describes one explicit rewrite endpoint for formula-derivation. The destination and rewrite keywords have the same meanings as rewrite-formula. pause is the amount of time to hold the optional explanation before this step’s transition begins. An explanation must be one line of plain text.

anchor defaults to #f, which means that the derivation’s shared anchor is used. A step can override it with a same-name symbol or an explicit formula-part-match. stationary has the same meaning as in rewrite-formula and makes additional matched parts fixed for this one step. This data does not claim that the rewrite is algebraically valid; it records the author’s chosen presentation.

procedure

(formula-derivation-step? value)  boolean?

  value : any/c
Returns #t when value was created by formula-step.

procedure

(formula-derivation 
  scene 
  initial 
  #:anchor anchor 
  #:steps steps 
  [#:explanation-position explanation-position 
  #:explanation-id explanation-id 
  #:explanation-font-size explanation-font-size 
  #:explanation-color explanation-color]) 
  scene?
  scene : scene?
  initial : formula-assembly-visual?
  anchor : (or/c symbol? formula-part-match?)
  steps : (listof formula-derivation-step?)
  explanation-position : (or/c false/c vec2?) = #f
  explanation-id : symbol? = 'derivation-note
  explanation-font-size : (and/c finite-real? positive?) = 1/4
  explanation-color : any/c = "darkslategray"
Appends an ordered derivation to scene. initial must already be present in the scene under its formula identity. For each steps entry, the builder first replaces its own optional explanation label, waits for that step’s pause, and then appends a rewrite-formula clip with the requested duration and correspondence options. The resulting endpoint becomes the construction template for the next step, while every rewrite still resolves its anchor from the current sampled scene formula.

When any step has an explanation, supply explanation-position. The builder creates plain text with explanation-id, which must be absent from the initial scene. Later explanations replace only that generated Visual. The final explanation remains visible unless a later step omits it.

This is immutable convenience syntax over existing scene and formula APIs. It does not parse TeX, infer operations, prove a derivation, choose matches/routes, or automatically lay out the explanation.

19.16 Named Formula Parts and Correspondence🔗ℹ

A formula assembly is a composite Visual made from independently typeset LaTeX formula parts. Each part has a symbol name. That name is local to one assembly and is also the identity of the part’s formula Visual.

Part order is significant back-to-front drawing order. Part positions are local to the assembly anchor. The library does not ask TeX to lay out several parts as one document. The caller chooses each local position explicitly. Parts can overlap when their local anchors are placed too close together.

struct

(struct formula-part (name formula)
    #:transparent)
  name : symbol?
  formula : formula-visual?
Represents one named formula fragment.

The name field is local to one formula assembly. The formula field contains the complete semantic formula Visual used to render the fragment. The structure guard requires (eq? name (visual-id formula)). This rule gives each local name one stable formula identity.

The formula transform and opacity are local to its containing assembly. The structure is immutable and transparent.

procedure

(latex-formula-part 
  source 
  #:name name 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:mode mode 
  #:font-size font-size 
  #:preamble preamble 
  #:document-class-options document-class-options 
  #:preview-options preview-options 
  #:horizontal-alignment horizontal-alignment 
  #:vertical-alignment vertical-alignment]) 
  formula-part?
  source : string?
  name : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  mode : formula-mode? = 'display
  font-size : (and/c finite-real? positive?) = 1
  preamble : string? = ""
  document-class-options : (listof latex-option?) = '()
  preview-options : (listof latex-option?) = '()
  horizontal-alignment : text-horizontal-alignment? = 'center
  vertical-alignment : text-vertical-alignment? = 'center
Creates a formula-part and its formula Visual in one step. name becomes both formula-part-name and the formula Visual identity. Every other argument has the same meaning and validation as the corresponding argument to latex-formula.

The center value is local to the formula assembly that will contain the part. Formula source, preamble, and string options are copied into immutable model storage.

Example:

(latex-formula-part "n(n+1)"
                    #:name 'numerator
                    #:center (vec2 0 1/2)
                    #:mode 'inline
                    #:font-size 1/3)

procedure

(formula-assembly parts 
  #:id id 
  [#:center center 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity]) 
  formula-assembly-visual?
  parts : (listof formula-part?)
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
Creates a semantic formula assembly. The parts list is stored in significant back-to-front order. An empty list creates a valid empty assembly.

Part names must be unique within the assembly. Because every part name is also its formula Visual identity, id must differ from every part name. Part names are local: two different assemblies may use the same names.

The assembly center is its reference position in the containing coordinate system. The assembly rotation is measured counter-clockwise in radians. Its own scale must be uniform after normalization. This is the same restriction used by group; a non-uniform parent scale followed by a rotated part can require shear, which the current transform model cannot represent. Individual formula parts may still use non-uniform local scales.

The assembly implements gen:visual, gen:affine-visual, and gen:opacity-visual. Existing movement, rotation, uniform scale, opacity, fade-in, and fade-out operations therefore work on the complete assembly.

Every nonempty part is typeset separately. The caller is responsible for local part spacing. The Pict adapter passes the same explicit renderer list to every part. A custom renderer placed before the defaults may instead support and replace the complete assembly. An empty assembly renders as stable transparent one-pixel local geometry without running TeX.

procedure

(formula-assembly-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in formula assembly Visual.

procedure

(formula-assembly-visual-parts assembly)

  (listof formula-part?)
  assembly : formula-assembly-visual?
Returns the assembly’s parts in significant back-to-front order. The returned list is immutable model data.

procedure

(formula-assembly-visual-with-parts assembly 
  parts) 
  formula-assembly-visual?
  assembly : formula-assembly-visual?
  parts : (listof formula-part?)
Returns a new assembly with parts as its significant ordered part list. Assembly identity, reference position, rotation, uniform scale, and opacity are preserved. The same name and identity checks as formula-assembly are performed. The original assembly is unchanged.

procedure

(formula-assembly-visual-part-names assembly)

  (listof symbol?)
  assembly : formula-assembly-visual?
Returns local part names in significant back-to-front order.

procedure

(formula-assembly-visual-has-part? assembly    
  name)  boolean?
  assembly : formula-assembly-visual?
  name : symbol?
Returns #t when assembly contains a part named name. This operation searches the local part namespace; it does not search the top-level scene state.

procedure

(formula-assembly-visual-ref assembly name)  formula-part?

  assembly : formula-assembly-visual?
  name : symbol?
Returns the part named name. An exception is raised when the local name is absent. The result is a formula-part, so use formula-part-formula to obtain its formula Visual.

procedure

(formula-select formula name)  visual-path?

  formula : formula-assembly-visual?
  name : symbol?
Returns the ordinary nested Visual path for a known named formula part. For an assembly named 'equation, selecting 'x returns '(equation x). The result can be passed directly to nested operations such as indicate, circumscribe, and fill-color-to. An exception is raised when name is absent.

procedure

(formula-style formula    
  selection    
  [#:color color    
  #:opacity opacity])  formula-assembly-visual?
  formula : formula-assembly-visual?
  selection : (or/c symbol? (and/c pair? (listof symbol?)))
  color : (or/c false/c color-spec?) = #f
  opacity : (or/c false/c opacity?) = #f
Immutably applies the supplied colour, opacity, or both to one named formula part or a nonempty list of distinct names. At least one style keyword is required. Every name is checked before any replacement is made, so a misspelled name cannot produce a partially styled assembly.

The new assembly preserves its identity, part order, formula source, TeX/SVG artifact, and ordinary transforms. Its selected formula leaves implement the existing fill-colour and opacity protocols. Equal styles therefore retain normal rigid matching motion; a paint change between formula-rewrite endpoints uses the established cross-fade fallback.

procedure

(formula-color formula selection color)

  formula-assembly-visual?
  formula : formula-assembly-visual?
  selection : (or/c symbol? (and/c pair? (listof symbol?)))
  color : color-spec?
Colour-only shorthand for formula-style.

procedure

(formula-color-map formula color-map)  formula-assembly-visual?

  formula : formula-assembly-visual?
  color-map : (hash/c symbol? color-spec?)
Applies one colour to each key named by color-map. The empty map returns an equivalent immutable assembly. This is also the operation used by the #:color-map keywords of tagged-formula, math-tex, and glyph-tex.

struct

(struct formula-part-match (source-name destination-name)
    #:transparent)
  source-name : symbol?
  destination-name : symbol?
Represents one manually chosen source-to-destination part match.

source-name names a part in a source assembly. destination-name names a part in a destination assembly. The structure itself checks only that both fields are symbols. A formula-correspondence checks that the names exist and are used one-to-one.

struct

(struct formula-correspondence (source destination matches)
    #:transparent)
  source : formula-assembly-visual?
  destination : formula-assembly-visual?
  matches : (listof formula-part-match?)
Represents a validated manual mapping between two formula assemblies.

The source and destination fields store the exact immutable assembly values used when the correspondence is created. The matches field is stored in significant caller order.

Construction checks all of the following:

  • Every source name exists in source.

  • Every destination name exists in destination.

  • A source name appears at most once.

  • A destination name appears at most once.

The match list may be empty. Equal names are not matched automatically. Parts omitted from matches remain explicitly unmatched. The list order is also the order of matched transition layers created by transform-formula-parts.

procedure

(formula-correspondence-auto source 
  destination) 
  formula-correspondence?
  source : formula-assembly-visual?
  destination : formula-assembly-visual?
Builds a deterministic correspondence for unchanged formula parts. Each source part is considered in source order and matches the first still-unmatched destination part with the same LaTeX source and typesetting options. This allows stable part names to change without losing unchanged semantic content. Parts without a match remain unmatched and follow the ordinary fade-out/fade-in transition behavior.

procedure

(formula-correspondence-unmatched-source-names correspondence)

  (listof symbol?)
  correspondence : formula-correspondence?
Returns source part names that do not occur in any match. The result preserves the source assembly’s significant part order.

procedure

(formula-correspondence-unmatched-destination-names correspondence)

  (listof symbol?)
  correspondence : formula-correspondence?
Returns destination part names that do not occur in any match. The result preserves the destination assembly’s significant part order.

A formula correspondence stores endpoint templates. It does not store sampled transition layers. Those layers are compiled when transform-formula-parts is passed to scene-play, so the operation can use the current formulas, local transforms, and local opacities from the scene.

19.17 Path Visuals🔗ℹ

A path Visual combines local path-geometry with identity, affine placement, fill, stroke, and cosmetic stroke width. Its geometry may contain line segments, cubic Bézier segments, or both. It implements gen:visual, gen:affine-visual, and gen:opacity-visual.

The Visual’s reference position is the translation component of its affine transform. Its path points remain local model data. Scale and rotation are applied around the local origin before the Visual is translated to its reference position.

procedure

(make-path-visual path    
  #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  path : path-geometry?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  fill : any/c = #f
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates a semantic path Visual from local path geometry. The id argument is required. center is the Visual’s reference position in its containing coordinate system. It is a world-space point at the top level and a group-local point when the Visual is a child. Rotation is measured counter-clockwise in radians, and scale is applied to local x and y coordinates before rotation. opacity is global and is applied to the complete rendered path after renderer dispatch.

The built-in Pict renderer interprets a false fill as transparent and a false stroke as no outline. Other style values are passed to the Racket drawing backend as color values. Stroke width is cosmetic and measured in output pixels; semantic scale does not multiply it.

Empty path geometry is accepted and produces a transparent one-pixel Pict in the built-in renderer.

procedure

(path-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in path Visual.

procedure

(path-visual-path visual)  path-geometry?

  visual : path-visual?
Returns visual’s local semantic path geometry. The returned geometry has not been translated, rotated, scaled, or converted to pixels.

procedure

(path-visual-fill visual)  any/c

  visual : path-visual?
Returns the stored fill style. The built-in renderer uses it only for closed subpaths. A false value disables filling.

procedure

(path-visual-stroke visual)  any/c

  visual : path-visual?
Returns the stored stroke style. A false value disables stroking in the built-in renderer.

procedure

(path-visual-stroke-width visual)

  (and/c finite-real? (>=/c 0))
  visual : path-visual?
Returns the stored cosmetic stroke width.

procedure

(path-visual-with-path visual path)  path-visual?

  visual : path-visual?
  path : path-geometry?
Returns a new path Visual with its local geometry replaced by path. Identity, affine transform, opacity, fill, stroke, and stroke width are preserved. The original Visual is unchanged.

procedure

(line start    
  end    
  #:id id    
  [#:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  start : vec2?
  end : vec2?
  id : symbol?
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates an open path Visual between two points in one containing coordinate system. The points are world-space values when the result is top level and local values when the result is placed in a group. start and end must differ.

The constructor uses the midpoint of the two points as the Visual’s reference position and subtracts that midpoint from both stored path points. The local line is therefore centered at the origin. Rotation and scale are applied around that midpoint. The fill style is always #f. The optional opacity value is preserved as semantic global opacity.

For example:

(line (vec2 -2 0)
      (vec2 2 0)
      #:id 'axis
      #:stroke "navy"
      #:stroke-width 3)

procedure

(polygon vertices    
  #:id id    
  [#:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  vertices : (listof vec2?)
  id : symbol?
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  fill : any/c = "cornflowerblue"
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates a closed path Visual through at least three vertices in one containing coordinate system. The vertices are world-space values at the top level and local values when the result is placed in a group. Vertex order is significant.

The constructor computes the center of the vertices’ axis-aligned bounding box and uses it as the Visual’s reference position. It subtracts that center from every stored path point, so scale and rotation occur around the bounding-box center. The constructor does not calculate a polygon centroid.

The closing edge from the last vertex to the first is implicit. Do not repeat the first vertex merely to close the polygon; repeating it adds a zero-length segment before the implicit closing edge. The optional opacity value is stored as semantic global opacity.

19.18 Bitmap Images🔗ℹ

procedure

(image source    
  #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity]    
  #:width width    
  #:height height)  image-visual?
  source : path-string?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  width : (and/c finite-real? positive?)
  height : (and/c finite-real? positive?)
Creates an immutable bitmap-image Visual. source is copied as a path string but is not opened during construction, scene sampling, or timeline compilation. width and height specify the unscaled local world dimensions, independently of the bitmap’s source-pixel dimensions.

The built-in renderer loads the source lazily, scales it to the requested world size at the current camera scale, then applies the normal Visual scale and rotation. A missing or unreadable source therefore raises a renderer-time error. Its renderer-local bitmap cache is bounded and does not affect scene semantics. Image Visuals implement affine and opacity protocols, so standard movement, scaling, rotation, fading, grouping, layout, camera placement, and frame rendering work without a special timeline request.

procedure

(image-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in bitmap image Visual.

procedure

(image-visual-source visual)  immutable-string?

  visual : image-visual?
Returns the copied renderer-resolved source pathname.

procedure

(image-visual-width visual)  (and/c finite-real? positive?)

  visual : image-visual?
Returns the unscaled local world width.

procedure

(image-visual-height visual)  (and/c finite-real? positive?)

  visual : image-visual?
Returns the unscaled local world height.

19.19 Full-Fidelity SVG Images🔗ℹ

procedure

(svg-image source    
  #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity]    
  #:width width    
  #:height height)  svg-image-visual?
  source : path-string?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  width : (and/c finite-real? positive?)
  height : (and/c finite-real? positive?)
Creates an immutable full-fidelity static SVG Visual. source is not opened until rendering; the default renderer delegates then to the catalog svg/svg package. That renderer supports substantially more SVG than the semantic importer, including transforms, gradients, clipping, masks, text, local image references, CSS, and many static filters.

width and height specify unscaled local world dimensions, independently of the SVG document’s viewport. The Visual otherwise behaves like image: standard movement, scaling, rotation, opacity animation, groups, layout, camera placement, and frame rendering work normally. The renderer has a bounded local source-Pict cache. Use svg->visual rather than this constructor when individual SVG elements must be directly addressed or animated.

procedure

(svg-image-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in full-fidelity SVG Visual.

procedure

(svg-image-visual-source visual)  immutable-string?

  visual : svg-image-visual?
Returns the copied renderer-resolved SVG source pathname.

procedure

(svg-image-visual-width visual)

  (and/c finite-real? positive?)
  visual : svg-image-visual?
Returns the unscaled local world width.

procedure

(svg-image-visual-height visual)

  (and/c finite-real? positive?)
  visual : svg-image-visual?
Returns the unscaled local world height.

19.20 Semantic SVG Import🔗ℹ

procedure

(svg->visual source    
  #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity])  group-visual?
  source : path-string?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
Reads an SVG XML file once and converts supported geometry into an immutable semantic group. SVG path, line, polyline, polygon, rect, circle, ellipse, and nested g elements are supported. The path importer accepts absolute and relative M, L, H, V, C, Q, and Z commands; quadratic segments are converted exactly to cubic semantic segments. Unsupported graphical tags are ignored.

The root takes id. An SVG element’s nonempty id becomes its stable child identity; missing IDs receive deterministic generated symbols. Nested g elements become nested built-in groups, so imported IDs participate in scene-ref, scene-visual-at, derived-context lookup, and all nested style and transform requests. The constructor rejects duplicate IDs using the existing built-in group-tree invariant.

SVG’s screen-down y coordinate is converted to the semantic world-up y coordinate. Unitless translate(x[, y]) transforms are supported. Other SVG transforms must be flattened before import. Inherited fill, stroke, stroke-width, and opacity attributes (including simple inline style declarations) are preserved. CSS stylesheets, clipping, text, use elements, arcs, and paint servers are outside this deliberately semantic subset.

19.21 Arrow and Cartesian Axes Visuals🔗ℹ

Arrow and axes values are semantic affine Visuals. They implement gen:visual, gen:affine-visual, and gen:opacity-visual. Their raw structure constructors and internal local geometry fields are not public.

19.21.1 Arrows🔗ℹ

procedure

(arrow start    
  end    
  #:id id    
  [#:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:tip-length tip-length    
  #:tip-width tip-width    
  #:start-tip? start-tip?    
  #:end-tip? end-tip?])  arrow-visual?
  start : vec2?
  end : vec2?
  id : symbol?
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
  tip-length : (and/c finite-real? positive?) = 3/10
  tip-width : (and/c finite-real? positive?) = 1/4
  start-tip? : boolean? = #f
  end-tip? : boolean? = #t
Creates a semantic arrow whose untransformed shaft begins at start and ends at end. Both points are in one containing coordinate system. They are world coordinates for a top-level Visual and local coordinates when the arrow is later placed in a group.

The points must be distinct and their distance must be finite. The constructor uses their midpoint as the Visual’s reference position and stores the two endpoints relative to that midpoint. The optional rotation and scale therefore act around the midpoint.

start-tip? and end-tip? independently select closed triangular tips. The default is one tip at the end. Both flags may be false, or both may be true. tip-length measures the distance from an apex to the center of its base. tip-width measures the full base width. Both are local world-unit geometry and are affected by semantic scale. A tip is allowed to be longer than the shaft.

stroke is adapter-specific style data. The built-in Pict renderer uses it for the shaft, tip fill, and tip outline. stroke-width is a cosmetic output width and is not multiplied by semantic scale. opacity is applied to the complete rendered arrow after renderer dispatch.

procedure

(arrow-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in arrow Visual.

procedure

(arrow-visual-length arrow)  (and/c finite-real? positive?)

  arrow : arrow-visual?
Returns the unscaled length of the stored local shaft. Translation, rotation, and semantic scale do not change this result.

procedure

(arrow-visual-stroke arrow)  any/c

  arrow : arrow-visual?
Returns the stored adapter-specific stroke style.

procedure

(arrow-visual-stroke-width arrow)

  (and/c finite-real? (>=/c 0))
  arrow : arrow-visual?
Returns the stored cosmetic stroke width.

procedure

(arrow-visual-tip-length arrow)

  (and/c finite-real? positive?)
  arrow : arrow-visual?
Returns the unscaled local length of each enabled triangular tip.

procedure

(arrow-visual-tip-width arrow)  (and/c finite-real? positive?)

  arrow : arrow-visual?
Returns the unscaled local base width of each enabled triangular tip.

procedure

(arrow-visual-start-tip? arrow)  boolean?

  arrow : arrow-visual?
Reports whether the start endpoint has a triangular tip.

procedure

(arrow-visual-end-tip? arrow)  boolean?

  arrow : arrow-visual?
Reports whether the end endpoint has a triangular tip.

procedure

(arrow-visual-start arrow)  vec2?

  arrow : arrow-visual?
Returns the current start point in the arrow’s containing coordinate system. The complete affine transform has been applied.

procedure

(arrow-visual-end arrow)  vec2?

  arrow : arrow-visual?
Returns the current end point in the arrow’s containing coordinate system. The complete affine transform has been applied.

procedure

(arrow-visual-point-at arrow progress)  vec2?

  arrow : arrow-visual?
  progress : (real-in 0 1)
Returns the current shaft point at progress. A value of 0 returns the transformed start, 1 returns the transformed end, and 1/2 returns the transformed midpoint. The procedure follows the shaft only; tip geometry does not affect the result.

19.21.2 Dynamic Endpoint Geometry🔗ℹ

SCENE-CN provides deterministic geometry relationships without mutable updaters. Each endpoint accepted by the procedures below may be a literal vec2, a point-valued scene-parameter? handle, a top-level Visual/symbol/nested visual-path?, or a value made with anchor-of. A plain Visual reference selects its semantic reference position. Parameter values must be vec2 at every sampled time.

procedure

(anchor-of target [anchor #:offset offset])  any/c

  target : (or/c visual? symbol? visual-path?)
  anchor : 
(or/c 'bottom-left 'bottom 'bottom-right
      'left 'center 'right
      'top-left 'top 'top-right)
 = 'center
  offset : vec2? = origin
Creates one endpoint description for target. A centre anchor is the ordinary semantic point. An edge or corner selects the target’s live renderer-measured box at render time; offset is a world-space offset from that selected point. This result is intended as an endpoint argument to the SCENE-CN constructors.

procedure

(line-between start    
  end    
  #:id id    
  [#:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  relation-visual?
  start : any/c
  end : any/c
  id : symbol?
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates a finite line segment with independently sampled endpoints.

procedure

(segment-between start 
  end 
  #:id id 
  [#:opacity opacity 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  relation-visual?
  start : any/c
  end : any/c
  id : symbol?
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
The mathematical finite-segment spelling of line-between.

procedure

(arrow-between start    
  end    
  #:id id    
  [#:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:tip-length tip-length    
  #:tip-width tip-width    
  #:start-tip? start-tip?    
  #:end-tip? end-tip?])  relation-visual?
  start : any/c
  end : any/c
  id : symbol?
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
  tip-length : (and/c finite-real? positive?) = 3/10
  tip-width : (and/c finite-real? positive?) = 1/4
  start-tip? : boolean? = #f
  end-tip? : boolean? = #t
Creates an arrow with a shaft and optional tips that follow independently sampled endpoints.

procedure

(ray-from start    
  through    
  #:id id    
  [#:length length    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:tip-length tip-length    
  #:tip-width tip-width    
  #:start-tip? start-tip?    
  #:end-tip? end-tip?])  relation-visual?
  start : any/c
  through : any/c
  id : symbol?
  length : (and/c finite-real? positive?) = 2
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
  tip-length : (and/c finite-real? positive?) = 3/10
  tip-width : (and/c finite-real? positive?) = 1/4
  start-tip? : boolean? = #f
  end-tip? : boolean? = #t
Creates a finite visible ray that begins at start and points through through. Its rendered length is fixed by length, avoiding an ill-defined infinite renderer object.

Every endpoint constructor returns a relation-visual?. Literal points, parameters, and centre references create a 'semantic relation; a non-centre anchor-of creates a 'layout relation, measured against the current renderer-visible box after normal scene sampling. The relations retain their identity, support their ordinary outer movement and opacity animation, and can be inspected before rendering. Endpoint geometry must still resolve to distinct points at the sampled time.

19.21.3 Mathematical Annotations🔗ℹ

SCENE-CO supplies small semantic, path-backed marks for explanatory diagrams. SCENE-ED additionally gives selected marks the same live endpoint protocol as line-between: a literal vec2, point-valued scene-parameter, Visual ID/path (its semantic centre), or anchor-of description. Literal points return the same immediate path-visual? or group-visual? values as before. Parameter and centre-reference inputs create semantic relations; an edge/corner anchor creates a layout relation. Both are deterministic from the sampled state. The layout phase remains top-level in this release, and it uses complete renderer bounds rather than exact visible outlines.

procedure

(arc #:id id    
  [#:center center    
  #:radius radius    
  #:start-angle start-angle    
  #:angle angle    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  id : symbol?
  center : vec2? = origin
  radius : (and/c finite-real? positive?) = 1
  start-angle : finite-real? = 0
  angle : (and/c finite-real? (not/c zero?)) = (/ pi 2)
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates an open circular arc. Positive sweeps travel counter-clockwise; the absolute sweep must be no greater than one full turn. The implementation splits the arc into quarter-turn cubic Bézier pieces, retaining exact cardinal endpoints rather than using a polyline approximation.

procedure

(dashed-path geometry    
  #:id id    
  [#:dash-length dash-length    
  #:gap-length gap-length    
  #:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  geometry : path-geometry?
  id : symbol?
  dash-length : (and/c finite-real? positive?) = 1/5
  gap-length : stroke-width? = 1/8
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Selects dash intervals by the geometry’s total arc length. Curves remain cubic path fragments; they are not flattened into renderer-specific segments.

procedure

(dashed-line start    
  end    
  #:id id    
  [#:dash-length dash-length    
  #:gap-length gap-length    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  start : vec2?
  end : vec2?
  id : symbol?
  dash-length : (and/c finite-real? positive?) = 1/5
  gap-length : stroke-width? = 1/8
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates a finite dashed line. start and end must differ.

procedure

(angle first    
  vertex    
  second    
  #:id id    
  [#:radius radius    
  #:reflex? reflex?    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  first : vec2?
  vertex : vec2?
  second : vec2?
  id : symbol?
  radius : (and/c finite-real? positive?) = 1/3
  reflex? : boolean? = #f
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates an arc mark from the ray vertexfirst to the ray vertexsecond. By default it selects the signed minor angle; reflex? selects its complementary reflex sweep. Collinear rays are rejected instead of producing a deceptive zero-angle mark.

procedure

(right-angle first    
  vertex    
  second    
  #:id id    
  [#:size size    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  first : vec2?
  vertex : vec2?
  second : vec2?
  id : symbol?
  size : (and/c finite-real? positive?) = 1/3
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates the conventional square-corner mark from two supplied rays. It does not try to prove that those rays are perpendicular.

procedure

(angle-between first    
  vertex    
  second    
  #:id id    
  [#:radius radius    
  #:reflex? reflex?    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  visual?
  first : any/c
  vertex : any/c
  second : any/c
  id : symbol?
  radius : (and/c finite-real? positive?) = 1/3
  reflex? : boolean? = #f
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates angle from three live endpoint descriptions. Literal vec2 values return the same static path as angle. Otherwise, all three endpoints are sampled together before the angle arc is built. It still does not infer a mathematical relationship between the rays.

procedure

(right-angle-between first    
  vertex    
  second    
  #:id id    
  [#:size size    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  visual?
  first : any/c
  vertex : any/c
  second : any/c
  id : symbol?
  size : (and/c finite-real? positive?) = 1/3
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates right-angle from three live endpoint descriptions. A right angle remains an author assertion: the implementation follows the two rays but does not verify they are perpendicular.

procedure

(brace-between start    
  end    
  #:id id    
  [#:offset offset    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  visual?
  start : any/c
  end : any/c
  id : symbol?
  offset : (and/c finite-real? (not/c zero?)) = 1/3
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates a symmetric cubic curly brace. Positive offset places it to the left of start-to-end travel; negative values place it on the other side. With literal points it is an ordinary path; otherwise its two live endpoints are sampled together. brace is a short spelling with the same arguments.

procedure

(brace start    
  end    
  #:id id    
  [#:offset offset    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  visual?
  start : any/c
  end : any/c
  id : symbol?
  offset : (and/c finite-real? (not/c zero?)) = 1/3
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Short spelling for brace-between. It creates the same symmetric cubic brace with the same placement and styling rules.

procedure

(brace-label start    
  end    
  label    
  #:id id    
  [#:offset offset    
  #:gap gap    
  #:font-size font-size    
  #:color color    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  visual?
  start : any/c
  end : any/c
  label : string?
  id : symbol?
  offset : (and/c finite-real? (not/c zero?)) = 1/3
  gap : stroke-width? = 1/6
  font-size : (and/c finite-real? positive?) = 1/4
  color : color-spec? = "black"
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates a brace and centered plain-text label. The child identities are deterministically derived as id plus -brace and -label. With live endpoints the brace and label are rebuilt together from the same two sampled points.

procedure

(curved-arrow-between start    
  end    
  #:id id    
  [#:angle angle    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:tip-length tip-length    
  #:tip-width tip-width])  visual?
  start : any/c
  end : any/c
  id : symbol?
  angle : finite-real? = (/ pi 2)
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
  tip-length : (and/c finite-real? positive?) = 3/10
  tip-width : (and/c finite-real? positive?) = 1/4
Creates curved-arrow from two live endpoint descriptions. Each sample rebuilds both the circular shaft and its final-tangent tip, so the arrow head follows the changing arc. It does not select routes around obstacles or support arbitrary Bézier/elliptical routes.

procedure

(surrounding-rectangle target 
  #:id id 
  [#:padding padding 
  #:opacity opacity 
  #:fill fill 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  relation-visual?
  target : (or/c visual? symbol? visual-path?)
  id : symbol?
  padding : stroke-width? = 1/8
  opacity : opacity? = 1
  fill : any/c = #f
  stroke : any/c = "yellow"
  stroke-width : stroke-width? = 3
Creates a layout relation around the sampled rendered bounding box of target. Padding is in world coordinates. The relation follows motion, scale, rotation, and nested/derived target layout, retains its ordinary outer style and opacity animation, and records its target as a semantic selection dependency. Its current implementation is square-cornered; #f selects its default transparent fill. Like other layout relations, it must currently remain top-level and its box includes renderer padding rather than only visible ink.

19.21.4 Mathematical Shape Catalogue🔗ℹ

SCENE-DJ adds a compact family of path-backed shapes. Except for the two convenience groups, each constructor returns an ordinary path-visual? with the usual affine placement, opacity, fill, and stroke protocols. They do not introduce renderer-specific leaf classes; the existing path renderer draws their line and cubic geometry, including odd-even holes in annulus.

procedure

(ellipse #:id id    
  [#:center center    
  #:width width    
  #:height height    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  id : symbol?
  center : vec2? = origin
  width : (and/c finite-real? positive?) = 2
  height : (and/c finite-real? positive?) = 1
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  fill : any/c = "cornflowerblue"
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates a cubic Bézier ellipse centered at center. Width and height are unscaled world dimensions. Rotation and scale are applied around the centre.

procedure

(annulus #:id id    
  [#:center center    
  #:inner-radius inner-radius    
  #:outer-radius outer-radius    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  id : symbol?
  center : vec2? = origin
  inner-radius : (and/c finite-real? positive?) = 1/2
  outer-radius : (and/c finite-real? positive?) = 1
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  fill : any/c = "cornflowerblue"
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates a closed ring with an odd-even transparent hole. The inner radius must be strictly smaller than the outer radius. A nonuniform semantic scale can turn the ring into an elliptical annulus.

procedure

(sector #:id id    
  [#:center center    
  #:radius radius    
  #:start-angle start-angle    
  #:angle angle    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  id : symbol?
  center : vec2? = origin
  radius : (and/c finite-real? positive?) = 1
  start-angle : finite-real? = 0
  angle : finite-real? = (/ pi 2)
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  fill : any/c = "cornflowerblue"
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates the closed radial wedge from start-angle through the signed central angle. The sweep must be nonzero and no longer than a complete turn. A positive sweep is counter-clockwise.

procedure

(regular-polygon #:id id    
  [#:center center    
  #:sides sides    
  #:radius radius    
  #:start-angle start-angle    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  id : symbol?
  center : vec2? = origin
  sides : exact-integer? = 5
  radius : (and/c finite-real? positive?) = 1
  start-angle : finite-real? = (/ pi 2)
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  fill : any/c = "cornflowerblue"
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates an equal-radius polygon with one vertex initially at start-angle. sides must be an exact integer at least three.

procedure

(star #:id id    
  [#:center center    
  #:points points    
  #:outer-radius outer-radius    
  #:inner-radius inner-radius    
  #:start-angle start-angle    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  id : symbol?
  center : vec2? = origin
  points : exact-integer? = 5
  outer-radius : (and/c finite-real? positive?) = 1
  inner-radius : (and/c finite-real? positive?) = 1/2
  start-angle : finite-real? = (/ pi 2)
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  fill : any/c = "gold"
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates an alternating outer/inner regular star boundary. points must be at least two, and the inner radius must be strictly smaller than the outer radius.

procedure

(rounded-rectangle #:id id 
  [#:center center 
  #:width width 
  #:height height 
  #:corner-radius corner-radius 
  #:rotation rotation 
  #:scale scale 
  #:opacity opacity 
  #:fill fill 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  path-visual?
  id : symbol?
  center : vec2? = origin
  width : (and/c finite-real? positive?) = 2
  height : (and/c finite-real? positive?) = 1
  corner-radius : stroke-width? = 1/5
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  fill : any/c = "cornflowerblue"
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates a rectangle with four cubic quarter-circle corners. Corner radius is nonnegative and may not exceed either half-extent. A zero radius creates the same outline topology as a sharp rectangle.

procedure

(arc-between-points start    
  end    
  #:id id    
  [#:angle angle    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  start : vec2?
  end : vec2?
  id : symbol?
  angle : finite-real? = (/ pi 2)
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
Creates the circular arc joining two distinct points with the specified signed central sweep. Its magnitude must be nonzero and strictly less than one full turn. Sign selects the side of the chord and traversal direction.

procedure

(curved-arrow start    
  end    
  #:id id    
  [#:angle angle    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:tip-length tip-length    
  #:tip-width tip-width])  group-visual?
  start : vec2?
  end : vec2?
  id : symbol?
  angle : finite-real? = (/ pi 2)
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
  tip-length : (and/c finite-real? positive?) = 3/10
  tip-width : (and/c finite-real? positive?) = 1/4
Creates a circular arc-between-points with a triangular tip aligned to its final tangent. The returned group has child identities formed from id plus -shaft and -tip.

procedure

(double-arrow start    
  end    
  #:id id    
  [#:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:tip-length tip-length    
  #:tip-width tip-width])  arrow-visual?
  start : vec2?
  end : vec2?
  id : symbol?
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  stroke : any/c = "black"
  stroke-width : stroke-width? = 2
  tip-length : (and/c finite-real? positive?) = 3/10
  tip-width : (and/c finite-real? positive?) = 1/4
Creates the ordinary semantic arrow from start to end with both start-tip? and end-tip? enabled.

procedure

(labeled-point label    
  #:id id    
  [#:center center    
  #:radius radius    
  #:label-offset label-offset    
  #:font-size font-size    
  #:font-family font-family    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:color color    
  #:opacity opacity])  group-visual?
  label : string?
  id : symbol?
  center : vec2? = origin
  radius : (and/c finite-real? positive?) = 1/10
  label-offset : vec2? = (vec2 1/4 1/4)
  font-size : (and/c finite-real? positive?) = 1/4
  font-family : any/c = 'roman
  fill : any/c = "crimson"
  stroke : any/c = "firebrick"
  stroke-width : stroke-width? = 2
  color : any/c = stroke
  opacity : opacity? = 1
Creates a dot and a plain-text label as one group. Its stable child identities are id plus -dot and -label; moving or fading the outer group therefore carries both together. Label placement is the explicit local label-offset, not a collision-aware layout operation.

19.21.5 Axis Ranges🔗ℹ

struct

(struct axis-range (minimum maximum tick-step)
    #:transparent)
  minimum : finite-real?
  maximum : finite-real?
  tick-step : (and/c finite-real? positive?)
Represents one closed numeric interval and the spacing of its regular ticks. The fields have these meanings:

  • minimum is the smallest represented coordinate.

  • maximum is the largest represented coordinate.

  • tick-step is the positive distance between regular tick coordinates.

minimum must be less than maximum. The computed difference (- maximum minimum) must also remain a positive finite real; this rejects an inexact endpoint pair whose subtraction overflows. The structure is immutable and transparent. Linear axes require their ranges to contain zero; logarithmic axes require strictly-positive ranges. Its public bindings include axis-range, axis-range?, the three field accessors, and struct:axis-range.

procedure

(axis-range-contains? range value)  boolean?

  range : axis-range?
  value : any/c
Returns #t when value is a finite real in the closed interval from (axis-range-minimum range) through (axis-range-maximum range). Non-real values, infinities, and NaN return #f.

procedure

(axis-range-tick-values range)  (listof finite-real?)

  range : axis-range?
Returns the nonzero integer multiples of (axis-range-tick-step range) that lie in the closed interval. The values are in increasing numeric order. An interval endpoint is included when it is such a multiple. Zero is omitted because the two Cartesian shafts already intersect there.

For example:

(axis-range-tick-values (axis-range -3 5 2))

returns '(-2 2 4). The procedure does not choose ticks from camera pixels or available label space.

Exact endpoint quotients are handled exactly. For inexact quotients, the procedure uses a fixed relative tolerance of 1e-12 when choosing the first and last integer indexes. This prevents ordinary decimal input such as -0.3, 0.3, and 0.1 from losing endpoint ticks because of binary floating-point rounding. It raises an exception when dividing a range endpoint by the step produces an infinite or NaN index.

procedure

(axis-scale? value)  boolean?

  value : any/c
Returns #t for the supported scale symbols 'linear and 'log.

19.21.6 Cartesian Axes🔗ℹ

procedure

(axes #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:x-range x-range    
  #:y-range y-range    
  #:x-scale x-scale    
  #:y-scale y-scale    
  #:x-log-base x-log-base    
  #:y-log-base y-log-base    
  #:x-length x-length    
  #:y-length y-length    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:tick-size tick-size    
  #:tip-length tip-length    
  #:tip-width tip-width    
  #:x-tip? x-tip?    
  #:y-tip? y-tip?])  axes-visual?
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  x-range : axis-range? = (axis-range -6 6 1)
  y-range : axis-range? = (axis-range -3 3 1)
  x-scale : axis-scale? = 'linear
  y-scale : axis-scale? = 'linear
  x-log-base : (and/c finite-real? (>/c 1)) = 10
  y-log-base : (and/c finite-real? (>/c 1)) = 10
  x-length : (and/c finite-real? positive?) = 12
  y-length : (and/c finite-real? positive?) = 6
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
  tick-size : (and/c finite-real? (>=/c 0)) = 3/20
  tip-length : (and/c finite-real? positive?) = 3/10
  tip-width : (and/c finite-real? positive?) = 1/4
  x-tip? : boolean? = #t
  y-tip? : boolean? = #t
Creates semantic two-dimensional Cartesian axes. On the default linear scales, numeric coordinate (0, 0) is the Visual’s local origin and reference point before center, rotation, and scale are applied.

The full interval from (axis-range-minimum x-range) to (axis-range-maximum x-range) is mapped to x-length local world units. The y interval is mapped independently to y-length. The x and y unit lengths can therefore differ. Each resulting length-per-display-unit must remain a positive finite real.

With 'log for x-scale or y-scale, that axis accepts only a strictly-positive axis-range. Numeric coordinates are converted through (log value) in the configured base before they are placed. A log axis uses numeric one as its shaft reference when it is visible (otherwise the minimum range value); coordinate zero is invalid. x-log-base and y-log-base must be finite and greater than one. The tick-step of a log range is a step in base-logarithm exponent space, so the usual value of one produces ticks at successive powers of the base.

The x shaft is drawn at numeric y coordinate zero on a linear y axis, and at numeric one (or the visible minimum) on a log y axis; the y shaft follows the same rule for its x coordinate. Regular ticks come from axis-range-tick-values on linear axes and powers of the configured base on log axes. tick-size is the full local length of each tick. A value of zero hides all ticks while preserving the ranges and coordinate conversion.

x-tip? and y-tip? select triangular tips at the maximum-x and maximum-y endpoints, respectively. tip-length and tip-width are local world-unit geometry. stroke-width is cosmetic. The built-in renderer uses stroke for shafts, ticks, tip fill, and tip outlines.

The constructor does not create numeric labels, axis-name labels, grid lines, or sampled plots. They can be added as separate Visuals. Renderer-aware layout can place labels around the complete axes render box.

procedure

(axes-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in Cartesian-axes Visual.

procedure

(axes-visual-x-range axes)  axis-range?

  axes : axes-visual?
Returns the stored horizontal numeric range.

procedure

(axes-visual-y-range axes)  axis-range?

  axes : axes-visual?
Returns the stored vertical numeric range.

procedure

(axes-visual-x-scale axes)  axis-scale?

  axes : axes-visual?
Returns the stored horizontal coordinate scale.

procedure

(axes-visual-y-scale axes)  axis-scale?

  axes : axes-visual?
Returns the stored vertical coordinate scale.

procedure

(axes-visual-x-log-base axes)  (and/c finite-real? (>/c 1))

  axes : axes-visual?
Returns the stored horizontal logarithm base. It affects coordinate conversion only when (axes-visual-x-scale axes) is 'log.

procedure

(axes-visual-y-log-base axes)  (and/c finite-real? (>/c 1))

  axes : axes-visual?
Returns the stored vertical logarithm base. It affects coordinate conversion only when (axes-visual-y-scale axes) is 'log.

procedure

(axes-visual-x-length axes)  (and/c finite-real? positive?)

  axes : axes-visual?
Returns the unscaled local length representing the full x range.

procedure

(axes-visual-y-length axes)  (and/c finite-real? positive?)

  axes : axes-visual?
Returns the unscaled local length representing the full y range.

procedure

(axes-visual-stroke axes)  any/c

  axes : axes-visual?
Returns the stored adapter-specific line and tip style.

procedure

(axes-visual-stroke-width axes)  (and/c finite-real? (>=/c 0))

  axes : axes-visual?
Returns the stored cosmetic stroke width.

procedure

(axes-visual-tick-size axes)  (and/c finite-real? (>=/c 0))

  axes : axes-visual?
Returns the unscaled full local length of each tick.

procedure

(axes-visual-tip-length axes)  (and/c finite-real? positive?)

  axes : axes-visual?
Returns the unscaled local length of each enabled maximum-end tip.

procedure

(axes-visual-tip-width axes)  (and/c finite-real? positive?)

  axes : axes-visual?
Returns the unscaled local base width of each enabled maximum-end tip.

procedure

(axes-visual-x-tip? axes)  boolean?

  axes : axes-visual?
Reports whether the maximum-x endpoint has a triangular tip.

procedure

(axes-visual-y-tip? axes)  boolean?

  axes : axes-visual?
Reports whether the maximum-y endpoint has a triangular tip.

procedure

(axes-x-unit-length axes)  (and/c finite-real? positive?)

  axes : axes-visual?
Returns the unscaled local length representing one x display-space unit. On a linear axis it is (/ (axes-visual-x-length axes) (- (axis-range-maximum (axes-visual-x-range axes)) (axis-range-minimum (axes-visual-x-range axes)))). On a log axis the denominator is the corresponding base-logarithm span.

procedure

(axes-y-unit-length axes)  (and/c finite-real? positive?)

  axes : axes-visual?
Returns the unscaled local length representing one y display-space unit. On a linear axis it is (/ (axes-visual-y-length axes) (- (axis-range-maximum (axes-visual-y-range axes)) (axis-range-minimum (axes-visual-y-range axes)))). On a log axis the denominator is the corresponding base-logarithm span.

procedure

(axes-coordinates->point axes x y)  vec2?

  axes : axes-visual?
  x : finite-real?
  y : finite-real?
Converts numeric coordinate (x, y) to a point in the axes’ containing coordinate system. The procedure first maps each coordinate through its linear or logarithmic display scale, multiplies by the independent local unit lengths, then applies semantic scale, rotation, and translation.

The numeric coordinates are not required to lie inside the displayed ranges. This permits extrapolation and placement just outside the visible axes. A value on a logarithmic axis must nevertheless be a positive finite real.

procedure

(axes-point->coordinates axes point)  vec2?

  axes : axes-visual?
  point : vec2?
Converts point from the axes’ containing coordinate system to numeric axis coordinates. The procedure removes translation, rotation, and positive scale, then divides by the independent x and y unit lengths.

For finite inputs this is the inverse of axes-coordinates->point up to ordinary numeric precision. A nonzero rotation normally introduces inexact trigonometric results.

19.22 Linear-Algebra Diagrams🔗ℹ

SCENE-CZ adds small, conventional linear-algebra diagrams without adding a mutable diagram class. Each constructor below returns an ordinary immutable Visual or group-visual?. Its children retain their normal nested paths, so existing scene operations work directly. In particular, apply-matrix can map one complete top-level diagram coherently.

procedure

(number-plane #:id id 
  [#:x-range x-range 
  #:y-range y-range 
  #:x-length x-length 
  #:y-length y-length 
  #:center center 
  #:rotation rotation 
  #:scale scale 
  #:grid? grid? 
  #:labels? labels? 
  #:grid-stroke grid-stroke 
  #:grid-stroke-width grid-stroke-width 
  #:axes-stroke axes-stroke 
  #:axes-stroke-width axes-stroke-width 
  #:label-font-size label-font-size 
  #:label-color label-color]) 
  group-visual?
  id : symbol?
  x-range : axis-range? = (axis-range -4 4 1)
  y-range : axis-range? = (axis-range -3 3 1)
  x-length : (and/c finite-real? positive?) = 8
  y-length : (and/c finite-real? positive?) = 6
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  grid? : boolean? = #t
  labels? : boolean? = #f
  grid-stroke : any/c = "lightsteelblue"
  grid-stroke-width : (and/c finite-real? (>=/c 0)) = 1
  axes-stroke : any/c = "navy"
  axes-stroke-width : (and/c finite-real? (>=/c 0)) = 2
  label-font-size : (and/c finite-real? positive?) = 1/4
  label-color : any/c = "navy"
Creates a conventional Cartesian number plane. The returned group has an 'axes child and, when requested, 'grid and 'labels children. The grid uses the plane’s ranges and display lengths; its geometry is therefore in the same coordinate system as the axes. Numeric labels are absent by default, because dense labels are often inappropriate in an animation.

The stable direct-child paths are produced by number-plane-grid-path, number-plane-axes-path, and number-plane-labels-path. When #:grid? or #:labels? is false, its corresponding path intentionally does not resolve.

procedure

(number-plane-grid-path plane-id)  visual-path?

  plane-id : symbol?
Returns (list plane-id 'grid).

procedure

(number-plane-axes-path plane-id)  visual-path?

  plane-id : symbol?
Returns (list plane-id 'axes).

procedure

(number-plane-labels-path plane-id)  visual-path?

  plane-id : symbol?
Returns (list plane-id 'labels).

procedure

(vector-arrow endpoint    
  [#:start start]    
  #:id id    
  [#:stroke stroke    
  #:stroke-width stroke-width    
  #:tip-length tip-length    
  #:tip-width tip-width])  arrow-visual?
  endpoint : vec2?
  start : vec2? = origin
  id : symbol?
  stroke : any/c = "darkorchid"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
  tip-length : (and/c finite-real? positive?) = 3/10
  tip-width : (and/c finite-real? positive?) = 1/4
Creates an ordinary arrow from start to endpoint. The name is deliberately vector-arrow, not vector, so requiring animate does not shadow Racket’s built-in vector constructor.

procedure

(vector-coordinates arrow)  vec2?

  arrow : arrow-visual?
Returns the arrow’s endpoint minus its start point, in the arrow’s containing coordinate system.

procedure

(vector-label arrow    
  #:id id    
  [#:text text    
  #:offset offset    
  #:font-size font-size    
  #:color color])  text-visual?
  arrow : arrow-visual?
  id : symbol?
  text : (or/c false/c string?) = #f
  offset : vec2? = (vec2 1/5 1/5)
  font-size : (and/c finite-real? positive?) = 1/4
  color : any/c = "darkorchid"
Creates a static text label beside arrow’s endpoint. Without #:text, its content is the vector’s coordinate pair. This is a construction-time snapshot: if the arrow itself is separately animated, rebuild the label through derived-visual until SCENE-DE supplies general live layout relationships.

procedure

(basis-vectors #:id id    
  [#:origin origin    
  #:e1 e1    
  #:e2 e2    
  #:e1-color e1-color    
  #:e2-color e2-color    
  #:stroke-width stroke-width])  group-visual?
  id : symbol?
  origin : vec2? = origin
  e1 : vec2? = (vec2 1 0)
  e2 : vec2? = (vec2 0 1)
  e1-color : any/c = "crimson"
  e2-color : any/c = "forestgreen"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Creates a group with conventional 'e1 and 'e2 arrow children. The e1 and e2 arguments are endpoints, not displacement vectors: their common start is origin.

procedure

(linear-transformation-diagram #:id id 
  [#:x-range x-range 
  #:y-range y-range 
  #:vector-end vector-end 
  #:unit-square? unit-square? 
  #:grid? grid?]) 
  group-visual?
  id : symbol?
  x-range : axis-range? = (axis-range -4 4 1)
  y-range : axis-range? = (axis-range -3 3 1)
  vector-end : vec2? = (vec2 3 2)
  unit-square? : boolean? = #t
  grid? : boolean? = #t
Creates the standard matrix-action diagram. Its stable children are 'plane, 'basis, 'vector, and, unless disabled, 'unit-square. The first two have their own paths such as '(diagram plane grid) and '(diagram basis e1).

For example, this keeps all geometric parts together while a title remains fixed outside the mapped group:

(define diagram
  (linear-transformation-diagram #:id 'diagram
                                 #:vector-end (vec2 3 2)))
 
(scene-play
 (scene-add (make-scene) diagram)
 (apply-matrix 'diagram
               (linear2 1 1
                        0 1))
 #:duration 3)

19.23 Complex and Polar Coordinates🔗ℹ

SCENE-DA uses ordinary Racket complex numbers and converts only at the drawing boundary. SCENE-DB follows the same approach for polar coordinate values and paths. Both planes are normal immutable group trees, not special scene types.

procedure

(complex->point value)  vec2?

  value : complex?
Returns (vec2 (real-part value) (imag-part value)). Both components must be finite reals.

procedure

(point->complex point)  complex?

  point : vec2?
Returns the ordinary Racket complex number whose real and imaginary parts are the x and y components of point.

procedure

(complex-domain-color value    
  [#:saturation saturation    
  #:brightness brightness    
  #:radial? radial?])  rgba-color?
  value : complex?
  saturation : (real-in 0 1) = 3/4
  brightness : (real-in 0 1) = 4/5
  radial? : boolean? = #t
Returns an opaque semantic colour whose hue is the argument of value. When #:radial? is true, its brightness also increases smoothly with the modulus. This is a pure colour helper; it does not create a renderer-only pixel effect.

procedure

(complex-domain-coloring function 
  #:id id 
  [#:x-min x-min 
  #:x-max x-max 
  #:y-min y-min 
  #:y-max y-max 
  #:columns columns 
  #:rows rows 
  #:saturation saturation 
  #:brightness brightness 
  #:radial? radial? 
  #:opacity opacity]) 
  group-visual?
  function : (procedure-arity-includes/c 1)
  id : symbol?
  x-min : finite-real? = -3
  x-max : finite-real? = 3
  y-min : finite-real? = -2
  y-max : finite-real? = 2
  columns : exact-positive-integer? = 24
  rows : exact-positive-integer? = 16
  saturation : (real-in 0 1) = 3/4
  brightness : (real-in 0 1) = 4/5
  radial? : boolean? = #t
  opacity : (real-in 0 1) = 1
Samples function once at the centre of each rectangular complex cell and returns a normal group of coloured rectangle Visuals. The function must return finite complex values. Each cell has a stable name derived from id, so the result remains ordinary semantic scene content rather than a continuous raster shader.

procedure

(complex-plane #:id id 
  [#:x-range x-range 
  #:y-range y-range 
  #:x-length x-length 
  #:y-length y-length 
  #:center center 
  #:rotation rotation 
  #:scale scale 
  #:grid? grid? 
  #:labels? labels? 
  #:grid-stroke grid-stroke 
  #:grid-stroke-width grid-stroke-width 
  #:axes-stroke axes-stroke 
  #:axes-stroke-width axes-stroke-width 
  #:label-font-size label-font-size 
  #:label-color label-color]) 
  group-visual?
  id : symbol?
  x-range : axis-range? = (axis-range -4 4 1)
  y-range : axis-range? = (axis-range -3 3 1)
  x-length : (and/c finite-real? positive?) = 8
  y-length : (and/c finite-real? positive?) = 6
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  grid? : boolean? = #t
  labels? : boolean? = #t
  grid-stroke : any/c = "lightsteelblue"
  grid-stroke-width : (and/c finite-real? (>=/c 0)) = 1
  axes-stroke : any/c = "navy"
  axes-stroke-width : (and/c finite-real? (>=/c 0)) = 2
  label-font-size : (and/c finite-real? positive?) = 1/4
  label-color : any/c = "navy"
Builds a Cartesian complex plane. Its direct 'coordinates child is a number-plane tree; when #:labels? is true, direct 'real-axis and 'imaginary-axis text leaves label Re and Im. The numeric labels are static construction-time labels.

procedure

(apply-complex-function target 
  function 
  [#:samples samples 
  #:adaptive? adaptive? 
  #:tolerance tolerance 
  #:max-depth max-depth 
  #:discontinuities discontinuities]) 
  apply-pointwise-request?
  target : (or/c visual? symbol? visual-path?)
  function : (procedure-arity-includes/c 1)
  samples : exact-positive-integer? = 24
  adaptive? : boolean? = #t
  tolerance : (and/c finite-real? positive?) = 1/32
  max-depth : exact-nonnegative-integer? = 8
  discontinuities : (or/c 'split 'error) = 'error
Creates apply-pointwise with each sampled world point converted by point->complex, passed to function, then converted back with complex->point. The function must return a complex number with finite real and imaginary parts at every retained sampled point. The default strict 'error discontinuity policy makes an accidental bad function result fail visibly. Use 'split for an intentional pole or excluded domain: failed samples then break the path rather than adding a long connecting chord. This API does not infer branch cuts or normalize by an axes’ numeric coordinate scale.

procedure

(apply-complex-homotopy target 
  homotopy 
  [#:samples samples 
  #:adaptive? adaptive? 
  #:tolerance tolerance 
  #:max-depth max-depth 
  #:discontinuities discontinuities]) 
  apply-homotopy-request?
  target : (or/c visual? symbol? visual-path?)
  homotopy : (procedure-arity-includes/c 2)
  samples : exact-positive-integer? = 24
  adaptive? : boolean? = #t
  tolerance : (and/c finite-real? positive?) = 1/32
  max-depth : exact-nonnegative-integer? = 8
  discontinuities : (or/c 'split 'error) = 'error
Creates apply-homotopy with each source point converted by point->complex, passed together with the current local phase to homotopy, and converted back with complex->point. The homotopy must return a finite complex value at every retained sample. Its strict default discontinuity policy matches apply-complex-function; choose 'split for an intentional pole or excluded domain.

procedure

(polar-coordinate? value)  boolean?

  value : any/c
Recognizes an immutable reading returned by point->polar.

procedure

(polar-coordinate-radius value)  (and/c finite-real? (>=/c 0))

  value : polar-coordinate?
Returns the nonnegative radius of a polar reading.

procedure

(polar-coordinate-angle value)  finite-real?

  value : polar-coordinate?
Returns the angle of a polar reading in radians.

procedure

(polar->point radius angle)  vec2?

  radius : finite-real?
  angle : finite-real?
Returns (vec2 (* radius (cos angle)) (* radius (sin angle))). A signed radius is accepted, which lets polar-graph express conventional rose curves.

procedure

(point->polar point)  polar-coordinate?

  point : vec2?
Returns a nonnegative-radius reading. The angle uses atan’s interval [-pi, pi]; the origin is assigned angle zero.

procedure

(polar-plane #:id id 
  [#:radii radii 
  #:angles angles 
  #:center center 
  #:rotation rotation 
  #:scale scale 
  #:labels? labels? 
  #:stroke stroke 
  #:stroke-width stroke-width 
  #:grid-stroke grid-stroke 
  #:grid-stroke-width grid-stroke-width 
  #:label-font-size label-font-size 
  #:label-color label-color]) 
  group-visual?
  id : symbol?
  radii : (listof (and/c finite-real? positive?)) = '(1 2 3)
  angles : (listof finite-real?) = (list 0 (/ pi 4) (/ pi 2))
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : (and/c finite-real? positive?) = 1
  labels? : boolean? = #t
  stroke : any/c = "steelblue"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
  grid-stroke : any/c = "lightsteelblue"
  grid-stroke-width : (and/c finite-real? (>=/c 0)) = 1
  label-font-size : (and/c finite-real? positive?) = 1/4
  label-color : any/c = "navy"
Builds a static polar grid. Its direct children are named 'rings and 'rays, plus 'labels when requested. Ring children use ring-0, ring-1, and so on; ray children use ray-0, ray-1, and so on. Labels are deliberately static and may overlap for dense choices.

procedure

(polar-graph radius-function    
  #:id id    
  [#:start start    
  #:end end    
  #:samples samples    
  #:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:fill fill])  path-visual?
  radius-function : (procedure-arity-includes/c 1)
  id : symbol?
  start : finite-real? = 0
  end : finite-real? = (* 2 pi)
  samples : (and/c exact-integer? (>=/c 2)) = 240
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
  stroke : any/c = "crimson"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
  fill : any/c = #f
Evenly samples (radius-function theta) from start through end and returns an ordinary open path. Each result must be a finite real, but it may be negative. Sampling is uniform in angle, not adaptive or arc-length parameterized.

19.24 Coordinate and Calculus Helpers🔗ℹ

SCENE-CP provides static, axes-aware construction helpers for common teaching diagrams. They evaluate numeric procedures during construction and return ordinary immutable Visuals or points. For an animated construction, place one of these calls inside derived-visual and rebuild it from the sampled parameter value.

procedure

(graph-point axes function x)  vec2?

  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x : finite-real?
Evaluates function at numeric x and converts the resulting coordinate through axes-coordinates->point. The result is in the axes’ containing world coordinate system.

procedure

(graph-label axes    
  function    
  x    
  label    
  #:id id    
  [#:offset offset    
  #:font-size font-size    
  #:color color])  text-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x : finite-real?
  label : string?
  id : symbol?
  offset : vec2? = (vec2 1/5 1/5)
  font-size : finite-real? = 1/4
  color : any/c = "black"
Creates plain text at (graph-point axes function x) plus the world-space offset.

procedure

(vertical-line-to-graph axes 
  function 
  x 
  #:id id 
  [#:baseline baseline 
  #:opacity opacity 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x : finite-real?
  id : symbol?
  baseline : finite-real? = 0
  opacity : opacity? = 1
  stroke : any/c = "gray"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates the axes-aware vertical projection from (x, baseline) to (x, function(x)). On a logarithmic y axis, the default baseline is the minimum visible y value rather than zero.

procedure

(horizontal-line-to-graph axes 
  function 
  x 
  #:id id 
  [#:baseline baseline 
  #:opacity opacity 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x : finite-real?
  id : symbol?
  baseline : finite-real? = 0
  opacity : opacity? = 1
  stroke : any/c = "gray"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Creates the horizontal projection from (baseline, function(x)) to the graph point. On a logarithmic x axis, the default baseline is the minimum visible x value.

procedure

(tangent-line axes    
  function    
  x    
  #:id id    
  [#:dx dx    
  #:length length    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x : finite-real?
  id : symbol?
  dx : (and/c finite-real? (>/c 0)) = 1/100
  length : (and/c finite-real? (>/c 0)) = 2
  opacity : opacity? = 1
  stroke : any/c = "crimson"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Estimates a tangent with the symmetric numeric difference at x. The visible segment has world-space length and is centred on the graph point. It is a numeric approximation, not symbolic differentiation.

procedure

(secant-line axes    
  function    
  x    
  dx    
  #:id id    
  [#:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x : finite-real?
  dx : (and/c finite-real? (not/c zero?))
  id : symbol?
  opacity : opacity? = 1
  stroke : any/c = "darkorange"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Connects the graph points at x and (+ x dx).

procedure

(secant-slope-group axes 
  function 
  x 
  dx 
  #:id id 
  [#:opacity opacity 
  #:secant-stroke secant-stroke 
  #:guide-stroke guide-stroke 
  #:stroke-width stroke-width 
  #:marker-radius marker-radius]) 
  group-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x : finite-real?
  dx : (and/c finite-real? (not/c zero?))
  id : symbol?
  opacity : opacity? = 1
  secant-stroke : any/c = "darkorange"
  guide-stroke : any/c = "gray"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
  marker-radius : (and/c finite-real? (>/c 0)) = 1/10
Builds a secant, endpoint markers, dashed Δx/Δy legs, and labels. Its stable children are named from id: id-secant, id-delta-x, id-delta-y, id-first-point, id-second-point, and the two corresponding label names.

procedure

(area-under-graph axes    
  function    
  #:id id    
  [#:x-min x-min    
  #:x-max x-max    
  #:baseline baseline    
  #:sample-count sample-count    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  id : symbol?
  x-min : (or/c finite-real? false/c) = #f
  x-max : (or/c finite-real? false/c) = #f
  baseline : finite-real? = 0
  sample-count : (and/c exact-integer? (>=/c 2)) = 101
  opacity : opacity? = 2/5
  fill : any/c = "cornflowerblue"
  stroke : any/c = #f
  stroke-width : (and/c finite-real? (>=/c 0)) = 0
Samples one finite function and closes the result to baseline. The result copies the current axes transform and uses one closed path subpath.

procedure

(area-between-curves axes 
  first-function 
  second-function 
  #:id id 
  [#:x-min x-min 
  #:x-max x-max 
  #:sample-count sample-count 
  #:opacity opacity 
  #:fill fill 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  path-visual?
  axes : axes-visual?
  first-function : (procedure-arity-includes/c 1)
  second-function : (procedure-arity-includes/c 1)
  id : symbol?
  x-min : (or/c finite-real? false/c) = #f
  x-max : (or/c finite-real? false/c) = #f
  sample-count : (and/c exact-integer? (>=/c 2)) = 101
  opacity : opacity? = 2/5
  fill : any/c = "mediumpurple"
  stroke : any/c = #f
  stroke-width : (and/c finite-real? (>=/c 0)) = 0
Samples two finite functions over one domain and returns their closed filled band in axes-local geometry.

procedure

(riemann-rectangles axes    
  function    
  #:id id    
  [#:x-min x-min    
  #:x-max x-max    
  #:count count    
  #:baseline baseline    
  #:opacity opacity    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  id : symbol?
  x-min : (or/c finite-real? false/c) = #f
  x-max : (or/c finite-real? false/c) = #f
  count : exact-positive-integer? = 8
  baseline : finite-real? = 0
  opacity : opacity? = 2/5
  fill : any/c = "seagreen"
  stroke : any/c = "darkgreen"
  stroke-width : (and/c finite-real? (>=/c 0)) = 1
Creates one closed midpoint rectangle per display-space interval. On a logarithmic x axis the rectangles are evenly spaced in log display coordinates, not by raw numeric width.

19.25 Coordinate Curves and Plots🔗ℹ

The procedures in this section convert ordered numeric coordinates to semantic path geometry. They use the local coordinate system of an axes Visual. They do not store a sampling procedure or a caller-owned point list in the result.

19.25.1 Interpolation Modes🔗ℹ

procedure

(curve-interpolation? value)  boolean?

  value : any/c
Returns #t when value is one of these symbols:

  • 'linear connects each accepted pair with a line segment.

  • 'smooth creates cubic Bézier segments that pass through all accepted samples in order.

Every public coordinate-plot procedure uses 'linear by default. An unsupported symbol or another value returns #f.

Smooth interpolation is applied separately to every accepted run. Suppose one run contains points P0 through Pn. For a segment from Pi to Pi+1, the usual interior control points are:

C1 = Pi + (Pi+1 - Pi-1) / 6

C2 = Pi+1 + (Pi - Pi+2) / 6

At an end of a run, the endpoint is repeated for the missing neighboring point. A run containing exactly two points uses a line-equivalent cubic whose controls are one third and two thirds of the way along the segment. The result therefore follows the same traversal order and reaches every accepted sample.

When clipping is enabled, sample pairs are clipped as line segments before smooth interpolation is calculated. Generated control points are then clamped to the closed axes rectangle. A cubic Bézier curve lies inside the convex hull of its endpoints and controls, so the resulting visible curve stays inside the rectangle. Clamping may reduce smoothness where a run touches a boundary.

19.25.2 Sampled Curves and Fields🔗ℹ

procedure

(sample-implicit-path axes    
  field    
  [#:level level    
  #:x-count x-count    
  #:y-count y-count])  path-geometry?
  axes : axes-visual?
  field : (procedure-arity-includes/c 2)
  level : finite-real? = 0
  x-count : (and/c exact-integer? (>=/c 2)) = 65
  y-count : (and/c exact-integer? (>=/c 2)) = 65
Samples a two-argument scalar field with deterministic marching squares and returns axes-local open contour segments where the field equals level. Adjacent cell segments are stitched into deterministic open or closed subpaths. Non-finite field samples create gaps. The result is immutable path geometry and does not retain the callback.

procedure

(implicit-curve axes    
  field    
  #:id id    
  [#:level level    
  #:x-count x-count    
  #:y-count y-count    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  axes : axes-visual?
  field : (procedure-arity-includes/c 2)
  id : symbol?
  level : finite-real? = 0
  x-count : (and/c exact-integer? (>=/c 2)) = 65
  y-count : (and/c exact-integer? (>=/c 2)) = 65
  opacity : opacity? = 1
  stroke : any/c = "darkorange"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Constructs a styled path Visual from sample-implicit-path, copying the current axes transform as a semantic snapshot.

procedure

(vector-field axes    
  field    
  #:id id    
  [#:x-count x-count    
  #:y-count y-count    
  #:scale scale    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:tip-length tip-length    
  #:tip-width tip-width])  group-visual?
  axes : axes-visual?
  field : (procedure-arity-includes/c 2)
  id : symbol?
  x-count : (and/c exact-integer? (>=/c 1)) = 9
  y-count : (and/c exact-integer? (>=/c 1)) = 7
  scale : finite-real? = 1/4
  opacity : opacity? = 1
  stroke : any/c = "seagreen"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
  tip-length : (and/c finite-real? (>/c 0)) = 3/20
  tip-width : (and/c finite-real? (>/c 0)) = 1/8
Samples field over a closed numeric axes grid. The procedure receives numeric x/y coordinates and must return exactly one vec2 vector. Each nonzero result becomes an arrow; zero vectors are omitted. The returned immutable group has stable child identities and can therefore use nested paths for lookup and animation. Sampling and axes transforms are captured at construction time; the group retains no procedure or renderer state.

19.26 Deterministic ODE Flow and Streamlines🔗ℹ

SCENE-DC turns a two-dimensional vector field into reproducible integral-curve geometry. A two-argument field is autonomous; a three-argument field receives time first. Fixed-step fourth-order Runge–Kutta (RK4) remains the default, with the caller selecting the step size and number of streamline steps. Neither the direct numerical solver nor a prepared trajectory depends on a prior rendered frame. prepare-ode-trajectory stores immutable canonical RK4 checkpoints, so an animated particle does not recompute the complete seed-to-time prefix for every frame. The renderer batches selected frame times by checkpoint interval, sharing each interval’s full RK4 suffix steps.

SCENE-DN adds an optional deterministic adaptive Dormand–Prince 5(4) backend. It stores accepted endpoint derivatives for cubic Hermite dense lookup, accepts time-dependent fields, can stop at one scalar sign-crossing event, and records immutable diagnostics. Once an adaptive trajectory is prepared, dense lookup and frame rendering never invoke the author field.

SCENE-3D-K factors the numerical operations behind both trajectory families into an immutable ode-state-space. The built-in real-ode-state-space, vec2-ode-state-space, and vec3-ode-state-space values make the shared RK4 and RK45 algorithms explicit; (numeric-vector-ode-state-space n) creates a fixed-length immutable numeric-vector state space. These values are useful when building a numerical extension, while the ordinary two-dimensional and spatial trajectory constructors remain the author-facing API.

struct

(struct ode-state-space (dimension
    add
    subtract
    scale
    norm
    interpolate
    finite?)
    #:transparent)
  dimension : exact-positive-integer?
  add : procedure?
  subtract : procedure?
  scale : procedure?
  norm : procedure?
  interpolate : procedure?
  finite? : procedure?
Describes finite vector-space operations for the shared solver kernel. Its procedures must consistently operate on the declared dimension; finite? recognizes the immutable state representation. Prepared numeric-vector states are immutable to prevent a retained mutable input from changing a trajectory.
The one-dimensional real state space.
The two-dimensional vec2 state space.
The three-dimensional vec3 state space.

procedure

(numeric-vector-ode-state-space dimension)  ode-state-space?

  dimension : exact-positive-integer?
Creates a space whose states are immutable vectors of exactly dimension finite reals.

procedure

(ode-flow-position field    
  seed    
  time    
  [#:step-size step-size])  vec2?
  field : 
(or/c (procedure-arity-includes/c 2)
      (procedure-arity-includes/c 3))
  seed : vec2?
  time : finite-real?
  step-size : (and/c finite-real? positive?) = 1/20
Returns the RK4 solution beginning at coordinate-space seed at time zero and integrated through signed time. A two-argument field receives numeric coordinate x and y values; a three-argument field receives time, x, and y. It must return one finite vec2 derivative. A positive time advances the field; a negative time integrates it backwards.

The final partial step is included, so the requested time is reached exactly in ordinary arithmetic rather than rounded to a step-grid endpoint. This is a fixed-step solver, not an adaptive tolerance-controlled integrator.

procedure

(adaptive-rk45 [#:relative-tolerance relative-tolerance 
  #:absolute-tolerance absolute-tolerance 
  #:initial-step initial-step 
  #:minimum-step minimum-step 
  #:maximum-step maximum-step 
  #:maximum-steps maximum-steps]) 
  adaptive-rk45?
  relative-tolerance : (and/c finite-real? positive?) = 1e-6
  absolute-tolerance : (and/c finite-real? positive?) = 1e-8
  initial-step : (and/c finite-real? positive?) = 1/10
  minimum-step : (and/c finite-real? positive?) = 1e-8
  maximum-step : (and/c finite-real? positive?) = 1
  maximum-steps : exact-positive-integer? = 100000
Creates immutable configuration for the deterministic Dormand–Prince embedded 5(4) adaptive solver. The step bounds must satisfy minimum-step <= initial-step <= maximum-step. The relative and absolute tolerances form the usual componentwise scale atol + rtol * max (abs (previous) ,abs (candidate)).

procedure

(adaptive-rk45? value)  boolean?

  value : any/c
Recognizes immutable adaptive Dormand–Prince solver configuration.

procedure

(ode-event function    
  [#:direction direction    
  #:name name])  ode-event?
  function : 
(or/c (procedure-arity-includes/c 2)
      (procedure-arity-includes/c 3))
  direction : (or/c 'any 'increasing 'decreasing) = 'any
  name : symbol? = 'event
Creates one terminal scalar event for adaptive preparation. Like a field, function accepts either (x y) or (time x y) and must return one finite real. A sign crossing ends the trajectory; increasing and decreasing select the crossing orientation. The root is located by deterministic bisection over the accepted step’s cubic dense output.

procedure

(ode-event? value)  boolean?

  value : any/c
Recognizes an adaptive terminal event declaration.

procedure

(ode-trajectory? value)  boolean?

  value : any/c
Returns #t for an immutable prepared fixed-RK4 or adaptive-RK45 trajectory.

procedure

(prepare-ode-trajectory field 
  seed 
  #:time-range time-range 
  [#:step-size step-size 
  #:checkpoint-every checkpoint-every 
  #:solver solver 
  #:event event]) 
  ode-trajectory?
  field : 
(or/c (procedure-arity-includes/c 2)
      (procedure-arity-includes/c 3))
  seed : vec2?
  time-range : (cons/c finite-real? finite-real?)
  step-size : (and/c finite-real? positive?) = 1/20
  checkpoint-every : exact-positive-integer? = 16
  solver : (or/c false/c adaptive-rk45?) = #f
  event : (or/c false/c ode-event?) = #f
Prepares a closed time range expressed as (cons start-time end-time), where start-time is at most end-time. The trajectory stores immutable states at canonical multiples of step-size, spaced by checkpoint-every full steps in both the positive and negative directions from the seed at time zero.

For a lookup, the trajectory begins at the preceding checkpoint between zero and the requested time, takes fewer than checkpoint-every full steps, and then takes the usual final remainder step. It therefore preserves the fixed-RK4 numerical meaning of ode-flow-position without repeating a long prefix for each frame.

The field must be pure and stable for the lifetime of the prepared value. The library cannot determine whether an arbitrary Racket procedure’s captured state has changed.

When solver is #f, this is the established fixed-RK4 checkpoint trajectory. event is then rejected. With an adaptive-rk45? value, accepted Dormand–Prince endpoint positions and derivatives are stored instead. event, when supplied, truncates the actual supported range at its dense scalar root.

procedure

(ode-trajectory-time-range trajectory)

  (cons/c finite-real? finite-real?)
  trajectory : ode-trajectory?
Returns the supported closed time range. For a trajectory stopped by an adaptive event, the relevant endpoint is the detected dense root rather than the original requested boundary.

procedure

(ode-trajectory-step-size trajectory)

  (or/c (and/c finite-real? positive?) false/c)
  trajectory : ode-trajectory?
Returns the fixed RK4 step size, or #f for an adaptive trajectory.

procedure

(ode-trajectory-checkpoint-every trajectory)

  (or/c exact-positive-integer? false/c)
  trajectory : ode-trajectory?
Returns the number of full RK4 steps between stored canonical checkpoints, or #f for an adaptive trajectory.

procedure

(ode-trajectory-solver trajectory)

  (or/c 'fixed-rk4 adaptive-rk45?)
  trajectory : ode-trajectory?
Returns 'fixed-rk4 for the established checkpoint backend or the immutable adaptive-rk45? value that prepared an adaptive trajectory.

procedure

(ode-trajectory-diagnostics trajectory)

  (or/c false/c ode-trajectory-diagnostics?)
  trajectory : ode-trajectory?
Returns #f for fixed RK4. An adaptive trajectory returns transparent diagnostics containing solver name, accepted and rejected step counts, termination time/reason, and the maximum componentwise scaled embedded error. The error is a local control diagnostic, not a global proof of solution error.

procedure

(ode-trajectory-diagnostics? value)  boolean?

  value : any/c
Recognizes the immutable diagnostics returned for a prepared adaptive ODE trajectory.

procedure

(ode-trajectory-position trajectory time)  vec2?

  trajectory : ode-trajectory?
  time : finite-real?
Returns the prepared position at time. Fixed trajectories reproduce the existing checkpoint/remainder RK4 path. Adaptive trajectories use stored cubic Hermite dense output and do not call the field. The time must lie inside the actual supported range, which may end early at an event root.

procedure

(streamline-points field    
  seed    
  [#:direction direction    
  #:step-size step-size    
  #:steps steps])  (listof vec2?)
  field : 
(or/c (procedure-arity-includes/c 2)
      (procedure-arity-includes/c 3))
  seed : vec2?
  direction : (or/c 'forward 'backward 'both) = 'both
  step-size : (and/c finite-real? positive?) = 1/20
  steps : exact-positive-integer? = 120
Returns the coordinate-space RK4 samples for one streamline. 'forward goes from time zero through positive time; 'backward returns points in increasing geometric order from negative time to the seed; 'both combines both directions without duplicating the seed.

procedure

(streamline axes    
  field    
  seed    
  #:id id    
  [#:direction direction    
  #:step-size step-size    
  #:steps steps    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  axes : axes-visual?
  field : 
(or/c (procedure-arity-includes/c 2)
      (procedure-arity-includes/c 3))
  seed : vec2?
  id : symbol?
  direction : (or/c 'forward 'backward 'both) = 'both
  step-size : (and/c finite-real? positive?) = 1/20
  steps : exact-positive-integer? = 120
  opacity : opacity? = 1
  stroke : any/c = "royalblue"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Converts streamline-points through axes into one ordinary world-space path Visual. The axes conversion is captured when the streamline is constructed. It does not clip, stop at axes bounds, or retain the field procedure after construction.

procedure

(streamlines axes    
  field    
  seeds    
  #:id id    
  [#:direction direction    
  #:step-size step-size    
  #:steps steps    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  group-visual?
  axes : axes-visual?
  field : 
(or/c (procedure-arity-includes/c 2)
      (procedure-arity-includes/c 3))
  seeds : (listof vec2?)
  id : symbol?
  direction : (or/c 'forward 'backward 'both) = 'both
  step-size : (and/c finite-real? positive?) = 1/20
  steps : exact-positive-integer? = 120
  opacity : opacity? = 1
  stroke : any/c = "royalblue"
  stroke-width : (and/c finite-real? (>=/c 0)) = 2
Builds an ordinary group of streamline paths. Seed number n becomes the direct child named by id-n; for example, the first child of 'flow is reachable at '(flow flow-0).

procedure

(flow-particle axes    
  trajectory    
  phase    
  #:id id    
  [#:shape shape    
  #:size size    
  #:fill fill    
  #:stroke stroke    
  #:stroke-width stroke-width    
  #:opacity opacity])  derived-visual?
  axes : axes-visual?
  trajectory : ode-trajectory?
  phase : (or/c symbol? scene-parameter?)
  id : symbol?
  shape : point-marker-shape? = 'circle
  size : (and/c finite-real? positive?) = 1/5
  fill : any/c = "crimson"
  stroke : any/c = "black"
  stroke-width : (and/c finite-real? (>=/c 0)) = 1
  opacity : opacity? = 1
Creates a parameter-driven point marker. At every scene sample, phase’s finite real value selects a position from trajectory, which is then converted through axes. The phase must remain within the trajectory’s declared range.

Before render-frames! creates frame workers, it samples all requested phase values and freezes the corresponding particle coordinates in an immutable table. The preparation pass walks each used checkpoint interval once, sharing full RK4 suffix steps among its selected times. Workers only read those coordinates; they never call the author field. Direct arbitrary-time scene sampling remains deterministic through ode-trajectory-position.

For an adaptive trajectory, the preparation pass instead reads its stored dense output directly; no numerical integration or field call occurs after the trajectory has been prepared.

procedure

(sample-function-path 
  axes 
  function 
  [#:x-min x-min 
  #:x-max x-max 
  #:sample-count sample-count 
  #:clip? clip? 
  #:max-jump max-jump 
  #:detect-discontinuities? detect-discontinuities? 
  #:interpolation interpolation]) 
  path-geometry?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x-min : (or/c finite-real? false/c) = #f
  x-max : (or/c finite-real? false/c) = #f
  sample-count : (and/c exact-integer? (>=/c 2)) = 201
  clip? : boolean? = #t
  max-jump : 
(or/c false/c
      (and/c finite-real? (>=/c 0)))
 = #f
  detect-discontinuities? : boolean? = #f
  interpolation : curve-interpolation? = 'linear
Samples function at sample-count uniformly spaced x values in increasing order. The closed interval includes both endpoints. When x-min or x-max is #f, the corresponding bound comes from (axes-visual-x-range axes). The resolved minimum must be less than the resolved maximum. Their difference must remain a positive finite real.

For a logarithmic x axis, spacing is uniform in the selected base-logarithm display coordinate instead. Thus a base-ten range from one through one thousand samples successive decades evenly. Explicit x-min and x-max bounds follow the same rule and must be strictly positive on a log axis.

All arguments are checked before function is called. When sampling completes without an error, the function is called exactly once for each sample x value. Sampling stops at the first invalid result or exception. Each call must return exactly one value. That value has these meanings:

  • A finite real is one numeric y sample.

  • #f is an explicit gap and breaks the current run.

  • Positive infinity, negative infinity, and NaN also create a gap.

  • Any other result raises an exception that reports the x value and the returned value.

Returning zero values or more than one value raises an exception that reports the x value and result count. An exception raised by function is not converted to a gap. It is reported together with the sample x value and the original exception message. This keeps programming errors separate from explicit discontinuities.

When max-jump is a number, two adjacent finite samples are connected only when the absolute difference between their numeric y values is no greater than that number. The threshold is applied before axes scaling and before clipping. The default #f performs no jump rejection. Use an explicit #f result when the location of a discontinuity is known.

When clip? is true, every accepted sample pair is clipped to the closed rectangle described by the axes x and y ranges. Clipping is performed on segments, so an intersection with a boundary becomes an exact path endpoint when exact arithmetic permits it. When an inexact coordinate difference would overflow, clipping temporarily uses the exact represented input values. When clip? is false, finite out-of-range samples remain in the path. Clipping does not decide whether a segment crossing the rectangle is a true discontinuity.

The interpolation argument controls the path segment kind as described by curve-interpolation?. Linear interpolation stores line segments. Smooth interpolation stores cubic Bézier segments through each accepted run. Breaks from non-finite values, explicit #f results, maximum-jump rejection, or clipping keep the runs separate.

When detect-discontinuities? is true, two adjacent samples that lie beyond opposite sides of the visible numeric y interval are treated as the hidden sides of a vertical asymptote and are not connected. This opt-in rule prevents clipping from drawing a false segment through the plot window while preserving the historical default behavior for steep continuous graphs.

The result contains zero or more open subpaths in sampling order. An isolated finite sample with no accepted adjacent pair does not create a point-only subpath. Every stored point uses the untransformed local coordinate system of axes. Numeric x is multiplied by axes-x-unit-length, and numeric y is multiplied by axes-y-unit-length. The axes translation, rotation, and scale are not applied to the returned geometry.

The sampling grid is deterministic. Exact bounds produce exact rational intermediate x values when ordinary exact arithmetic permits it. The result contains only immutable path geometry. Rendering it later does not call function again.

procedure

(function-graph 
  axes 
  function 
  #:id id 
  [#:x-min x-min 
  #:x-max x-max 
  #:sample-count sample-count 
  #:clip? clip? 
  #:max-jump max-jump 
  #:detect-discontinuities? detect-discontinuities? 
  #:interpolation interpolation 
  #:opacity opacity 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  id : symbol?
  x-min : (or/c finite-real? false/c) = #f
  x-max : (or/c finite-real? false/c) = #f
  sample-count : (and/c exact-integer? (>=/c 2)) = 201
  clip? : boolean? = #t
  max-jump : 
(or/c false/c
      (and/c finite-real? (>=/c 0)))
 = #f
  detect-discontinuities? : boolean? = #f
  interpolation : curve-interpolation? = 'linear
  opacity : opacity? = 1
  stroke : any/c = "royalblue"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Calls sample-function-path with the same axes, function, interval, sample count, clipping, jump, discontinuity detection, and interpolation arguments. It wraps the result in a built-in path Visual.

The graph copies the current translation, rotation, and scale of axes. Its local geometry already uses the axes x and y unit lengths, so the graph and axes coincide at construction time even when the axes are translated, rotated, or non-uniformly scaled. This is a snapshot. Updating either immutable Visual later does not update the other. Put both in a group or apply matching animation requests when they should continue to move together.

The graph has no fill. The identity, opacity, and stroke width are checked before the numeric function is called. stroke and stroke-width are used by the ordinary path renderer. The result works with create, uncreate, path replacement, movement, rotation, non-uniform scaling, fading, groups, layout, and custom path renderers. There is no graph-specific renderer or timeline request.

procedure

(sample-adaptive-function-path 
  axes 
  function 
  [#:x-min x-min 
  #:x-max x-max 
  #:initial-sample-count initial-sample-count 
  #:max-deviation max-deviation 
  #:max-depth max-depth 
  #:clip? clip? 
  #:max-jump max-jump 
  #:detect-discontinuities? detect-discontinuities? 
  #:excluded-intervals excluded-intervals 
  #:interpolation interpolation]) 
  path-geometry?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  x-min : (or/c finite-real? false/c) = #f
  x-max : (or/c finite-real? false/c) = #f
  initial-sample-count : (and/c exact-integer? (>=/c 2)) = 17
  max-deviation : (and/c finite-real? (>=/c 0)) = 1/100
  max-depth : (and/c exact-integer? (>=/c 0)) = 12
  clip? : boolean? = #t
  max-jump : (or/c false/c (and/c finite-real? (>=/c 0))) = #f
  detect-discontinuities? : boolean? = #t
  excluded-intervals : list? = '()
  interpolation : curve-interpolation? = 'linear
Samples function adaptively. The procedure first evaluates a deterministic, display-uniform grid of initial-sample-count points, then recursively evaluates each interval’s display-space midpoint. An interval is split while its midpoint differs from the chord midpoint by more than max-deviation in untransformed axes-local world units. Refinement stops after max-depth splits per initial interval, so the deviation threshold is a target rather than a guaranteed global bound.

The x-coordinate rule is the same as sample-function-path: linear axes use arithmetic interpolation and log axes use uniform logarithmic display interpolation. Callback values follow the same finite-real/#f/nonfinite rules, except that an exact numeric division-by-zero exception is treated as a gap. Other callback exceptions are reported with their x value.

With detect-discontinuities? true, an interval whose adjacent samples lie beyond opposite visible y boundaries is refined and ultimately broken, rather than clipped through the axes. max-jump adds an independent numeric y-distance break rule. excluded-intervals is a list of either (cons minimum maximum) or (list minimum maximum) values; each finite increasing interval splits the domain and no segment crosses its interior. Overlapping exclusions are merged deterministically.

The result uses the ordinary clipping and linear/smooth path interpolation machinery. It contains immutable axes-local geometry and retains neither the function nor adaptive evaluation cache. No finite initial grid can detect an oscillation that aliases every one of its samples; raise initial-sample-count for that case.

procedure

(adaptive-function-graph 
  axes 
  function 
  #:id id 
  [#:x-min x-min 
  #:x-max x-max 
  #:initial-sample-count initial-sample-count 
  #:max-deviation max-deviation 
  #:max-depth max-depth 
  #:clip? clip? 
  #:max-jump max-jump 
  #:detect-discontinuities? detect-discontinuities? 
  #:excluded-intervals excluded-intervals 
  #:interpolation interpolation 
  #:opacity opacity 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  id : symbol?
  x-min : (or/c finite-real? false/c) = #f
  x-max : (or/c finite-real? false/c) = #f
  initial-sample-count : (and/c exact-integer? (>=/c 2)) = 17
  max-deviation : (and/c finite-real? (>=/c 0)) = 1/100
  max-depth : (and/c exact-integer? (>=/c 0)) = 12
  clip? : boolean? = #t
  max-jump : (or/c false/c (and/c finite-real? (>=/c 0))) = #f
  detect-discontinuities? : boolean? = #t
  excluded-intervals : list? = '()
  interpolation : curve-interpolation? = 'linear
  opacity : opacity? = 1
  stroke : any/c = "royalblue"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Calls sample-adaptive-function-path and wraps the result in the same immutable axes-transform snapshot as function-graph. The graph is an ordinary path Visual: it can be created, morphed, faded, moved, or grouped by the existing animation API.

procedure

(derived-function-graph 
  axes 
  field 
  #:id id 
  [#:x-min x-min 
  #:x-max x-max 
  #:sample-count sample-count 
  #:clip? clip? 
  #:max-jump max-jump 
  #:detect-discontinuities? detect-discontinuities? 
  #:interpolation interpolation 
  #:opacity opacity 
  #:stroke stroke 
  #:stroke-width stroke-width]) 
  derived-visual?
  axes : axes-visual?
  field : (procedure-arity-includes/c 2)
  id : symbol?
  x-min : (or/c finite-real? false/c) = #f
  x-max : (or/c finite-real? false/c) = #f
  sample-count : (and/c exact-integer? (>=/c 2)) = 201
  clip? : boolean? = #t
  max-jump : 
(or/c false/c
      (and/c finite-real? (>=/c 0)))
 = #f
  detect-discontinuities? : boolean? = #f
  interpolation : curve-interpolation? = 'linear
  opacity : opacity? = 1
  stroke : any/c = "royalblue"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Creates a pure derived function graph. field receives the sampled derived-context? first and one numeric x coordinate second. It must return the same one-value result accepted by function-graph. The ordinary graph options have the same meanings as in function-graph.

For each resolved scene state, the field is sampled anew and produces one concrete path Visual with the requested identity, style, and axes transform. This permits an immutable parameter or another resolved Visual to drive a plot without a mutable updater. As with any derived-visual?, animate its source values or dependencies rather than applying a direct Visual animation to the derived graph.

19.26.1 Parametric Curves🔗ℹ

struct

(struct parameter-range (start end)
    #:transparent)
  start : finite-real?
  end : finite-real?
Represents one ordered closed parameter domain. The fields have these meanings:

  • start is the first parameter passed to a sampling procedure.

  • end is the last parameter passed to a sampling procedure.

The values must be distinct finite reals. The computed difference (- end start) must also remain a nonzero finite real. The order is significant. When start is greater than end, sampling proceeds in decreasing order.

The structure is immutable and transparent. Its public bindings include parameter-range, parameter-range?, both field accessors, and struct:parameter-range.

procedure

(sample-parametric-path axes 
  function 
  [#:parameter-range domain 
  #:sample-count sample-count 
  #:clip? clip? 
  #:max-distance max-distance 
  #:interpolation interpolation]) 
  path-geometry?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  domain : parameter-range? = (parameter-range 0 1)
  sample-count : (and/c exact-integer? (>=/c 2)) = 201
  clip? : boolean? = #t
  max-distance : 
(or/c false/c
      (and/c finite-real? (>=/c 0)))
 = #f
  interpolation : curve-interpolation? = 'linear
Samples function at sample-count uniformly spaced parameter values from (parameter-range-start domain) through (parameter-range-end domain). Both endpoints are included exactly as stored. Intermediate values follow the same increasing or decreasing order. Exact endpoints produce exact rational intermediate values when ordinary exact arithmetic permits it.

All arguments are checked before function is called. Each sampling call must return exactly one value:

  • A vec2 is one finite numeric coordinate.

  • #f is an explicit gap.

Another value, zero values, or multiple values raise an exception that reports the parameter value. An exception from function is reported with the same parameter and the original exception message. Sampling stops at the first error.

When max-distance is a number, two adjacent coordinates are connected only when their Euclidean distance in numeric-coordinate units is no greater than that number. The distance is measured before independent axes scaling. The default #f applies no distance rejection.

Clipping and interpolation follow the common rules described above. The result contains axes-local open subpaths and does not retain function or domain. Empty runs and isolated finite coordinates produce no drawn segment.

procedure

(parametric-curve axes    
  function    
  #:id id    
  [#:parameter-range domain    
  #:sample-count sample-count    
  #:clip? clip?    
  #:max-distance max-distance    
  #:interpolation interpolation    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  axes : axes-visual?
  function : (procedure-arity-includes/c 1)
  id : symbol?
  domain : parameter-range? = (parameter-range 0 1)
  sample-count : (and/c exact-integer? (>=/c 2)) = 201
  clip? : boolean? = #t
  max-distance : 
(or/c false/c
      (and/c finite-real? (>=/c 0)))
 = #f
  interpolation : curve-interpolation? = 'linear
  opacity : opacity? = 1
  stroke : any/c = "royalblue"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Calls sample-parametric-path with the same sampling arguments and wraps the result in an ordinary path Visual. Identity, opacity, and stroke width are checked before the sampling procedure is called.

The returned path has no fill and copies the current axes translation, rotation, and scale. This is a construction-time snapshot, not a live link. The result can use every operation available to an ordinary path Visual, including create, uncreate, morphing, affine animation, opacity, groups, and renderer-aware layout.

19.26.2 Ordered Data Plots🔗ℹ

procedure

(data-series-path axes 
  points 
  [#:clip? clip? 
  #:max-distance max-distance 
  #:interpolation interpolation]) 
  path-geometry?
  axes : axes-visual?
  points : (listof (or/c vec2? false/c))
  clip? : boolean? = #t
  max-distance : 
(or/c false/c
      (and/c finite-real? (>=/c 0)))
 = #f
  interpolation : curve-interpolation? = 'linear
Converts points to axes-local path geometry. The input must be a proper list containing only vec2 values and #f. A vec2 is one numeric coordinate. #f is an explicit gap.

List order is traversal order. The procedure does not sort by x, infer time order, remove repeated coordinates, or retain the input list. An empty list, a one-point list, or a finite coordinate isolated by gaps produces no drawn segment.

The max-distance, clip?, and interpolation arguments have the same meanings as for sample-parametric-path. Distance is Euclidean in numeric-coordinate units. The result contains only immutable path geometry.

procedure

(data-plot axes    
  points    
  #:id id    
  [#:clip? clip?    
  #:max-distance max-distance    
  #:interpolation interpolation    
  #:opacity opacity    
  #:stroke stroke    
  #:stroke-width stroke-width])  path-visual?
  axes : axes-visual?
  points : (listof (or/c vec2? false/c))
  id : symbol?
  clip? : boolean? = #t
  max-distance : 
(or/c false/c
      (and/c finite-real? (>=/c 0)))
 = #f
  interpolation : curve-interpolation? = 'linear
  opacity : opacity? = 1
  stroke : any/c = "seagreen"
  stroke-width : (and/c finite-real? (>=/c 0)) = 3
Calls data-series-path with the same point, clipping, distance, and interpolation arguments and wraps the result in an ordinary path Visual. Identity, opacity, and stroke width are checked before the point series is converted.

The returned path has no fill and copies the axes translation, rotation, and scale at construction time. It works with ordinary path rendering, creation, removal, morphing, movement, rotation, non-uniform scaling, fading, groups, and relative layout.

19.27 Group Visuals🔗ℹ

A group is a semantic composite. Its children are stored as ordinary Visual values, not as Picts. The child list is significant back-to-front order. Child positions are local to the group anchor.

All children must implement both gen:visual and gen:affine-visual. Circles, rectangles, paths, function graphs, parametric curves, data plots, arrows, axes, plain text, formulas, and groups all satisfy this requirement. A child may itself be a group. Direct siblings must have distinct identities, and a group identity may not occur anywhere below that group. The same child identity may be reused in separate nested branches; its complete Visual path identifies it unambiguously. A custom affine Visual is treated as one leaf because there is no public protocol for inspecting children hidden inside it.

procedure

(group children    
  #:id id    
  [#:center center    
  #:rotation rotation    
  #:scale scale    
  #:opacity opacity])  group-visual?
  children : (listof (and/c visual? affine-visual?))
  id : symbol?
  center : vec2? = origin
  rotation : finite-real? = 0
  scale : scale-factor? = 1
  opacity : opacity? = 1
Creates a semantic group with children in significant back-to-front order. An empty list creates a valid empty group.

The center value places the group anchor in its containing coordinate system. At the top level this is a world-space point. In a parent group it is a local point. Each child’s existing reference position is interpreted in the group’s local coordinates.

The group scale may be a positive finite scalar or a positive vec2, but its normalized x and y components must be equal. This uniform-scale restriction lets parent transforms compose exactly with rotated children without introducing shear. The group may be rotated by any finite angle.

The group opacity is applied to the complete composed result. Child opacity is applied first, so opacity is inherited multiplicatively through nested groups.

The constructor rejects a non-affine child, a nonsymbol child identity, a repeated identity anywhere in the built-in group tree, or a descendant whose identity equals id. For a custom affine child, its reported position must agree with the translation in its reported affine transform.

Nested children are addressed by nonempty paths such as '(parent child) for scene-state lookup and compatible animation requests. Their identity remains local to the containing group, so a bare child symbol is not a top-level scene identity.

procedure

(group-visual? value)  boolean?

  value : any/c
Returns #t when value is a built-in group Visual.

procedure

(group-visual-children group)

  (listof (and/c visual? affine-visual?))
  group : group-visual?
Returns the group’s children in significant back-to-front order. The returned Visuals use coordinates local to the group. The list is immutable model data.

procedure

(group-visual-with-children group children)  group-visual?

  group : group-visual?
  children : (listof (and/c visual? affine-visual?))
Returns a new group with children as its significant back-to-front child list. Identity, group transform, and opacity are preserved. The same child and identity validation as group is performed. The original group is unchanged.

19.28 First-Class Relation Visuals🔗ℹ

A relation is an immutable Visual whose concrete geometry is recomputed from explicit dependencies in each sampled scene state. It replaces the former split between pure endpoint geometry and renderer-aware endpoint wrappers. No relation uses a mutable updater or needs the preceding frame.

procedure

(relation-visual template    
  [#:depends-on dependencies    
  #:phase phase    
  #:structure structure    
  #:space space    
  #:cache-key cache-key]    
  resolver)  relation-visual?
  template : visual?
  dependencies : (listof relation-dependency?) = '()
  phase : (or/c 'semantic 'layout) = 'semantic
  structure : (or/c 'root-only 'fixed) = 'root-only
  space : (or/c 'world 'local) = 'world
  cache-key : any/c = #f
  resolver : (-> relation-context? visual? visual?)
Creates a relation with the stable identity of template. The resolver receives a read-only relation-context? and a local template, and must return one concrete Visual with the same identity. Every value, Visual, renderer-anchor, or semantic selection read through the context must be named in dependencies; undeclared reads fail descriptively.

The ordinary movement, rotation, scale, opacity, fill, stroke, and stroke-width controls form an outer envelope. They are applied after the resolver has computed the current geometry, so a relation may be animated concurrently with its own changing dependencies. A requested style must be supported by both the template and the concrete result. A 'fixed relation preserves the template’s complete child-ID tree and may expose nested paths; a 'root-only relation deliberately exposes only its root ID.

A 'semantic relation is resolved from model data. A 'layout relation may use relation-context-anchor-ref, relation-context-layout-box, or selection boxes after the active renderer has measured its targets. Layout relations are currently top-level only, and their measurements are complete Pict boxes rather than tight visible outlines.

procedure

(relation-context-layout-box context    
  visual)  layout-box?
  context : relation-context?
  visual : visual?
Measures one resolver-local concrete Visual in the active renderer/camera configuration. This operation is available only to layout relations. It is intended for relations such as follow-anchor that must align one anchor of their own content to an anchor of another Visual.

procedure

(relation-visual? value)  boolean?

  value : any/c
Recognizes an immutable relation Visual.

procedure

(relation-visual-dependencies relation)

  (listof relation-dependency?)
  relation : relation-visual?
Returns the relation’s explicitly declared dependencies in author order.

procedure

(relation-visual-cacheability relation)

  (or/c 'serializable 'explicit-key 'disabled)
  relation : relation-visual?
Reports whether the resolver can participate in a persistent cache. Built-in transparent specifications are 'serializable; an author procedure with #:cache-key is 'explicit-key; an opaque procedure is 'disabled.

procedure

(relation-dependency? value)  boolean?

  value : any/c
Recognizes a declared value, Visual, anchor, or selection dependency.

procedure

(relation-context? value)  boolean?

  value : any/c
Recognizes the read-only context supplied to a relation resolver.

procedure

(relation-context-anchor-ref context    
  target    
  anchor)  vec2?
  context : relation-context?
  target : (or/c visual? symbol? visual-path?)
  anchor : symbol?
Returns a renderer-measured anchor for a layout relation after recording the corresponding declared anchor-dependency.

procedure

(value-dependency target)  relation-dependency?

  target : (or/c symbol? scene-parameter?)
Declares one sampled scalar/value input.

procedure

(visual-dependency target)  relation-dependency?

  target : (or/c visual? symbol? visual-path?)
Declares one semantic Visual input.

procedure

(anchor-dependency target anchor)  relation-dependency?

  target : (or/c visual? symbol? visual-path?)
  anchor : symbol?
Declares one renderer-measured anchor input.

procedure

(selection-dependency selection)  relation-dependency?

  selection : visual-selection?
Declares one semantic selection input.

procedure

(scene-validate-relations state)  immutable-hash?

  state : scene-state?
Checks declared relation dependencies and reports missing targets or deterministic dependency cycles before rendering.

procedure

(scene-relation-report state [target])  any/c

  state : scene-state?
  target : (or/c #f visual? symbol? visual-path?) = #f
Returns deterministic relation-resolution report data without invoking author resolver procedures. It records full path, drawing order, phase, structure, declared dependencies, cacheability, and warnings. Library-owned serializable specifications are cacheable; generic resolver procedures remain opaque unless the author supplies #:cache-key.

procedure

(scene-relation-sample-report state [target])  any/c

  state : scene-state?
  target : (or/c #f visual? symbol? visual-path?) = #f
Returns the same report shape, but additionally resolves each selected 'semantic relation once for this sampled state. The report’s 'used-dependencies and 'unused-dependencies fields then distinguish declared inputs that the resolver actually read from declared inputs it did not read at this instant. This is an opt-in diagnostic operation: it can run the author’s resolver procedure, but does not alter the immutable scene state or renderer cache.

For a 'layout relation those fields are #f. Determining its actual reads requires the active renderer’s measured layout boxes, which this headless report intentionally does not invent.

Built-in line-between, arrow-between, ray-from, parameter-display, and follow-anchor use serializable relation specifications. The live angle, brace, and curved-arrow constructors use generic relations because their builder procedure is author-specific; therefore they deliberately do not claim automatic persistent-cache reuse.

procedure

(follow-anchor content 
  target 
  [#:offset offset 
  #:target-anchor target-anchor 
  #:self-anchor self-anchor]) 
  relation-visual?
  content : visual?
  target : (or/c visual? symbol? visual-path?)
  offset : vec2? = origin
  target-anchor : 
(or/c 'bottom-left 'bottom 'bottom-right
      'left 'center 'right
      'top-left 'top 'top-right)
   = 'center
  self-anchor : 
(or/c 'bottom-left 'bottom 'bottom-right
      'left 'center 'right
      'top-left 'top 'top-right)
   = 'center
Creates one world-space relation whose selected content anchor follows the selected sampled anchor of target, plus offset. target may be a top-level Visual, its symbol identity, or a nested path. The default centre-to-centre form is a semantic relation: it follows the target’s sampled reference point without invoking a renderer. Choosing a non-centre target or content anchor creates a layout relation, which measures the relevant Pict box in the active camera and renderer configuration. Both forms follow target motion without frame-mutating callbacks.

The content must be a concrete, non-frame-space Visual, and content and target must have distinct identities. Attachments may be animated through the normal relation envelope. One attachment may target another when the resulting relation graph is acyclic; they neither avoid other labels nor inherit target rotation. Layout attachments are top-level and renderer-dependent; a semantic centre attachment can be queried directly from a sampled scene state.

19.28.1 Acyclic Live Layout🔗ℹ

SCENE-DE gives the renderer-aware attachment model concise relationship names. Their relation graph is resolved from a concrete target outward at each render. A direct or indirect cycle raises an exception; no prior frame is consulted.

procedure

(follow-above content target [#:gap gap])  relation-visual?

  content : visual?
  target : (or/c visual? symbol? visual-path?)
  gap : (and/c finite-real? (>=/c 0)) = 0
Places the content’s bottom anchor at the target’s top anchor plus gap.

procedure

(follow-below content target [#:gap gap])  relation-visual?

  content : visual?
  target : (or/c visual? symbol? visual-path?)
  gap : (and/c finite-real? (>=/c 0)) = 0
Places the content’s top anchor at the target’s bottom anchor minus gap.

procedure

(follow-left-of content target [#:gap gap])  relation-visual?

  content : visual?
  target : (or/c visual? symbol? visual-path?)
  gap : (and/c finite-real? (>=/c 0)) = 0
Places the content’s right anchor at the target’s left anchor minus gap.

procedure

(follow-right-of content target [#:gap gap])  relation-visual?

  content : visual?
  target : (or/c visual? symbol? visual-path?)
  gap : (and/c finite-real? (>=/c 0)) = 0
Places the content’s left anchor at the target’s right anchor plus gap.