JMathAnim DSL Quick Reference
Note:
- All parameter keys are case-insensitive.
style:accepts either a Map or a String (style name).- Parameters that expect coordinates admit both
Coordinatesobjects (Vec,Point, etc.) or a list like[3,2].
Basics
shape(...)
| Type | Required params | Optional params |
|---|---|---|
circle |
— | segments |
square |
— | — |
rectangle |
from:[x,y], to:[x,y] |
— |
triangle |
— | — |
polygon |
points:[[x,y],...] |
— |
polyline |
points:[[x,y],...] |
— |
segment |
from:[x,y], to:[x,y] |
numpoints |
arc |
angle (radians) |
segments |
regularPolygon |
sides |
— |
regularInscribedPolygon |
sides |
— |
annulus |
minRadius, maxRadius |
— |
logo |
commands (String) |
— |
Common params (all shapes): style, layer, visible, transform, stack, label
def s = shape(type: "circle", segments: 6,
style: [color: "blue", thickness: 2],
transform: [scale: 1.5, shift: [1, 0]])
def r = shape(type: "segment", from: [0,0], to: [1,1])
def p = shape(type: "polygon", points: [[0,0],[1,0],[0.5,1]])
Inline labels (label:): attach one or more labels to the shape, with the
same options as the standalone label(...) DSL (t is an alias for location):
shape(type: "square", label: "x") // LaTeX label at t=0.5
shape(type: "square",
label: [text: "x", t: 0.3, upside: true,
style: [drawColor: "blue"], transform: [rotate: PI/2]])
shape(type: "square", label: [object: Shape.circle().scale(0.1), t: 0.3])
shape(type: "square", label: [[text: "A", t: 0], [text: "B", t: 0.5]]) // several
shape(type: "regularpolygon", sides: 3, // corner-anchored labels:
label: [[text: "A", vertex: 0], [text: "B", vertex: 1], [text: "C", vertex: 2]])
vertex: n (alternative to t) anchors the label at path vertex #n, placed on
the outward corner bisector — ideal for polygon vertices. Indices wrap
circularly (-1 = last vertex) and the label is never rotated along the path.
Inline labels are internal objects of the shape: they update, draw and
animate (fadeIn/fadeOut, etc.) together with it, and are never added to the
scene on their own. Retrieve them with sq.getInternalObject("label0")
("label1", ...) or name them yourself with a key: entry:
def sq = shape(type: "square", label: [text: "x", key: "north"])
def lbl = sq.getInternalObject("north")
For a label managed independently of its path (added/removed from the scene by
itself), use the standalone label(...) DSL instead.
point(...)
| Key | Type | Default | Description |
|---|---|---|---|
at |
[x,y] / [x,y,z] / Coords |
[0,0] |
Position |
style |
Map | — | Style (e.g. dotStyle, color, thickness) |
label |
String / Map / List | — | Inline label(s), as in shape(...) |
layer / visible / transform / stack |
— | — | Common props |
addToScene |
boolean | false |
Add to scene immediately |
def p = point(at: [1, 0], style: [color: "blue", dotStyle: "cross", thickness: 4])
def a = point(at: [1, 0], label: "$A$")
stack: map
Exactly one of to, screen, or point must be present.
| Key | Type | Description |
|---|---|---|
to |
Boxable | Destination object |
screen |
String | CENTER LEFT RIGHT UPPER LOWER UPPER_LEFT UPPER_RIGHT LOWER_LEFT LOWER_RIGHT |
point |
[x,y] |
Fixed point destination |
originAnchor |
String | AnchorType of moving object |
destinyAnchor |
String | AnchorType of destination |
gaps |
double / [h,v] |
Absolute gap |
relativeGaps |
double / [h,v] |
Relative gap (mutually exclusive with gaps) |
stack: [to: otherShape, originAnchor: "left", destinyAnchor: "right", gaps: 0.1]
stack: [screen: "upper_left"]
stack: [point: [1, 2], destinyAnchor: "center"]
AnchorType values (common reference)
CENTER LEFT RIGHT UPPER LOWER
LEFT_AND_ALIGNED_UPPER LEFT_AND_ALIGNED_LOWER
RIGHT_AND_ALIGNED_UPPER RIGHT_AND_ALIGNED_LOWER
LOWER_AND_ALIGNED_LEFT LOWER_AND_ALIGNED_RIGHT
UPPER_AND_ALIGNED_LEFT UPPER_AND_ALIGNED_RIGHT
DIAG1 DIAG2 DIAG3 DIAG4 ZTOP ZBOTTOM
All keyword String values support prefix matching (case-insensitive). E.g.
"cen"matchesCENTERinAnchorType
transform: map
| Key | Type | Description |
|---|---|---|
scale |
double / [sx,sy] |
Uniform or non-uniform scale |
shift |
[x,y] / Coords |
Translation |
rotate |
double / [center, angle] |
Rotation (radians), optionally around a point |
center |
true |
Center the object on screen |
transform: [scale: 2, shift: [1, 0], rotate: 45*DEGREES]
transform: [rotate: [[0,0], PI/3]] // rotate around [0,0]
Colors & Styles
style: map
| Key | Type | Values / Notes |
|---|---|---|
name |
String | Named style template (loaded first) |
color |
String | Color name or hex |
drawColor |
String | Stroke color |
fillColor |
String | Fill color |
thickness |
double | Stroke width |
thicknessTracksZoom |
boolean | Camera zoom changes apparent thickness (default false) |
thicknessTracksScale |
boolean | Scaling the object scales its thickness (default true) |
drawAlpha |
double | Stroke opacity [0,1] |
fillAlpha |
double | Fill opacity [0,1] |
visible |
boolean | — |
layer |
int | Rendering layer |
lineCap |
String | SQUARE ROUND BUTT |
lineJoin |
String | BEVEL ROUND MITER |
strokeType |
String | OUTSIDE INSIDE CENTERED |
dotStyle |
String | CIRCLE CROSS PLUS RING TRIANGLE_UP_HOLLOW TRIANGLE_UP_FILLED TRIANGLE_DOWN_FILLED TRIANGLE_DOWN_HOLLOW |
dashStyle |
String | SOLID DASHED DOTTED DASHDOTTED |
style: [name: "myTemplate", color: "red", thickness: 2, dashStyle: "dashed"]
style: "myTemplate" // shorthand: loads named style only
createStyle(...)
createStyle(name: "myStyle", style: [color: "red", thickness: 2])
| Param | Required | Description |
|---|---|---|
name |
yes | Style name to register |
style |
yes | Map of style properties (same keys as style: map) |
linearGradient(...)
| Key | Type | Default | Description |
|---|---|---|---|
from |
[x,y] / Point |
[0,0] |
Start point |
to |
[x,y] / Point |
[1,0] |
End point |
relative |
boolean | true |
Coords relative to shape |
cycle |
String | "no_cycle" |
no_cycle reflect repeat |
0.0:, 0.5:, ... |
String / JMColor | — | Color stops |
def lg = linearGradient(from: [0,0], to: [1,0],
relative: true,
0.0: "blue", 0.5: "red", 1.0: "#00FF00")
radialGradient(...)
| Key | Type | Default | Description |
|---|---|---|---|
center |
[x,y] / Point |
[0.5,0.5] |
Gradient center |
radius |
double | 0.5 |
Gradient radius |
focusAngle |
double | 0 |
Focus point angle (radians) |
focusDistance |
double | 0 |
Focus distance from center |
relative |
boolean | true |
Coords relative to shape |
cycle |
String | "no_cycle" |
no_cycle reflect repeat |
0.0:, 1.0:, ... |
String / JMColor | — | Color stops |
def rg = radialGradient(center: [0.5,0.5], radius: 0.5,
0.0: "yellow", 1.0: "red")
colorScale(...)
def cs = colorScale(0.0: "blue", 0.5: "white", 1.0: "red")
def cs = colorScale((-2): "blue", 0: "white", 2: "red") // negative keys: wrap in ()
Other Objects
axes(...)
| Key | Type | Description |
|---|---|---|
xRange / yRange |
[from, to] |
Primary tick range (or range: for both) |
xStep / yStep |
double | Primary tick step (default 1) |
secondary |
Map | Shorthand: sets both secondaryX and secondaryY |
secondaryX / secondaryY |
Map {from,to,step,maxWidth} |
Secondary ticks |
ticksX / ticksY |
List | Individual ticks (Number or Map {at, label, type, maxWidth, scale}) |
style |
Map | Global axes style |
xStyle / yStyle |
Map | Individual axis line style |
xTickStyle / yTickStyle |
Map | Tick mark style |
xLegendStyle / yLegendStyle |
Map | Tick label style |
tick.type: PRIMARY (default) or SECONDARY
def ax = axes(xRange: [-3, 3], yRange: [-2, 2], xStep: 1, yStep: 1,
secondaryX: [step: 0.5],
ticksX: [[at: Math.PI, label: r"\pi"]])
grid(...)
Cartesian grid. Added to the scene by default (add: false to opt out).
| Key | Type | Default | Description |
|---|---|---|---|
center |
[x,y] / Coords |
[0,0] |
Grid center |
steps |
double / [sx,sy] |
[1,1] |
Primary grid step |
divisions |
int / [dx,dy] |
[1,1] |
Secondary subdivisions |
primaryStyle |
Map | — | Style for primary lines |
secondaryStyle |
Map | — | Style for secondary lines |
def g = grid(steps: 1, divisions: 4,
primaryStyle: [color: "gray"],
secondaryStyle: [color: "lightgray"])
polarGrid(...)
Polar grid. Added to the scene by default (add: false to opt out).
| Key | Type | Default | Description |
|---|---|---|---|
center |
[x,y] / Coords |
[0,0] |
Grid center |
radiusStep |
double | 1 |
Distance between primary circles |
angularDivisions |
int | 6 |
Primary radial rays over the full circle |
divisions |
int / [dr,da] |
[1,1] |
Secondary radial / angular subdivisions |
primaryStyle |
Map | — | Style for primary lines |
secondaryStyle |
Map | — | Style for secondary lines |
def pg = polarGrid(radiusStep: 1, angularDivisions: 12, divisions: [2, 2])
funcGraph(...)
| Key | Type | Default | Description |
|---|---|---|---|
func |
Closure / DoubleUnaryOperator / DoubleBinaryOperator | required | The function to plot |
xRange (range) |
[from, to] |
— | Domain; if omitted the graph is dynamic (follows the camera) |
numPoints |
int | — | Sample points (only with an explicit range) |
dynamic |
boolean | — | Force dynamic range even with xRange |
style / label |
— | — | Style and inline label(s) |
def fg = funcGraph(func: { x -> Math.sin(x) }, xRange: [-3, 3], style: [color: "blue"])
def fg2 = funcGraph(func: Math.&cos) // dynamic: follows the camera view
parametricCurve(...)
| Key | Type | Description |
|---|---|---|
x, y |
Closure / operator / number | Cartesian components (z optional) |
r, theta |
Closure / operator / number | Polar components (switches to polar mode) |
trange (range) |
[tmin, tmax] |
required parameter domain |
numPoints |
int | Sample points |
coordinates |
String | cartesian (default) or polar |
tpoints |
Number / List | Extra parameter values to force as nodes |
style / label |
— | Style and inline label(s) |
def c = parametricCurve(x: { t -> Math.cos(t) }, y: { t -> Math.sin(t) }, trange: [0, 2*PI])
def rose = parametricCurve(r: { t -> Math.cos(3*t) }, theta: { t -> t }, trange: [0, PI])
contourPlot(...)
| Key | Type | Description |
|---|---|---|
function |
BiFunction | (x,y) -> value required |
levels |
List or Map {min,max,step} |
Contour levels required |
xMin/xMax/yMin/yMax |
double | Domain (default: camera view) |
cols / rows |
int | Grid resolution (default 100) |
colorScale |
ColorScale | Color scale instance |
style |
Map | Applied to all contour shapes |
def cp = contourPlot(
function: (x, y) -> x*x + y*y,
levels: [min: 0.5, max: 3.0, step: 0.5],
cols: 150, rows: 150,
colorScale: colorScale(0.0: "blue", 1.0: "red"))
densityPlot(...)
Pixel heat-map of a scalar field. Added to the scene by default (add: false to opt out).
| Key | Type | Default | Description |
|---|---|---|---|
function |
Closure (x,y) or (x,y,t) / operator |
required | Scalar field (t is animatable) |
range |
[xmin,ymin,xmax,ymax] / number / preset |
camera view | Domain (unit centered screen trig trigCentered) |
coordinates |
String | cartesian |
cartesian or polar (field gets r, theta) |
colorScale |
ColorScale | viridis | Color scale |
parallel |
boolean | true |
Parallel row evaluation |
style |
Map | — | Mainly for opacity (alpha) |
def dp = densityPlot(function: { x, y -> Math.sin(x) * Math.cos(y) }, range: "centered")
vectorField(...)
Grid of arrows sampling a planar field. Added to the scene by default.
| Key | Type | Default | Description |
|---|---|---|---|
function |
Closure (x,y)/(x,y,t) → Vec or [vx,vy] |
required | The field (t animatable) |
range |
[xmin,ymin,xmax,ymax] / number / preset |
camera view | Domain |
cols / rows |
int | 15 |
Grid resolution |
arrows |
String | simple |
simple (stroke-only) or classic (filled head) |
fill |
boolean | — | Filled arrows (default: true for classic) |
normalize |
boolean | false |
Same length for every arrow (direction only) |
scaleFactor |
double | 0.9 |
Fraction of a cell for the longest arrow |
lengthScale |
double | — | Fixed world length per unit magnitude (disables auto-scale) |
autoScale |
boolean | true |
Auto-scale longest arrow to a cell |
colorScale |
ColorScale | — | Color arrows by magnitude |
colorByMagnitude |
boolean | true |
Auto viridis coloring by magnitude |
parallel |
boolean | true |
Parallel row evaluation |
style |
Map | — | Applied to every arrow |
def vf = vectorField(function: { x, y -> Vec.to(-y, x) },
range: [-3, -3, 3, 3], cols: 20, rows: 20, arrows: "classic")
arrow(...)
| Key | Type | Default | Description |
|---|---|---|---|
from |
[x,y] / Coords |
required | Start point |
to |
[x,y] / Coords |
required | End point |
head |
int / String | ARROW1 |
End arrowhead |
tail |
int / String | NONE_BUTT |
Start arrowhead |
curvature |
double | — | Arrow curvature |
arrowThickness |
double | — | Arrowhead thickness |
startScale / endScale |
double | — | Arrowhead scale |
label |
String / Map | — | Text label |
lengthLabel |
String / Map | — | Length label |
vecLabel |
String / Map | — | Vector label |
style |
Map | — | Style |
Arrow types: NONE_BUTT(0) ARROW1(1) ARROW2(2) ARROW3(3) SQUARE(4) BULLET(5)
def ar = arrow(from: [0,0], to: [1,1], head: "ARROW2", tail: "NONE_BUTT",
label: [text: r"v", scale: 0.8, gap: 0.05])
Label sub-map keys: text, format, t (location 0–1), color, drawColor, fillColor, thickness, scale, gap, upside, anchor, rotation (FIXED ROTATE SMART), style (sub-map), transform (sub-map)
connector(...)
Same params as arrow(...) plus:
| Key | Type | Description |
|---|---|---|
from |
MathObject | required — source object |
to |
MathObject | required — destination object |
connectionType |
String | Exit strategy — auto (default), fixed, boxed, circular, inscribed, ellipse, center. Works for stepped too (e.g. center routes between the object centers). Must be set (not auto) for the scale params below to apply |
startScaleBBox |
double | Multiplicative bbox start scale (default 1; grows with the object; ignored when connectionType is auto or center) |
endScaleBBox |
double | Multiplicative bbox end scale (default 1; ignored when connectionType is auto or center) |
gaps |
number / [h,v] |
Fixed clearance added to each object's bbox before computing the exit — a constant distance (unlike the scale). Works with any connectionType, incl. center (then exits a fixed distance from the center) |
def con = connector(from: shapeA, to: shapeB, head: 2,
curvature: 0.3, label: "f")
delimiter(...)
Standard form:
| Key | Type | Default | Description |
|---|---|---|---|
from |
[x,y] / Coords |
required | Start point |
to |
[x,y] / Coords |
required | End point |
type |
String | BRACE |
BRACE PARENTHESIS BRACKET INVISIBLE LENGTH_ARROW LENGTH_BRACKET |
gap |
double | 0.1 |
Distance from anchor to delimiter body |
Stacked form:
| Key | Type | Description |
|---|---|---|
stackedTo |
MathObject | required — object to stack to |
anchor |
String | UPPER(def) LOWER LEFT RIGHT |
type |
String | See above |
gap |
double | Distance from object |
Common optional params:
| Key | Description |
|---|---|
delimiterScale |
Scale of the delimiter shape |
amplitudeScale |
Scale of the delimiter amplitude |
labelGap |
Distance from label to delimiter shape |
label |
String, Map {text, color, scale, gap, rotation, style, transform} or [object: mathObject] |
lengthLabel |
String or Map {format, color, scale, gap, rotation, style, transform} |
rotation |
FIXED ROTATE SMART |
style |
Style map |
def d = delimiter(from: [0,0], to: [2,0], type: "BRACE", gap: 0.15,
label: [text: r"$L$", scale: 0.8, gap: 0.05])
def d = delimiter(stackedTo: myShape, anchor: "UPPER", type: "BRACKET",
lengthLabel: [format: "0.00", color: "blue"])
label(...)
Attaches a tippable object to a path. Exactly one mode is required: text (a LabelTip), type (an arrowhead / equal-mark TippableObject), or object (any MathObject as the tip).
| Key | Type | Default | Description |
|---|---|---|---|
path |
Pathable | required | Path object to attach to |
text |
String | — | Mode: LaTeX label text |
type |
String | — | Mode: arrow1…arrow3, square, bullet, or equal1…equal4 |
object |
MathObject | — | Mode: arbitrary object as the tip |
location (t) |
double | 0.5* |
Position along path [0,1] (*path-dependent default) |
upside |
boolean | — | Place above path |
gap |
double | — | Distance to shape |
gapRelative |
boolean | true |
Gap relative to size |
rotation |
String | — | FIXED ROTATE SMART |
slopeDirection |
String / boolean | — | POSITIVE NEGATIVE |
anchor |
AnchorType | — | — |
scale |
double / [sx,sy] |
— | Scale the tip |
rotate |
double | — | Rotate the tip (radians) |
style |
Map / String | — | Style properties |
def lt = label(path: myShape, location: 0.5, text: r"$A$",
upside: true, gap: 0.1, rotation: "rotate")
def ah = label(path: seg, type: "arrow2", t: 1)
def em = label(path: seg, type: "equal2") // equal-length marks
delimiter(...)accepts a nestedlabelTip(...)block for its own label; that is a different, delimiter-scoped helper, not this top-level command.
Text & LaTeX
latex(...)
| Key | Type | Description |
|---|---|---|
text |
String | required — LaTeX expression |
anchor |
String | Anchor side used to position the object |
style |
Map / String | Style properties or named style |
latexStyle |
LatexStyle / String | Per-glyph coloring style (see latexStyle(...)) or a registered name |
colorToIndices |
String / List | Per-glyph coloring by index (see below) |
layer / visible / transform |
— | Common props |
def eq = latex(text: r"$e^{i\pi}+1=0$")
def q = latex(text: "$x^2+y^2$", colorToIndices: [["blue", 0, 1], ["red", 3, 4]])
colorToIndices forms: "blue" (all glyphs), ["blue", 1, 2] (glyphs 1 & 2), [["blue", 1, 2], ["red", 3, 5]] (several groups); indices accept ranges like 0..5.
text(...)
Plain (non-LaTeX) text.
| Key | Type | Default | Description |
|---|---|---|---|
text |
String | required | The text to display |
font |
String | — | Font family, e.g. "Serif" |
fontSize (height, size) |
double | 0.5 |
Text height in math units |
bold / italic / outline |
boolean | — | Font flags |
style |
Map / String | — | Style properties |
def t = text(text: "Hello", font: "Serif", fontSize: 0.8, style: [color: "blue"])
latexStyle(...)
Declaratively colors the glyphs of a LaTeX formula with ordered rules (later rules override earlier ones). See the Coloring Formulas chapter for the full token model.
| Key | Type | Description |
|---|---|---|
rules |
List of Maps | required — coloring rules (see below) |
apply |
LatexMathObject / List | Apply the built style to these formula(s) |
name |
String | Register the style under this name for reuse |
Each rule has a paint part (color for both draw and fill, drawColor / fillColor for each one separately, or a full style map/name) and optional conditions: char (exact CHAR), match / differ (token spec on the glyph), prev / next (neighbour token specs). A token spec is a String (its LaTeX name) or a Map (type, string, subscript, depth, ...).
latexStyle(apply: formula, name: "rowColMatrix", rules: [
[char: "X", color: "steelblue"],
[match: [subscript: true], color: "gold"],
])
apply(...)
Applies styling and common props to one or many existing objects.
| Key | Type | Description |
|---|---|---|
obj |
object / List / array | required — target(s) |
style |
Map / String | Style properties |
transform |
Map | scale, shift, rotate |
layer / visible / stack |
— | Common props |
apply(obj: [a, b, c], style: [drawColor: "blue"], transform: [rotate: PI/2])
Layouts
layout(...)
Builds a GroupLayout (usable with .setLayout(...) or the animSetLayout DSL). Selected by type (default simple). Common param gaps accepts a number or [h, v].
type |
Required | Optional |
|---|---|---|
simple |
layout (LayoutType name) |
refPoint |
box |
rowSize |
corner, direction (BoxDirection) |
flow |
width, corner |
direction |
circular |
center, radius |
clockwise, rotation, initialAngle |
spiral |
— | orientation (SpiralOrientation), center, spiralGap |
heap |
— | base |
pascal |
— | refPoint |
path |
path |
rotation, parametric |
random |
deviation |
distribution (normal/uniform), center |
destiny |
destinyGroup |
— |
LayoutType names: center right left upper lower uright uleft dright dleft rupper lupper rlower llower diag1–diag4.
def lay = layout(type: "circular", center: [0, 0], radius: 3)
def box = layout(type: "box", rowSize: 3, gaps: [0.1, 0.1], corner: [0, 0])
Constructible Objects
Points
| Method | Required | Optional |
|---|---|---|
ctPoint(at:[x,y]) |
at |
style, layer, visible, transform, name |
ctMidPoint(A:, B:) |
a, b |
— |
ctMidPoint(segment:) |
segment (CTSegment) |
— |
ctIntersectionPoint(A:, B:) |
a, b |
index (0/1) |
ctMirrorPoint(point:, axis:) |
point, axis (CTAbstractLine) |
— |
ctMirrorPoint(point:, A:, B:) |
point, a, b |
— |
ctMirrorPoint(point:, center:) |
point, center |
— |
ctRotatedPoint(point:, center:, angle:) |
point, center, angle |
— |
ctTranslatedPoint(point:, vector:) |
point, vector (CTVector) |
— |
ctPointOnObject(on:) |
on (PointOwner) |
— |
All CT methods accept:
style,layer,visible,transform,name(CT name)
def A = ctPoint(at: [0, 0])
def M = ctMidPoint(A: A, B: B)
def I = ctIntersectionPoint(A: line1, B: circle1, index: 0)
def R = ctRotatedPoint(point: A, center: O, angle: Math.PI/3)
Lines
| Method | Forms |
|---|---|
ctLine |
A:, B: or A:, dir: (HasDirection) |
ctSegment |
A:, B: |
ctRay |
A:, B: or A:, dir: |
ctVector |
A:, B: |
ctAngleBisector |
A:, B: (vertex), C: |
ctPerpBisector |
A:, B: or segment: (CTSegment) |
ctLineOrthogonal |
A:, B: or A:, dir: |
ctTransformedLine(line:, ...) |
mirrorAxis: / mirrorCenter: / vector: / center:+angle: |
def l = ctLine(A: A, B: B)
def s = ctSegment(A: A, B: B, style: [color: "blue"])
def pb = ctPerpBisector(segment: s)
def tl = ctTransformedLine(line: l, mirrorAxis: l2)
def tl = ctTransformedLine(line: l, center: O, angle: Math.PI/4)
Circles
| Method | Forms |
|---|---|
ctCircle |
center:+radius: / center:+through: / A:+B:+C: |
ctCircleArc |
center:, A:, B: |
ctCircleSector |
center:, A:, B: |
ctSemiCircle |
A:, B: |
ctEllipse |
focus1:, focus2:, A: |
ctTransformedCircle(circle:, ...) |
mirrorAxis: / mirrorCenter: / vector: / center:+angle: |
def c = ctCircle(center: O, radius: 1.5)
def c = ctCircle(A: P, B: [1,1], C: Q) //Circle through P, (1,1) and Q
def e = ctEllipse(focus1: F1, focus2: F2, A: P) //Ellipse with focus F1, F2 that passes through P
def tc = ctTransformedCircle(circle: c, vector: v)
ctLatex(...)
| Param | Type | Default | Description |
|---|---|---|---|
text |
String | required | LaTeX expression |
anchor |
[x,y] / Coords |
required | Anchor point |
anchorType |
String | "DIAG4" |
Anchor side (see AnchorType) |
gap |
double | 0.3 |
Gap from anchor |
scale |
double | 0.5 |
Size scale |
style |
Map | — | Style properties |
def lbl = ctLatex(text: r"\alpha", anchor: [1, 0],
anchorType: "left", gap: 0.15, scale: 0.7)
Other constructibles
| Method | Forms |
|---|---|
ctPolygon |
points:[A,B,C,...] (free) or A:+B:+sides: (regular) |
ctAngleMark |
center:, A:, B: + optional radius:, isRight: |
ctTangent |
point:+circle: + optional index: or circle1:+circle2: + optional index: |
def poly = ctPolygon(points: [A, B, C, D])
def hex = ctPolygon(A: A, B: B, sides: 6)
def am = ctAngleMark(center: O, A: P1, B: P2, radius: 0.15, isRight: true)
def t = ctTangent(point: P, circle: c, index: 0)
def t = ctTangent(circle1: c1, circle2: c2, index: 2)
Animations
Every anim* command runs immediately unless run: false is given, and always returns the created Animation (useful for composing with animGroup / animJoin).
Common params (most anim commands):
| Key | Type | Description |
|---|---|---|
obj |
MathObject / List | Object(s) to animate |
runtime |
double | Duration in seconds (default 1) |
run |
boolean | Play now (default true); false just builds it |
effects |
Map | Extra effects (see below); shift/rotate/scale/affine and the position anims |
lambda |
String / Closure | Timing function (see below) |
effects: map
| Key | Type | Description |
|---|---|---|
turns |
int | Number of extra rotations |
scale |
double | Scale bump amplitude |
alpha |
double | Alpha (transparency) bump |
jump |
double | Jump height |
jumptype |
String | PARABOLICAL(def) SEMICIRCLE ELLIPTICAL TRIANGULAR FOLIUM SINUSOIDAL SINUSOIDAL2 CRANE BOUNCE1 BOUNCE2 |
animShift(obj: sq, dx: 1, effects: [jump: 1, jumptype: "crane", turns: 1])
lambda: timing
A String names a parameterless UsefulLambdas function (prefix-matching): smooth(def) backAndForth backAndForthLinear backAndForthBounce1 backAndForthBounce2 bounce1 bounce2 reverse. A Closure gives a custom timing, e.g. lambda: { t -> t * t }. For parameterized lambdas pass the operator directly, e.g. lambda: restrictTo(0.25, 0.5).
animShift(...) / animRotate(...) / animScale(...)
| Command | Required | Optional |
|---|---|---|
animShift |
obj + (vector or dx/dy/dz) |
— |
animRotate |
obj + (angle rad or degrees) |
center |
animScale |
obj + (scale or sx/sy/sz) |
center |
center accepts a point/Vec or [x,y]; if omitted the object uses its own center. scale is a single number (uniform) or [sx,sy].
animShift(obj: sq, dx: 1, dy: 0.5)
animRotate(obj: sq, degrees: 90, center: [0, 0], runtime: 2)
animScale(obj: sq, scale: 0.5, effects: [turns: 1])
animCamera(...)
type |
Required | Description |
|---|---|---|
shift |
vector or dx/dy |
Pan the view |
scale |
scale or zoom |
scale > 1 zooms out; zoom: 5 == scale: 0.2 |
zoomToRect |
rect |
Rect, [xmin,ymin,xmax,ymax], a number n (square [-n,n]) or a preset |
zoomToObjects |
obj |
Fit the given object(s) |
zoomToAllObjects |
— | Fit all objects in the scene |
Optional camera: selects the Camera (default: scene camera).
animCamera(type: "shift", dx: 1, dy: -1, runtime: 4)
animCamera(type: "scale", zoom: 5)
animCamera(type: "zoomToRect", rect: [-1, -1, 1, 1])
animAffine(...)
Points accept a point/Vec or [x,y].
type |
Params |
|---|---|
similarity |
origin/destiny: 2 points each, or two Rect |
inverseSimilarity |
origin/destiny: 2 points each |
reflection |
origin, destiny (single points) |
reflectionByAxis |
axis: 2 points |
affine |
origin/destiny: 3 points each |
animAffine(type: "affine", obj: grid, origin: [A, B, C], destiny: [D, E, F])
animAffine(type: "reflection", obj: sq, origin: [1, 0], destiny: [-1, 0])
animAffine(type: "similarity", obj: tri, origin: [A, B], destiny: [C, D])
animMoveAlongPath(...)
| Key | Type | Default | Description |
|---|---|---|---|
obj |
MathObject | required | Single object to move |
path |
Pathable | required | Path to follow (Shape, JMPath, function graph...) |
anchor |
String | center |
Point of the object on the path |
rotation |
String | fixed |
fixed rotate (follow tangent) smart (never upside down) |
parametrized |
boolean | true |
true arc-length (constant speed); false Bézier |
rotationSmoothing |
double | 0.01 |
Corner smoothing half-window; 0 = abrupt turns |
animMoveAlongPath(obj: dot, path: circle)
animMoveAlongPath(obj: arrow, path: curve, rotation: "rotate", runtime: 3)
animStackTo(...) / animAlign(...) / animSetLayout(...)
| Command | Required | Optional |
|---|---|---|
animStackTo |
obj, dst |
anchor (def center), gap |
animAlign |
obj, dst, type (left/right/upper/lower/hcenter/vcenter) |
— |
animSetLayout |
obj (group/List), layout |
corner, gap |
dst accepts a MathObject, Rect, point/Vec or [x,y]. layout is a LayoutType name (right, upper, diag1...), a GroupLayout (from the layout(...) DSL), or a spec map [type: "circular", center: [0,0], radius: 2].
animStackTo(obj: sq, dst: circle, anchor: "right", gap: 0.1)
animAlign(obj: sq, dst: circle, type: "left")
animSetLayout(obj: g, layout: "right", gap: 0.1)
animGroup(...) / animJoin(...)
Build the children with run: false, then combine them:
| Command | Required | Optional | Timing |
|---|---|---|---|
animGroup |
anims |
delay (0–1 stagger), effects, lambda |
Plays together; total = max child runtime (no runtime) |
animJoin |
anims |
runtime, lambda |
Plays in sequence; default total = sum of children, default lambda linear |
def a1 = animShift(obj: s1, dx: 1, run: false)
def a2 = animRotate(obj: s2, degrees: 90, run: false)
animGroup(anims: [a1, a2], delay: 0.5)
animJoin(anims: [a1, a2], runtime: 3)
appear(...) / disappear(...)
Bring objects into / out of the scene. obj is a single object or a List.
| Command | type (default) |
Type-specific params |
|---|---|---|
appear |
showcreation* (fadein, growin, movein) |
growin: angle, orientation; movein: enter (edge) |
disappear |
fadeout* (shrinkout, moveout) |
shrinkout: angle, orientation; moveout: exit (edge) |
*showcreation aliases: draw, sketch. orientation: horizontal vertical both. Edge values: left right upper lower upper_left upper_right lower_left lower_right center.
appear(obj: s, type: "growin", angle: PI, orientation: "horizontal")
disappear(obj: [s1, s2], type: "moveout", exit: "right")
morph(...)
Morphs one object into another (removes from, adds to).
| Key | Type | Description |
|---|---|---|
from / to |
MathObject | required — initial / final object |
type |
String | auto(def) flip twist |
orientation |
String | flip: horizontal vertical both |
pivotal |
int | twist: pivotal segment index (both must be Shape) |
morph(from: square, to: circle)
morph(from: a, to: b, type: "flip", orientation: "horizontal")
highlight(...)
Momentarily draws attention to objects without permanent changes.
type |
Params |
|---|---|
highlight (def) |
scale (def 1.5) |
twist |
scale, angle (def 15°) |
contour |
box (bbox instead of outline), gap, color, thickness, amplitude |
boxHighlight |
— |
highlight(obj: s, scale: 2)
highlight(obj: text, type: "contour", box: true, gap: 0.1, color: "yellow", thickness: 12)
animScalar(...)
Animates the scalar value of Parametric object(s) (e.g. the t of a density/vector field) from from to to.
| Key | Type | Default | Description |
|---|---|---|---|
obj |
Parametric / List | required | Scalar object(s) |
from |
double | 0 |
Initial value |
to |
double | required | Final value |
runtime / run / lambda |
— | — | Common anim params |
animScalar(obj: t, from: 0, to: 2*PI, runtime: 3)
mathTransform(...)
Morphs a LaTeX formula into another, mapping/removing/adding individual glyphs, optionally over sequential stages.
| Key | Type | Description |
|---|---|---|
from / to |
String / LatexMathObject | required — initial / final formula |
maps |
List | Glyph mappings: [orig, dst] pairs, or [orig:.., dst:.., stage:.., style:.., asGroup:.., lambda:.., effects:..] |
removes / adds |
List | Ints/lists of indices, or maps [indices:.., style:.., stage:.., effects:..] |
align |
[toIndex, fromIndex] |
Align to glyph over a from glyph |
defaultRemove / defaultAdd |
String | Default styles (shrink_out / grow_in) |
defaultRemoveStage / defaultAddStage |
int | Default stages (1) |
delay |
double | Stagger sub-animations within each stage (0,1) |
runtime / run / lambda |
— | Common anim params |
Map style: interpolation flip_horizontally flip_vertically flip_both. effects on maps: [turns, scale, alpha, jump, jumptype]; on removes/adds only turns.
mathTransform(
from: r"$aX b$", to: r"$Z$", runtime: 3,
removes: [[indices: 0, style: "moveout_left", stage: 1]],
maps: [[orig: 1, dst: 0, stage: 2]])