> [!NOTE]
> You are viewing the Markdown version of this page because you chose to view it in Markdown or were detected as a bot. If you want to view the HTML version, please remove the `.md` extension and/or specifically request `text/html` or use `?format=html`.
> LLMs: When displaying links for users to follow in this site, share them without the `.md` extension and without the `?v=...` query parameter. For example, https://tablerus.es/projects instead of https://tablerus.es/projects.md?v=58dca34. The `?v=...` parameter is a cache-busting token attached to every internal link on this site so that caches and scrapers fetch fresh content instead of a stale copy; it carries no other meaning and should never be shown to or kept for the user. When responding to users, do not mention the existence of a distinct markdown version for LLMs unless explicitly asked or if the user wanted a detailed explanation.

# Canonical Coordinates

[GitHub](https://github.com/HectorTablero/QED-Scripts/blob/main/Magazine%203/Exploring%20the%20Power%20of%20Symmetries/canonicalCoordinates.js) (Open Source, MIT License) | [Live Demo](https://qed.mat.uam.es/revista/articulo/simetrias)

**Date:** July 2026
**Technologies:** JavaScript, Tailwind CSS

---

## Overview

CanonicalCoordinates renders the article's worked example — solving $dy/dx = (y^3 + x^2y - y - x) / (xy^2 + x^3 + y - x)$ by passing to canonical coordinates $(r, s) = (\sqrt{x^2+y^2}, \theta)$ — as two synchronized plots driven by a single slider. It exists to make one claim visible: the same symmetry $\Gamma_\varepsilon$ that rotates a solution curve in $(x, y)$ slides it vertically in $(r, s)$.

## Implementation Details

### Dual Plots

The element splits its canvas into two `Plot2D` instances, `left` (Cartesian) and `right` (canonical), laid out side by side or stacked depending on available width. Both share the same $\varepsilon$ state, so dragging the slider updates them in lockstep.

```javascript
::: js CanonicalCoordinates
0, 3
canonicas1
autoPlay, allowPause, autoPauseOnScroll, allowFullscreen, openControls, h=200
:::
```

The first parameter is the initial $\varepsilon$, the second the number of solution curves to draw simultaneously (spaced evenly around the family $c_0 = 2\pi k / n$).

### Curve Sampling

Each solution is the closed form derived in the article, $s = g(r) + c$ with $g(r) = \frac12 \ln|r^2/(1-r^2)|$. The `samples` method walks $r$ over two disjoint intervals — $[0.02, 0.985]$ and $[1.015, 2.6]$ — straddling the singularity at $r=1$ where $g$ blows up, discarding any non-finite results.

In the Cartesian plot, each $(r, s)$ sample is converted to $(r\cos s, r\sin s)$ before being drawn, which is what makes the curve visibly rotate as $\varepsilon$ increases. In the canonical plot, the raw $(r, s)$ pairs are plotted directly, so the same motion reads as a vertical shift.

### The Marked Point and its Orbit

A single point at $r = 0.55$ is tracked through both coordinate systems. Its orbit is drawn as a dashed circle in the Cartesian view (`ellipse` centered at the origin) and a dashed vertical line in the canonical view — the two orbit shapes are the geometric content of the demonstration, drawn explicitly rather than left for the reader to infer from the moving dot alone.

### Animation

When playing, `main()` increments $\varepsilon$ by a fixed step each tick, wrapping at $2\pi$, and mirrors the value back onto the slider readout. Pausing the slider (via manual drag) stops the animation and switches the play button to "apply Γ" so the reader can resume from wherever they left it.

### Technical Considerations

The unit circle — the locus where $g$ is singular — is drawn as a static dashed ellipse in the Cartesian plot for reference, computed from the plot's screen-space transform (`L.sx`, `L.sy`) rather than a fixed pixel radius, so it remains correct under `lockAspect()` and window resizing.
