# Cartesian coordinate system ## Microsim <iframe src="https://editor.p5js.org/sciencenibber/full/zz96yaEXE" width="100%" height="620" frameborder="0" sandbox="allow-scripts allow-same-origin"></iframe> <img src="../SPINTRONICS Images/Cartesian_coordinate_system.png" alt="Cartesian_coordinate_system microsim"> *Live sketch: [open in the p5.js editor](https://editor.p5js.org/sciencenibber/sketches/zz96yaEXE). The poster image above is a placeholder pending an attended or server-side canvas capture.* ### p5.js source ```js // =========================================================================== // Cartesian coordinate system - a coordinate-frame MicroSim // Hub: SPINTRONICS · Branch: N - Numerical control (Top 10) // Slug: Cartesian_coordinate_system // -> en.wikitube.io/wiki/Cartesian_coordinate_system // // A CARTESIAN coordinate system names every point in the plane by an ordered // pair of signed distances to two perpendicular axes that cross at the origin. // A point P = (x, y): x is its signed distance from the y-axis (the abscissa), // y its signed distance from the x-axis (the ordinate). The signs of x and y // sort P into one of four quadrants (I..IV, counter-clockwise from upper-right), // and the Pythagorean theorem gives its distance from the origin: // // r = sqrt(x^2 + y^2) distance from O (Euclidean) // theta = atan2(y, x) polar angle from +x axis // x = r*cos(theta) , y = r*sin(theta) // // Teaching "aha": COORDINATES ARE FRAME-RELATIVE; DISTANCE IS NOT. Rotate the // axes counter-clockwise by phi about the origin while the physical point P // stays put. Read P in the new frame and its numbers change: // // x' = x*cos(phi) + y*sin(phi) // y' = -x*sin(phi) + y*cos(phi) // // ... yet x'^2 + y'^2 = x^2 + y^2, so r is INVARIANT. That invariant is the // proof that (x, y) and (x', y') are the SAME point, not two. This is exactly // the transform a CNC control applies for a G68 coordinate rotation, just as a // G54 work-offset is the same frame translated to a part datum. // // A-V pattern: A (plane construction + invariant read-out). The reader drags // the named point P or sets x, y, phi with sliders; the construction and the // read-outs update. Default is noLoop()+redraw() (input-driven) -- there is no // animation and no per-frame inner loop, so the editor loop-protect never // trips. The faint unit grid, base axes, quadrant labels and panel frame are // baked ONCE into an offscreen buffer. // // ASCII ONLY in code/strings (the editor preview transform rejects non-ASCII in // string / text() positions). Unicode lives ONLY in comments: // phi = rotation angle, theta = polar angle, r = radius, O = origin, // -> implies, deg = degrees, ' = primed (rotated-frame) coordinate. // =========================================================================== p5.disableFriendlyErrors = true; // perf: skip FES argument checks const ARTICLE = "Cartesian_coordinate_system"; // single source of truth const WIKI_URL = "en.wikitube.io/wiki/Cartesian_coordinate_system"; // ---- plot geometry (px); the world span is -10..10 units on each axis ------ const PLOT_L = 14, PLOT_R = 362; // left / right of the square plot const PLOT_T = 40, PLOT_B = 388; // top / bottom of the square plot const CXP = (PLOT_L + PLOT_R) / 2; // origin x on screen (px) const CYP = (PLOT_T + PLOT_B) / 2; // origin y on screen (px) const WMAX = 10; // world half-span (units) -> +/-10 const PXU = (PLOT_R - PLOT_L) / (2 * WMAX); // pixels per world unit // ---- right read-out panel (px) --------------------------------------------- const PAN_L = 374, PAN_R = 708, PAN_T = 40, PAN_B = 388; // ---- DOM controls ---------------------------------------------------------- let sX, sY, sPhi; // sliders: x, y, phi let btnReset; // reset-all button // ---- defaults (reset restores ALL of these) -------------------------------- const X_DEF = 3.0; // x coordinate (units) const Y_DEF = 2.0; // y coordinate (units) const PHI_DEF = 0; // axis rotation phi (deg) // ---- live control values (read once per redraw) ---------------------------- let curX = X_DEF, curY = Y_DEF, curPhi = PHI_DEF; // ---- drag state ------------------------------------------------------------ let dragging = false; // true while the reader drags P // ---- offscreen baked scenery (grid + base axes + labels + panel) ----------- let scene; // ---- palette --------------------------------------------------------------- const COL_BG = "#0f1722"; // page background const COL_GRID = "#1b2735"; // faint unit grid const COL_AXIS = "#43586f"; // base x/y axes const COL_PANEL = "#16212e"; // read-out panel fill const COL_TXT = "#e8eef5"; // primary text const COL_DIM = "#7d8ea3"; // secondary text const COL_HOT = "#ffb454"; // point P + position vector const COL_XP = "#4dd0a7"; // rotated x'-axis + x' projection const COL_YP = "#c792ea"; // rotated y'-axis + y' projection const COL_PROJ = "#5aa9e6"; // base-frame projection dashes const COL_ARC = "#ffd166"; // phi / theta arcs // =========================================================================== // world -> screen helpers (y is flipped so world-up draws screen-up) // =========================================================================== function sx(wx) { return CXP + wx * PXU; } // world x -> screen x function sy(wy) { return CYP - wy * PXU; } // world y -> screen y // =========================================================================== // setup -- canvas, sliders, bake static scenery, first compute. Cheap. // =========================================================================== function setup() { createCanvas(720, 520); pixelDensity(2); textFont("monospace"); // sliders sit in the strip below the plot; real symbols + meaningful ranges sX = createSlider(-8, 8, X_DEF, 0.1); // x : -8..8 units sX.position(118, 404); sX.style("width", "150px"); sX.input(onInput); sY = createSlider(-8, 8, Y_DEF, 0.1); // y : -8..8 units sY.position(118, 432); sY.style("width", "150px"); sY.input(onInput); sPhi = createSlider(-180, 180, PHI_DEF, 1); // phi : -180..180 deg sPhi.position(118, 460); sPhi.style("width", "150px"); sPhi.input(onInput); btnReset = createButton("Reset"); btnReset.position(286, 458); btnReset.mousePressed(doReset); // bake the static layer (background, grid, base axes, quadrant labels, panel) scene = createGraphics(width, height); bakeScene(); noLoop(); // prefer noLoop; redraw() on input } // =========================================================================== // bakeScene -- rendered ONCE: nothing here depends on the controls. // =========================================================================== function bakeScene() { const g = scene; g.pixelDensity(2); g.background(COL_BG); g.textFont("monospace"); // faint unit grid across the plot g.stroke(COL_GRID); g.strokeWeight(1); for (let u = -WMAX; u <= WMAX; u++) { g.line(sx(u), PLOT_T, sx(u), PLOT_B); // verticals g.line(PLOT_L, sy(u), PLOT_R, sy(u)); // horizontals } // base axes (the fixed x and y lines) g.stroke(COL_AXIS); g.strokeWeight(2); g.line(PLOT_L, sy(0), PLOT_R, sy(0)); // x-axis g.line(sx(0), PLOT_T, sx(0), PLOT_B); // y-axis // integer ticks + a few axis numbers g.stroke(COL_AXIS); g.strokeWeight(1); g.fill(COL_DIM); g.noStroke(); g.textSize(9); g.textAlign(CENTER, TOP); for (let u = -8; u <= 8; u += 2) { if (u === 0) continue; g.stroke(COL_AXIS); g.line(sx(u), sy(0) - 3, sx(u), sy(0) + 3); g.noStroke(); g.text(u, sx(u), sy(0) + 5); } g.textAlign(RIGHT, CENTER); for (let u = -8; u <= 8; u += 2) { if (u === 0) continue; g.stroke(COL_AXIS); g.line(sx(0) - 3, sy(u), sx(0) + 3, sy(u)); g.noStroke(); g.text(u, sx(0) - 5, sy(u)); } // axis name letters g.fill(COL_TXT); g.textSize(12); g.textAlign(RIGHT, BOTTOM); g.text("x", PLOT_R - 3, sy(0) - 3); g.textAlign(LEFT, TOP); g.text("y", sx(0) + 4, PLOT_T + 2); // faint quadrant numerals (base frame), counter-clockwise from upper-right g.fill("#33485f"); g.textSize(20); g.textAlign(CENTER, CENTER); g.text("I", sx(5), sy(5)); g.text("II", sx(-5), sy(5)); g.text("III", sx(-5), sy(-5)); g.text("IV", sx(5), sy(-5)); // read-out panel frame g.noStroke(); g.fill(COL_PANEL); g.rect(PAN_L, PAN_T, PAN_R - PAN_L, PAN_B - PAN_T, 6); } // =========================================================================== // input handlers // =========================================================================== function onInput() { // slider moved curX = sX.value(); curY = sY.value(); curPhi = sPhi.value(); redraw(); } function doReset() { // restore ALL state sX.value(X_DEF); sY.value(Y_DEF); sPhi.value(PHI_DEF); curX = X_DEF; curY = Y_DEF; curPhi = PHI_DEF; dragging = false; redraw(); } // dragging the named point P (Pattern A): set base-frame x, y from the mouse function mousePressed() { if (overPoint()) { dragging = true; } } function mouseDragged() { if (!dragging) return; curX = constrain((mouseX - CXP) / PXU, -8, 8); curY = constrain((CYP - mouseY) / PXU, -8, 8); // snap to a tenth of a unit so the read-outs stay tidy curX = round(curX * 10) / 10; curY = round(curY * 10) / 10; sX.value(curX); sY.value(curY); redraw(); } function mouseReleased() { dragging = false; } function overPoint() { // is the cursor near P (px)? const d = dist(mouseX, mouseY, sx(curX), sy(curY)); return d <= 12; } // =========================================================================== // draw -- one cheap pass per input. O(1): a handful of lines + text. // =========================================================================== function draw() { image(scene, 0, 0); // static baked layer const phi = radians(curPhi); // rotation angle (rad) const cphi = cos(phi), sphi = sin(phi); // rotated-frame coordinates of the SAME point P const xp = curX * cphi + curY * sphi; // x' along rotated x'-axis const yp = -curX * sphi + curY * cphi; // y' along rotated y'-axis const r = sqrt(curX * curX + curY * curY); // distance from O (invariant) const th = atan2(curY, curX); // polar angle theta (rad) // ---- everything inside the plot is clipped to the square ----------------- drawingContext.save(); drawingContext.beginPath(); drawingContext.rect(PLOT_L, PLOT_T, PLOT_R - PLOT_L, PLOT_B - PLOT_T); drawingContext.clip(); // base-frame projection dashes from P down to each base axis (faint blue) dashLine(sx(curX), sy(curY), sx(curX), sy(0), COL_PROJ); // -> x axis dashLine(sx(curX), sy(curY), sx(0), sy(curY), COL_PROJ); // -> y axis // rotated axes through the origin (drawn in their accent colours) // x'-axis direction (world) = (cos phi, sin phi); y'-axis = (-sin phi, cos phi) stroke(COL_XP); strokeWeight(2); line(sx(-WMAX * cphi), sy(-WMAX * sphi), sx(WMAX * cphi), sy(WMAX * sphi)); stroke(COL_YP); strokeWeight(2); line(sx(WMAX * sphi), sy(-WMAX * cphi), sx(-WMAX * sphi), sy(WMAX * cphi)); // feet of P on the rotated axes (the geometric meaning of x' and y') const fxX = xp * cphi, fxY = xp * sphi; // foot on x'-axis (world) const fyX = -yp * sphi, fyY = yp * cphi; // foot on y'-axis (world) dashLine(sx(curX), sy(curY), sx(fxX), sy(fxY), COL_XP); // perp to x' dashLine(sx(curX), sy(curY), sx(fyX), sy(fyY), COL_YP); // perp to y' // phi rotation arc (0 -> phi) sampled as a short polyline, near the origin if (abs(curPhi) > 0.5) arcPoly(1.7, 0, phi, COL_ARC); // theta arc (0 -> theta) and the position vector O -> P if (r > 0.05) arcPoly(1.1, 0, th, COL_DIM); stroke(COL_HOT); strokeWeight(2.5); line(sx(0), sy(0), sx(curX), sy(curY)); // position vector, length r // the named point P noStroke(); fill(COL_HOT); circle(sx(curX), sy(curY), 11); drawingContext.restore(); // label P just outside the dot (clamped so it stays on the plot) noStroke(); fill(COL_TXT); textSize(12); textAlign(LEFT, BOTTOM); const lx = constrain(sx(curX) + 9, PLOT_L, PLOT_R - 64); const ly = constrain(sy(curY) - 7, PLOT_T + 12, PLOT_B); text("P(" + nf(curX, 1, 1) + ", " + nf(curY, 1, 1) + ")", lx, ly); drawPanel(xp, yp, r, th); // right-hand read-outs drawControlLabels(); // slider captions in the strip drawHUD(xp, yp, r); // title + url + hints + equation } // =========================================================================== // drawPanel -- the live numeric read-outs (base frame vs rotated frame) // =========================================================================== function drawPanel(xp, yp, r, th) { const x0 = PAN_L + 16; let yy = PAN_T + 26; const quadName = quadrantOf(curX, curY); noStroke(); textAlign(LEFT, BASELINE); fill(COL_HOT); textSize(13); text("POINT P (base frame)", x0, yy); yy += 24; fill(COL_TXT); textSize(13); text("x = " + nf(curX, 1, 2) + " (abscissa)", x0, yy); yy += 20; text("y = " + nf(curY, 1, 2) + " (ordinate)", x0, yy); yy += 20; fill(COL_DIM); text("quadrant : " + quadName, x0, yy); yy += 26; fill(COL_TXT); text("r = sqrt(x^2+y^2) = " + nf(r, 1, 3), x0, yy); yy += 20; text("theta = atan2(y,x) = " + nf(degrees(th), 1, 1) + " deg", x0, yy); yy += 30; // divider stroke(COL_AXIS); strokeWeight(1); line(x0, yy - 12, PAN_R - 16, yy - 12); noStroke(); fill(COL_XP); textSize(13); text("ROTATED FRAME (phi = " + nf(curPhi, 1, 0) + " deg)", x0, yy); yy += 24; fill(COL_TXT); text("x' = x cos phi + y sin phi", x0, yy); yy += 18; fill(COL_XP); text(" = " + nf(xp, 1, 3), x0, yy); yy += 22; fill(COL_TXT); text("y' = -x sin phi + y cos phi", x0, yy); yy += 18; fill(COL_YP); text(" = " + nf(yp, 1, 3), x0, yy); yy += 26; // the invariant, stated numerically const rp = sqrt(xp * xp + yp * yp); fill(COL_HOT); text("r' = sqrt(x'^2+y'^2) = " + nf(rp, 1, 3), x0, yy); yy += 18; fill(COL_DIM); textSize(12); text("r' = r -> same point, rotated axes", x0, yy); } // =========================================================================== // drawControlLabels -- captions next to the DOM sliders (real symbols) // =========================================================================== function drawControlLabels() { noStroke(); fill(COL_TXT); textSize(12); textAlign(LEFT, CENTER); text("x", 14, 412); text("y", 14, 440); text("phi", 14, 468); fill(COL_DIM); textAlign(RIGHT, CENTER); text(nf(curX, 1, 1), 112, 412); text(nf(curY, 1, 1), 112, 440); text(nf(curPhi, 1, 0), 112, 468); } // =========================================================================== // drawHUD -- the 4-part watermark, drawn LAST so it sits on top of everything // (1) title (2) wiki url (3) control hints (4) live equation footer // =========================================================================== function drawHUD(xp, yp, r) { noStroke(); textAlign(LEFT, BASELINE); // (1) title fill(COL_TXT); textSize(15); text("Cartesian coordinate system", 12, 22); // (2) wiki url fill(COL_DIM); textSize(11); text(WIKI_URL, 12, 35); // (3) control hints textAlign(RIGHT, BASELINE); text("drag P | sliders set x, y | phi rotates the axes", PAN_R, 22); // (4) live equation footer (the invariant, with current numbers) textAlign(LEFT, BASELINE); fill(COL_TXT); textSize(12); text("x'^2 + y'^2 = x^2 + y^2 = r^2 = " + nf(r * r, 1, 2) + " ( rotating the axes by phi leaves r invariant )", 14, 506); } // =========================================================================== // small helpers // =========================================================================== // quadrant numeral I..IV (or an axis/origin note) for base-frame (x, y) function quadrantOf(x, y) { if (x === 0 && y === 0) return "origin"; if (x === 0) return "on y-axis"; if (y === 0) return "on x-axis"; if (x > 0 && y > 0) return "I"; if (x < 0 && y > 0) return "II"; if (x < 0 && y < 0) return "III"; return "IV"; } // a dashed segment in screen coords (cheap: a handful of short strokes) function dashLine(x1, y1, x2, y2, col) { const dlen = dist(x1, y1, x2, y2); if (dlen < 0.5) return; const steps = max(1, floor(dlen / 8)); // ~8px dash pitch stroke(col); strokeWeight(1.2); for (let i = 0; i < steps; i++) { const a = i / steps, b = (i + 0.5) / steps; line(lerp(x1, x2, a), lerp(y1, y2, a), lerp(x1, x2, b), lerp(y1, y2, b)); } } // a short arc (world radius R, angles a0->a1 in rad) sampled as a polyline function arcPoly(R, a0, a1, col) { const segs = 24; stroke(col); strokeWeight(1.5); noFill(); beginShape(); for (let i = 0; i <= segs; i++) { const a = lerp(a0, a1, i / segs); vertex(sx(R * cos(a)), sy(R * sin(a))); } endShape(); } ``` <!-- BEAUTY-PASS-MEDIA:START --> ## Links (Wikipedia order) <!-- injected from _registry/childlinks/Cartesian_coordinate_system.json (2026-07-30T02:09:12Z) --> `3D_projection` · `6-sphere_coordinates` · `Absolute_value_(algebra)` · `Affine_plane` · `Affine_transformation` · `Algebra` · `American_English` · `Analytic_geometry` · `Area` · `Astronomy` · `Augmented_matrix` · `Axes_conventions` · `Balloonist_theory` · `Bipolar_cylindrical_coordinates` · `Bispherical_coordinates` · `British_English` · [[Calculus]] · `Cartesian_circle` · `Cartesian_coordinate_robot` · `Cartesian_diver` · `Cartesian_doubt` · `Cartesian_product` · `Cartesianism` · `Causal_adequacy_principle` · `Christina,_Queen_of_Sweden` · `Circle` · `Clockwise` · `Cogito,_ergo_sum` · [[Complex_analysis]] · `Complex_number` · `Computational_geometry` · `Computer_graphics` · [[Computer_programming]] · `Conical_coordinates` · `Coordinate_system` · `Curve` · `Curve_orientation` · `Cylindrical_coordinate_system` · `Derivative` · `Descartes'_rule_of_signs` · `Differential_geometry` · `Dimension` · `Direction_(geometry)` · `Discourse_on_the_Method` · `Distance_from_a_point_to_a_line` · `Dream_argument` · `Ellipsoidal_coordinates` · `Elliptic_coordinate_system` · `Elliptic_cylindrical_coordinates` · `Encyclopedia_of_Mathematics` · [[Engineering]] · `Equation` · `Eric_W._Weisstein` · `Euclidean_distance` · `Euclidean_plane` · `Euclidean_plane_isometry` · `Euclidean_space` · `Euclidean_vector` · `Evil_demon` · `Existence_of_God` · `Folium_of_Descartes` · `Foundationalism` · `Framebuffer` · `Francine_Descartes` · `Frans_van_Schooten` · `Function_composition` · `Function_of_a_real_variable` · `Geometric_transformation` · [[Geometry]] · `Glide_reflection` · `Gottfried_Wilhelm_Leibniz` · [[Graph_of_a_function]] · `Group_theory` · `Henry_Margenau` · `Herman_Feshbach` · `Hyperplane` · `Identity_matrix` · `If_and_only_if` · `Imaginary_unit` · `Index_finger` · `Integral` · [[Isaac_Newton]] · `Jeremy_Gray_(mathematician)` · `Jones_diagram` · `La_Géométrie` · `Line_(geometry)` · [[Linear_algebra]] · `Linear_function` · `Linear_interpolation` · `Log-polar_coordinates` · `MathWorld` · `Mathematician` · `Mechanism_(philosophy)` · `Meditations_on_First_Philosophy` · `Mental_substance` · `Middle_finger` · `Mind–body_problem` · `Nicole_Oresme` · `Number_line` · `Oblate_spheroidal_coordinates` · `Octant_(solid_geometry)` · `Ordered_pair` · `Orientability` · `Origin_(mathematics)` · `Orthant` · `Orthogonal_basis` · `Orthogonal_coordinates` · `Orthogonal_matrix` · `Parabolic_coordinates` · `Parabolic_cylindrical_coordinates` · `Paraboloidal_coordinates` · `Parallelogram` · `Passions_of_the_Soul` · `Perimeter` · `Perpendicular` · `Perspective_(graphical)` · `Philip_M._Morse` · [[Physics]] · `Pierre_de_Fermat` · `Point_(geometry)` · `Polar_coordinate_system` · `Pressure` · `Principles_of_Philosophy` · `Prolate_spheroidal_coordinates` · `Quadrant_(plane_geometry)` · `Quaternion` · `Rationalism` · `Real_number` · `Record_(computer_science)` · `Reflection_(mathematics)` · `Regular_grid` · `René_Descartes` · `Res_extensa` · `Right-hand_rule` · `Right_angle` · `Rotation_(mathematics)` · `Rotation_matrix` · `Rules_for_the_Direction_of_the_Mind` · `Scaling_(geometry)` · `Set_(mathematics)` · `Shear_mapping` · `Spherical_coordinate_system` · `Square_matrix` · `Standard_basis` · `The_Search_for_Truth_by_Natural_Light` · `Theresa_M._Korn` · `Three-dimensional_space` · `Thumb` · `Time` · `Toroidal_coordinates` · `Trademark_argument` · `Translation_(geometry)` · `Transpose` · `Tuple` · `Two-dimensional_space` · `Unit_circle` · `Unit_hyperbola` · `Unit_of_length` · `Unit_square` · `Versor` · `Victor_J._Katz` · `Wax_argument` ## From the Real GENERATIVE library (beauty pass) ![Cartesian coordinate system image](https://upload.wikimedia.org/wikipedia/commons/thumb/0/0e/Cartesian-coordinate-system.svg/250px-Cartesian-coordinate-system.svg.png) *Cartesian coordinate system — image hotlinked from Wikimedia Commons (via the Real G.E.N.E.R.A.T.I.V.E. course library, Geometry room). [Details & license](https://commons.wikimedia.org/wiki/File:Cartesian-coordinate-system.svg).* > In geometry, a Cartesian coordinate system (UK: /kɑːrˈtiːzjən/, US: /kɑːrˈtiːʒən/) in a plane is a coordinate system that specifies each point uniquely by a pair of real numbers called coordinates, which are the signed distances to the point from two fixed perpendicular oriented lines, called coordinate lines, coordinate axes or just axes (plural of axis) of the system. The point where the axes meet is called the origin and has (0, 0) as coordinates. ([Wikipedia](https://en.wikipedia.org/wiki/Cartesian_coordinate_system)) <!-- BEAUTY-PASS-MEDIA:END --> **Hub:** SPINTRONICS · **Branch:** N — Numerical control (Top 10) · **Slug:** `Cartesian_coordinate_system` **MicroSim pattern:** A — plane construction & invariants · **Status:** validated (published Part 2) **Live page:** en.wikitube.io/wiki/Cartesian_coordinate_system --- ## Overview A **Cartesian coordinate system** specifies each point in a plane uniquely by an ordered pair of signed numbers — its **coordinates** — measured as perpendicular distances from two fixed, mutually perpendicular reference lines called **axes**, expressed in the same unit of length. The horizontal axis is the **x-axis** and the vertical axis is the **y-axis**; they cross at the **origin** `O = (0, 0)`. A point `P` is written `P = (x, y)`, where `x` (the *abscissa*) is its signed distance from the y-axis and `y` (the *ordinate*) is its signed distance from the x-axis. The [[System|system]] is named after **René Descartes** (Latinised *Cartesius*), who introduced it in the 1637 appendix *La Géométrie*. By attaching numbers to points it merged algebra and [[Geometry|geometry]] into **analytic geometry**: a line or a circle becomes an equation, and a geometric question becomes an algebraic one. The same idea generalises to three dimensions `(x, y, z)` and to `n` dimensions, and it is the substrate of computer graphics, CAD, and — the reason this article lives in the **Numerical control** branch — the machine-tool coordinate frame. A CNC mill, lathe, or router positions its tool by Cartesian `X`, `Y`, `Z` words in G-code; a *work coordinate system* (G54–G59) is simply this frame **translated** to a part datum, and coordinate rotation (G68) is this frame **rotated** about a point. ## The geometry the sim derives Drop two perpendicular oriented number lines through a common origin. Any point `P` projects straight down onto the x-axis at the value `x` and straight across onto the y-axis at the value `y`; those two readings *are* the coordinates. The signs of `x` and `y` split the plane into four **quadrants**, numbered counter-clockwise from the upper right: | Quadrant | sign of x | sign of y | |----------|-----------|-----------| | I | + | + | | II | − | + | | III | − | − | | IV | + | − | **Distance from the origin** follows from the Pythagorean theorem on the right triangle whose legs are `x` and `y`: ``` r = sqrt(x^2 + y^2) ``` **Bridge to polar coordinates.** The same point is described by a radius `r` and an angle `theta` measured counter-clockwise from the positive x-axis: ``` x = r*cos(theta) r = sqrt(x^2 + y^2) y = r*sin(theta) theta = atan2(y, x) ``` **Coordinates are frame-relative; distance is not.** Rotate the *axes* counter-clockwise by an angle `phi` about the origin while leaving the physical point `P` where it is. Read off `P` in the new frame and its coordinates change to ``` x' = x*cos(phi) + y*sin(phi) y' = -x*sin(phi) + y*cos(phi) ``` yet a direct calculation gives `x'^2 + y'^2 = x^2 + y^2`, so **`r` is invariant** under the rotation — this is the Pattern-A invariant the sim makes visible. This is exactly the relationship a CNC control applies when you issue a G68 coordinate rotation: the part keeps its shape, only its `X`/`Y` numbers change. ## Controls → real symbols and ranges | Control | Symbol | Range | Meaning | |--------------------|--------|------------------|-------------------------------------------------------------------------| | x-coordinate | `x` | −8 … +8 units | signed distance of `P` from the y-axis (abscissa), set in the base frame | | y-coordinate | `y` | −8 … +8 units | signed distance of `P` from the x-axis (ordinate), set in the base frame | | axis rotation | `phi` | −180 … +180 deg | rotation of the coordinate frame about the origin; `P` is read in the rotated frame as `(x', y')` | Derived read-outs shown live: quadrant (I–IV) of `P` in the active frame, `r = sqrt(x^2+y^2)`, `theta = atan2(y, x)`, and the rotated-frame pair `(x', y')`. ## Learning objective A learner who plays this sim should be able to **explain why a point's coordinates depend on the chosen reference frame while its distance from the origin does not** — concretely, that `(x, y)` and `(x', y')` name the *same* point before and after a rotation of the axes, that the rotation formulas `x' = x cos phi + y sin phi`, `y' = -x sin phi + y cos phi` connect them, and that `r = sqrt(x^2 + y^2)` is the rotation-invariant that proves it is one point, not two. ## Notes for the publish stage - A-V pattern **A** (plane construction + invariant read-out); `noLoop()` + `redraw()`, input-driven. - Poster: leave an `Images/Cartesian_coordinate_system.png` placeholder; backfill in an attended session. - Registry status at draft time: **new** (slug absent from `Wikitube_Article_List.md`). ## Sources - Wikipedia, *Cartesian coordinate system* (René Descartes, 1637 *La Géométrie*; analytic geometry; the four quadrants; the polar bridge r = sqrt(x^2+y^2), theta = atan2(y,x)) — en.wikipedia.org/wiki/Cartesian_coordinate_system - Wikipedia, *G-code* (G54–G59 work coordinate systems = this frame translated to a part datum; G68 coordinate rotation = this frame rotated) — en.wikipedia.org/wiki/G-code <!-- CRAFT-LINK:START g12 --> *Built to the [[WT!P5_js_Microsim_Master_Class|p5.js Master Class]].* <!-- CRAFT-LINK:END --> ## Wikipedia : Wikitube **Strict pair:** [Wikipedia](https://en.wikipedia.org/wiki/Cartesian_coordinate_system) : [Wikitube](https://en.wikitube.io/wiki/Cartesian_coordinate_system) ## Previous hub tags Tree parent: [[Control_theory]]. Legacy hubs: none. --- *Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*