# Physical system
## Microsim
<iframe src="https://editor.p5js.org/sciencenibber/full/F4e514fVU" width="740" height="560" frameborder="0" title="Physical system microsim"></iframe>
<img src="../SPINTRONICS_Statics_Images/Physical_system.png" alt="Physical_system microsim">
- **Editor URL:** [Open in the p5.js editor](https://editor.p5js.org/sciencenibber/sketches/F4e514fVU)
- **Pattern:** **A** — plane construction & free-body diagram (system isolation)
- **Canvas:** 720 x 520, `pixelDensity(2)`; vanilla p5, no external libraries
**Description (what it shows).** A small bench carries a fixed **wall**, **block A** joined to the wall by spring **k1**, **block B** joined to A by spring **k2**, gravity and ground-normal forces on each block, and a **hand** pushing B. A dashed, glowing **system boundary** marks the chosen system; drag it left or right and widen it with a slider to enclose different subsets of {wall, A, B}. Every force acting on a body inside the boundary is classified live: a force whose other end lies outside is **external** (bright, labelled with its value, and added to the net) while a force whose other end is also inside is **internal** (faint, dashed -- one half of an equal-and-opposite pair that cancels). A side panel renders the system's free-body diagram and the running net, and a teal resultant arrow grows from the system centroid. Push **P** to see the net change sign and null to zero; toggle **show internal pairs** to watch the cancelling forces appear and vanish.
```js
// =====================================================================
// Article : Physical system
// Slug : Physical_system
// Wikitube : en.wikitube.io/wiki/Physical_system
// Category : SPINTRONICS / Statics (mechatronics & electronics hub)
// Idea : A physical system is the portion of the universe you draw a
// BOUNDARY around to analyse; everything else is its
// environment. The modelling act IS choosing the boundary.
// Forces that cross the boundary are EXTERNAL (they appear in
// the system's free-body diagram); forces wholly inside come
// in equal-and-opposite action-reaction pairs that CANCEL --
// they are INTERNAL and never move the system as a whole.
// Equation : F_net(system) = sum of EXTERNAL forces
// (internal pairs sum to zero by Newton's third law)
// Pattern : A -- plane construction & free-body diagram (system isolation)
//
// THE LESSON THIS SIM IS BUILT TO TEACH (the "aha"):
// The SAME collection of bodies and forces gives a DIFFERENT free body
// depending on where you draw the system boundary. Slide / widen the
// boundary over a small chain (wall - block A - spring - block B - hand):
// * a force with one end in and one end out -> EXTERNAL (counts)
// * a force with both ends inside -> INTERNAL, its reaction is also
// inside, the pair cancels (does NOT count)
// Enclose both blocks and the A<->B spring vanishes from the net.
// Enclose the wall too and its spring vanishes as well. Internal forces
// never accelerate the whole; only boundary-crossing forces do. That is
// why "isolate the system, then sum the external forces" is the first
// move in every statics and dynamics problem.
//
// Input-driven: noLoop() + redraw(); no animation loop at all, so the
// editor loop-protect cannot trip. Every redraw is a slider/drag/button.
// =====================================================================
const ARTICLE = "Physical_system";
p5.disableFriendlyErrors = true;
// ---- palette (Statics room: light schematic bench) ------------------
const BG = 248; // paper-white background
const GRIDC = [226, 229, 234]; // faint construction grid
const STRUCT = [80, 90, 110]; // slate: wall, ground, labels
const BLOCKC = [70, 80, 96]; // block body
const BLOCKF = [232, 236, 242]; // block fill
const SYSFILL = [62, 132, 214]; // system interior tint (boundary)
const SYSEDGE = [36, 104, 196]; // system boundary stroke (glow)
const EXTCOL = [210, 70, 35]; // external force (crosses boundary)
const INTCOL = [150, 155, 165]; // internal force (cancelling pair)
const NETCOL = [33, 110, 95]; // net external resultant (teal)
const OKG = [40, 150, 95]; // "net" accent
// ---- canvas / layout (every constant derived from width & height) ---
const CW = 720, CH = 520;
let SX0; // px of x = 0 m (the wall face)
let PXPM; // pixels per metre (bench scale)
let PXPN; // pixels per newton (arrow scale)
let BENCH_Y; // y of the bench top surface (px)
let BOXT, BOXB; // boundary top / bottom (px)
let panX, panY, panW, panH; // right-hand free-body panel
// ---- the bodies on the bench (metres along x; y is up) --------------
// includable entities: wall, block A, block B. earth/ground/hand are the
// rest of the universe and are never inside the system.
const WALL = 0, A = 1, B = 2, EARTH = 3, GROUND = 4, AGENT = 5;
const XM_WALL = 0.0, XM_A = 1.15, XM_B = 2.55; // metres
const BLK_W = 0.46, BLK_H = 0.40; // block size (m)
// ---- fixed force magnitudes (N) -------------------------------------
const S1 = 28; // wall<->A spring tension (pulls A toward the wall)
const S2 = 36; // A<->B spring tension (pulls A,B toward each other)
const WA = 48, NA = 48; // weight / normal on A (balance vertically)
const WB = 32, NB = 32; // weight / normal on B (balance vertically)
// ---- the interactions. force on `a` is (fx,fy); on `b` it is -(fx,fy).
// (Newton's third law: every interaction is one equal-opposite pair.)
const INTER = [
{ a: A, b: WALL, fx: -S1, fy: 0, lab: "spring k1 (wall<->A)" },
{ a: A, b: B, fx: +S2, fy: 0, lab: "spring k2 (A<->B)" },
{ a: A, b: EARTH, fx: 0, fy: -WA, lab: "weight A" },
{ a: A, b: GROUND, fx: 0, fy: +NA, lab: "normal A" },
{ a: B, b: EARTH, fx: 0, fy: -WB, lab: "weight B" },
{ a: B, b: GROUND, fx: 0, fy: +NB, lab: "normal B" },
{ a: B, b: AGENT, fx: 0, fy: 0, lab: "applied push P" } // fx set from slider
];
const APPLIED = 6; // index of the applied-force row (its fx = P)
// ---- controls -------------------------------------------------------
const P_DEF = 24; // default applied push P (N, +x on block B)
const BOXC_DEF = 1.85; // default boundary centre (m)
const BOXW_DEF = 2.4; // default boundary width (m)
let pS, wS; // applied force, boundary width sliders
let internalChk, resetBtn;
let boxC = BOXC_DEF; // boundary centre (m); draggable
let dragging = false;
// ---- live state (computed once per redraw; no per-frame allocation) --
let P = P_DEF;
let boxL = 0, boxR = 0; // boundary edges (m)
let wallIn = false, aIn = false, bIn = false;
let cxA = 0, cyA = 0, cxB = 0, cyB = 0; // block centres (px)
let netX = 0, netY = 0, nExt = 0, nInt = 0;
function setup() {
createCanvas(CW, CH);
pixelDensity(2);
describe(
"A physical system on a small bench: a wall, block A joined to the " +
"wall by spring k1, block B joined to A by spring k2, gravity and " +
"ground-normal forces on each block, and a hand pushing B. A dashed " +
"boundary marks the chosen system; drag it or widen it with a slider. " +
"Forces that cross the boundary are external and are summed into a net " +
"resultant; forces with both ends inside form internal action-reaction " +
"pairs that cancel. A side panel lists the system's free-body diagram.");
// layout derived from canvas size
SX0 = width * 0.112; // x = 0 m (wall face)
PXPM = width * 0.144; // ~14% of width per metre
PXPN = 1.0; // 1 N -> 1 px of arrow
BENCH_Y = height * 0.585; // bench top surface
BOXT = height * 0.27; // boundary top
BOXB = BENCH_Y + 22; // boundary bottom (just under the bench)
panW = width * 0.30; panH = height * 0.50;
panX = width - panW - 12; panY = height * 0.175;
// --- control row (below the bench) -----------------------------------
const sx = 150, sw = 132;
let y = 372;
pS = createSlider(0, 80, P_DEF, 1); pS.position(sx, y); pS.size(sw); y += 30;
wS = createSlider(0.4, 3.4, BOXW_DEF, 0.05); wS.position(sx, y); wS.size(sw); y += 32;
resetBtn = createButton("reset"); resetBtn.position(18, y); resetBtn.mousePressed(doReset);
internalChk = createCheckbox(" show internal pairs", true);
internalChk.position(78, y); internalChk.changed(redraw);
pS.input(redraw);
wS.input(redraw);
noLoop();
}
// =====================================================================
// COMPUTE -- read controls once, classify forces, sum the externals.
// =====================================================================
function compute() {
P = pS.value();
INTER[APPLIED].fx = P;
const w = wS.value();
boxL = boxC - w / 2;
boxR = boxC + w / 2;
wallIn = within(XM_WALL);
aIn = within(XM_A);
bIn = within(XM_B);
cxA = mx(XM_A); cyA = BENCH_Y - (BLK_H * 0.5) * PXPM;
cxB = mx(XM_B); cyB = BENCH_Y - (BLK_H * 0.5) * PXPM;
// sum the EXTERNAL forces on the chosen system
netX = 0; netY = 0; nExt = 0; nInt = 0;
for (let i = 0; i < INTER.length; i++) {
const it = INTER[i];
accumulate(it.a, it.b, it.fx, it.fy); // force on endpoint a
accumulate(it.b, it.a, -it.fx, -it.fy); // reaction on endpoint b
}
}
// classify one (force-on-endpoint): only matters if the endpoint is a
// block that is inside the system. internal if the other end is also in.
function accumulate(ep, other, fx, fy) {
if (!isBlock(ep)) return;
if (!inSys(ep)) return;
if (inSys(other)) { nInt++; } // internal pair (cancels)
else { nExt++; netX += fx; netY += fy; } // external -> counts
}
function within(xm) { return xm >= boxL && xm <= boxR; }
function isBlock(id) { return id === A || id === B; }
function inSys(id) {
if (id === WALL) return wallIn;
if (id === A) return aIn;
if (id === B) return bIn;
return false; // earth / ground / hand
}
function mx(xm) { return SX0 + xm * PXPM; } // metres -> px (x)
function blkCenter(id) { return id === A ? [cxA, cyA] : [cxB, cyB]; }
// =====================================================================
// DRAW
// =====================================================================
function draw() {
compute();
background(BG);
drawGrid();
drawWall();
drawGround();
drawSpringSchematic(); // light connector lines between bodies
drawBoundary(); // the system membrane (signature visual)
drawBlock(A, "A", aIn);
drawBlock(B, "B", bIn);
drawForces(); // external (bright) + internal (faint)
drawNet(); // the net external resultant
drawPanel(); // the system's free-body diagram
drawBanner();
drawHUD(); // 4-part watermark, drawn last
}
// ---------------------------------------------------------------------
// The system boundary: a translucent tinted rectangle with a glowing
// dashed edge and SYSTEM / environment labels. This is the one object
// the whole sim is about, so it gets the signature visual treatment.
// ---------------------------------------------------------------------
function drawBoundary() {
const xl = constrain(mx(boxL), 6, panX - 6);
const xr = constrain(mx(boxR), 6, panX - 6);
const w = xr - xl;
push();
// soft glow on a single rect, then reset shadow (cheap, one shape)
noStroke();
drawingContext.shadowColor = "rgba(40,110,200,0.30)";
drawingContext.shadowBlur = 18;
fill(SYSFILL[0], SYSFILL[1], SYSFILL[2], 26);
rect(xl, BOXT, w, BOXB - BOXT, 12);
drawingContext.shadowBlur = 0;
// dashed boundary edge
stroke(SYSEDGE[0], SYSEDGE[1], SYSEDGE[2], 220); strokeWeight(2);
noFill();
drawingContext.setLineDash([8, 5]);
rect(xl, BOXT, w, BOXB - BOXT, 12);
drawingContext.setLineDash([]);
// labels
noStroke();
fill(SYSEDGE[0], SYSEDGE[1], SYSEDGE[2]);
textAlign(LEFT, BOTTOM); textSize(12); textStyle(BOLD);
text("SYSTEM (boundary)", xl + 6, BOXT - 4);
textStyle(NORMAL);
fill(150, 150, 158);
textAlign(LEFT, TOP); textSize(11);
text("environment", 12, BOXT + 2);
pop();
}
// ---------------------------------------------------------------------
// The fixed wall on the left (environment structure) with hatching.
// ---------------------------------------------------------------------
function drawWall() {
const x = mx(XM_WALL);
push();
stroke(STRUCT[0], STRUCT[1], STRUCT[2]); strokeWeight(3);
line(x, BENCH_Y - 78, x, BENCH_Y);
strokeWeight(1);
for (let y = BENCH_Y - 76; y < BENCH_Y; y += 9) line(x, y, x - 11, y + 9);
noStroke(); fill(STRUCT[0], STRUCT[1], STRUCT[2]);
textAlign(CENTER, BOTTOM); textSize(11);
text("wall", x - 4, BENCH_Y - 82);
pop();
}
// ---------------------------------------------------------------------
// The ground / bench surface (environment) with hatching.
// ---------------------------------------------------------------------
function drawGround() {
push();
stroke(STRUCT[0], STRUCT[1], STRUCT[2]); strokeWeight(2.5);
line(mx(XM_WALL), BENCH_Y, mx(3.25), BENCH_Y);
strokeWeight(1);
for (let x = mx(XM_WALL) + 6; x < mx(3.25); x += 13) line(x, BENCH_Y, x - 9, BENCH_Y + 9);
noStroke(); fill(150, 150, 158);
textAlign(RIGHT, TOP); textSize(11);
text("ground", mx(3.22), BENCH_Y + 10);
pop();
}
// ---------------------------------------------------------------------
// Light schematic spring connectors (wall-A and A-B) -- context only.
// ---------------------------------------------------------------------
function drawSpringSchematic() {
push();
stroke(170, 175, 184); strokeWeight(1.6);
coil(mx(XM_WALL), cyA, cxA - (BLK_W * 0.5) * PXPM, cyA, 6);
coil(cxA + (BLK_W * 0.5) * PXPM, cyA, cxB - (BLK_W * 0.5) * PXPM, cyB, 7);
pop();
}
// a simple zig-zag spring between two points (single polyline)
function coil(x0, y0, x1, y1, n) {
const segs = n * 2;
noFill();
beginShape();
vertex(x0, y0);
for (let i = 1; i < segs; i++) {
const t = i / segs;
const x = lerp(x0, x1, t);
const off = (i % 2 === 0) ? -5 : 5;
vertex(x, y0 + off);
}
vertex(x1, y1);
endShape();
}
// ---------------------------------------------------------------------
// A block (A or B). Brighter when it is inside the system.
// ---------------------------------------------------------------------
function drawBlock(id, lab, inside) {
const c = blkCenter(id);
const w = BLK_W * PXPM, h = BLK_H * PXPM;
push();
rectMode(CENTER);
stroke(BLOCKC[0], BLOCKC[1], BLOCKC[2]); strokeWeight(inside ? 2.4 : 1.4);
fill(inside ? 255 : BLOCKF[0], inside ? 255 : BLOCKF[1], inside ? 255 : BLOCKF[2]);
rect(c[0], c[1], w, h, 5);
noStroke(); fill(BLOCKC[0], BLOCKC[1], BLOCKC[2]);
textAlign(CENTER, CENTER); textSize(17); textStyle(BOLD);
text(lab, c[0], c[1]);
textStyle(NORMAL);
pop();
}
// ---------------------------------------------------------------------
// Draw every force ON A BODY THAT IS IN THE SYSTEM. External forces
// (other end outside) are bright and counted; internal forces (other
// end inside too) are faint and only shown when the checkbox is on.
// ---------------------------------------------------------------------
function drawForces() {
const showInt = internalChk.checked();
for (let i = 0; i < INTER.length; i++) {
const it = INTER[i];
drawOneForce(it.a, it.b, it.fx, it.fy, it.lab, showInt);
drawOneForce(it.b, it.a, -it.fx, -it.fy, it.lab, showInt);
}
}
function drawOneForce(ep, other, fx, fy, lab, showInt) {
if (!isBlock(ep)) return;
if (!inSys(ep)) return; // not part of the chosen system
const fmag = sqrt(fx * fx + fy * fy);
if (fmag < 0.5) return;
const internal = inSys(other);
if (internal && !showInt) return;
const c = blkCenter(ep);
const col = internal ? INTCOL : EXTCOL;
const wt = internal ? 2 : 3.2;
// screen vector: math y-up flips to y-down on the canvas
const vx = fx * PXPN, vy = -fy * PXPN;
if (internal) {
push(); drawingContext.setLineDash([4, 4]);
drawArrow(c[0], c[1], vx, vy, col, wt);
pop();
} else {
drawArrow(c[0], c[1], vx, vy, col, wt);
// value label near the tip
const u = fmag * PXPN || 1;
const lx = c[0] + vx + (vx / u) * 12;
const ly = c[1] + vy + (vy / u) * 12;
noStroke(); fill(EXTCOL[0], EXTCOL[1], EXTCOL[2]);
textAlign(CENTER, CENTER); textSize(10);
text(nf(fmag, 0, 0) + "N", lx, ly);
}
}
// ---------------------------------------------------------------------
// The net external resultant, drawn from the system centroid.
// ---------------------------------------------------------------------
function drawNet() {
if (aIn === false && bIn === false) return; // empty system
// centroid of the in-system blocks
let sx = 0, sy = 0, n = 0;
if (aIn) { sx += cxA; sy += cyA; n++; }
if (bIn) { sx += cxB; sy += cyB; n++; }
if (n === 0) return;
const gx = sx / n, gy = sy / n - 4;
const fmag = sqrt(netX * netX + netY * netY);
push();
// centroid marker
noStroke(); fill(NETCOL[0], NETCOL[1], NETCOL[2]);
circle(gx, gy, 7);
if (fmag < 0.5) {
textAlign(CENTER, BOTTOM); textSize(11); textStyle(BOLD);
fill(OKG[0], OKG[1], OKG[2]);
text("F_net = 0 (balanced)", gx, gy - 10);
textStyle(NORMAL);
pop();
return;
}
const vx = netX * PXPN, vy = -netY * PXPN;
drawArrow(gx, gy, vx, vy, NETCOL, 5);
const u = fmag * PXPN || 1;
const lx = gx + vx + (vx / u) * 18;
const ly = gy + vy + (vy / u) * 14;
noStroke(); fill(NETCOL[0], NETCOL[1], NETCOL[2]);
textAlign(CENTER, CENTER); textSize(12); textStyle(BOLD);
text("F_net " + nf(fmag, 0, 0) + "N", lx, ly);
textStyle(NORMAL);
pop();
}
// ---------------------------------------------------------------------
// A straight arrow from (x,y) along (vx,vy).
// ---------------------------------------------------------------------
function drawArrow(x, y, vx, vy, col, wt) {
const len = sqrt(vx * vx + vy * vy);
if (len < 0.5) return;
push();
stroke(col[0], col[1], col[2]); strokeWeight(wt);
line(x, y, x + vx, y + vy);
translate(x + vx, y + vy); rotate(atan2(vy, vx));
const hs = 8 + wt * 1.3;
noStroke(); fill(col[0], col[1], col[2]);
triangle(0, 0, -hs, -hs * 0.42, -hs, hs * 0.42);
pop();
}
// ---------------------------------------------------------------------
// The free-body panel: the system's contents, external forces, the net,
// and the cancelling internal pairs.
// ---------------------------------------------------------------------
function drawPanel() {
push();
noStroke(); fill(255); rect(panX, panY, panW, panH, 8);
stroke(GRIDC[0], GRIDC[1], GRIDC[2]); strokeWeight(1); noFill();
rect(panX, panY, panW, panH, 8);
pop();
const px = panX + 12;
let y = panY + 12;
noStroke(); textAlign(LEFT, TOP);
fill(90); textSize(12); textStyle(BOLD);
text("Free body of the SYSTEM", px, y); textStyle(NORMAL);
y += 20;
// contents
fill(SYSEDGE[0], SYSEDGE[1], SYSEDGE[2]); textSize(11); textStyle(BOLD);
text("contents: " + contentsLabel(), px, y); textStyle(NORMAL);
y += 20;
fill(EXTCOL[0], EXTCOL[1], EXTCOL[2]); textSize(11); textStyle(BOLD);
text("external forces (cross boundary)", px, y); textStyle(NORMAL);
y += 16;
// list each external force on the system
fill(60); textSize(11);
let listed = 0;
for (let i = 0; i < INTER.length; i++) {
const it = INTER[i];
y = listExt(it.a, it.b, it.fx, it.fy, it.lab, px, y) || y;
y = listExt(it.b, it.a, -it.fx, -it.fy, it.lab, px, y) || y;
}
// net
push(); stroke(GRIDC[0], GRIDC[1], GRIDC[2]); strokeWeight(1);
line(px, y + 2, panX + panW - 12, y + 2); pop();
y += 8;
const fmag = sqrt(netX * netX + netY * netY);
fill(NETCOL[0], NETCOL[1], NETCOL[2]); textSize(12); textStyle(BOLD);
text("NET = (" + nf(netX, 0, 0) + ", " + nf(netY, 0, 0) + ") N", px, y);
y += 15;
fill(fmag < 0.5 ? OKG : NETCOL); textSize(11);
text(fmag < 0.5 ? "|F_net| = 0 -> balanced" : "|F_net| = " + nf(fmag, 0, 1) + " N", px, y);
textStyle(NORMAL);
y += 20;
// internal note
fill(INTCOL[0], INTCOL[1], INTCOL[2]); textSize(11); textStyle(BOLD);
text("internal pairs (cancel): " + nInt, px, y); textStyle(NORMAL);
y += 15;
fill(120); textSize(10);
text("each is one half of an equal-and-", px, y); y += 12;
text("opposite pair -- both ends inside,", px, y); y += 12;
text("so it sums to zero.", px, y);
}
// list a single external force line in the panel (returns new y or null)
function listExt(ep, other, fx, fy, lab, px, y) {
if (!isBlock(ep)) return null;
if (!inSys(ep)) return null;
if (inSys(other)) return null; // internal, not listed here
const fmag = sqrt(fx * fx + fy * fy);
if (fmag < 0.5) return null;
const onWhich = (ep === A) ? "A" : "B";
text("- " + lab + " on " + onWhich + ": (" +
nf(fx, 0, 0) + ", " + nf(fy, 0, 0) + ")", px, y);
return y + 14;
}
function contentsLabel() {
const parts = [];
if (wallIn) parts.push("wall");
if (aIn) parts.push("A");
if (bIn) parts.push("B");
if (parts.length === 0) return "{ empty }";
return "{ " + parts.join(", ") + " }";
}
// ---------------------------------------------------------------------
// Top banner.
// ---------------------------------------------------------------------
function drawBanner() {
push();
textAlign(LEFT, TOP); textSize(13); textStyle(BOLD); noStroke();
fill(STRUCT[0], STRUCT[1], STRUCT[2]);
text("A physical system is whatever you draw the boundary around -- the rest is its environment.",
14, 62);
textStyle(NORMAL);
pop();
}
// ---------------------------------------------------------------------
// 4-part self-identifying HUD watermark.
// ---------------------------------------------------------------------
function drawHUD() {
noStroke();
// (1) title block (top-left)
textAlign(LEFT, TOP);
fill(20); textSize(20); textStyle(BOLD);
text("Physical system", 14, 12); textStyle(NORMAL);
fill(110); textSize(12);
text("Wikitube microsim - en.wikitube.io/wiki/" + ARTICLE, 14, 38);
// (2) control labels beside the sliders
textAlign(LEFT, CENTER); fill(70); textSize(11);
text("applied push P = " + nf(P, 0, 0) + " N", 18, 381);
text("boundary width = " + nf(wS.value(), 0, 2) + " m", 18, 411);
// (3) control hint + live readout (bottom-left)
textAlign(LEFT, BOTTOM); textSize(11); fill(90);
const yb = height - 10;
text("drag the boundary box left/right; widen it to enclose more; push P; toggle internal pairs",
14, yb - 16);
fill(40); textSize(12); textStyle(BOLD);
text("system " + contentsLabel() + " external forces: " + nExt +
" internal pairs: " + nInt + " F_net = (" +
nf(netX, 0, 0) + ", " + nf(netY, 0, 0) + ") N", 14, yb);
textStyle(NORMAL);
// (4) bottom-right equation footer (ASCII only)
textAlign(RIGHT, BOTTOM); fill(80); textSize(11);
text("F_net(system) = sum of EXTERNAL forces (internal pairs cancel)",
width - 12, height - 10);
}
// ---------------------------------------------------------------------
// Faint construction grid (reference layer, under everything).
// ---------------------------------------------------------------------
function drawGrid() {
stroke(GRIDC[0], GRIDC[1], GRIDC[2]); strokeWeight(1);
for (let x = 0; x <= width; x += 36) line(x, 0, x, height);
for (let y = 0; y <= height; y += 36) line(0, y, width, y);
}
// ---------------------------------------------------------------------
// Interaction: drag the system boundary box horizontally.
// ---------------------------------------------------------------------
function mousePressed() {
const xl = mx(boxL), xr = mx(boxR);
if (mouseX >= xl && mouseX <= xr && mouseY >= BOXT && mouseY <= BOXB) {
dragging = true;
}
}
function mouseDragged() {
if (!dragging) return;
boxC = (mouseX - SX0) / PXPM; // px -> metres
boxC = constrain(boxC, -0.4, 3.4);
redraw();
}
function mouseReleased() { dragging = false; }
// ---------------------------------------------------------------------
// reset restores ALL state (sliders + boundary centre + checkbox).
// ---------------------------------------------------------------------
function doReset() {
pS.value(P_DEF);
wS.value(BOXW_DEF);
boxC = BOXC_DEF;
dragging = false;
internalChk.checked(true);
redraw();
}
```
## Microsim log
| Date | Version | Editor URL | Change summary |
|------|---------|------------|----------------|
| 2026-06-22 | v1 | [open](https://editor.p5js.org/sciencenibber/sketches/F4e514fVU) | Initial Microsim Worklist build. Pattern A system-isolation free-body diagram: a draggable system boundary over a wall-block-spring-block-hand chain reclassifies each force as external (crosses the boundary, summed into a net resultant) or internal (action-reaction pair, both ends inside, cancels). Verified before publish: pure ASCII, `node --check` clean, p5 reserved-name lint (caught and renamed the cursor constant `HAND` -> `AGENT`), and a 6-case standalone logic check confirming the net external force for the empty / single-block / both-blocks / wall-enclosed / horizontally-balanced configurations. Published byte-perfect (in-editor doc SHA-256 == disk SHA-256), FES-clean console. |
## Links (Wikipedia order)
<!-- injected from _registry/childlinks/Physical_system.json (2026-07-30T02:09:12Z) -->
[[Alexander_Bogdanov]] · [[Allenna_Leonard]] · [[Anatol_Rapoport]] · [[Anthony_Wilden]] · [[Barbara_J._Grosz]] · [[Biological_system]] · [[Béla_H._Bánáthy]] · [[C._West_Churchman]] · [[Charles_A._S._Hall]] · [[Claude_Shannon]] · [[Complex_system]] · [[Control_theory]] · [[Coupled_human–environment_system]] · [[Cybernetics]] · `Degrees_of_freedom_(physics_and_chemistry)` · [[Donella_Meadows]] · [[Doubling_time]] · [[Earth_system_science]] · `Economic_system` · [[Ecosystem]] · [[Edsger_W._Dijkstra]] · [[Edward_Norton_Lorenz]] · [[Eric_Trist]] · [[Francisco_Varela]] · `Fred_Emery_(psychologist)` · [[George_Dantzig]] · [[George_Klir]] · [[Gregory_Bateson]] · [[Heinz_von_Foerster]] · [[Howard_T._Odum]] · [[Humberto_Maturana]] · [[Ilya_Prigogine]] · [[Information_system]] · [[Isolated_system]] · [[James_Grier_Miller]] · [[James_J._Kay]] · [[Jay_Wright_Forrester]] · [[Jennifer_Wilby]] · [[John_Seddon]] · [[Kathleen_Carley]] · [[Katia_Sycara]] · `Kenneth_E._Boulding` · [[Kevin_Warwick]] · [[Limiting_factor]] · [[List_of_systems_sciences_organizations]] · `List_of_systems_scientists` · [[Living_systems]] · [[Ludwig_von_Bertalanffy]] · [[Lydia_Kavraki]] · [[Manfred_Clynes]] · [[Manuela_M._Veloso]] · [[Margaret_Boden]] · [[Margaret_Mead]] · [[Mary_Cartwright]] · [[Mihajlo_D._Mesarovic]] · `Mike_Jackson_(systems_scientist)` · [[Multi-agent_system]] · [[Murray_Bowen]] · [[Negative_feedback]] · [[Nervous_system]] · [[Niklas_Luhmann]] · [[Norbert_Wiener]] · `Open_quantum_system` · [[Pendulum]] · [[Peter_Senge]] · [[Phase_space]] · `Physical_object` · [[Physics]] · `Plant_(control_theory)` · [[Positive_feedback]] · [[Principia_Cybernetica]] · [[Qian_Xuesen]] · [[Radhika_Nagpal]] · [[Recommender_system]] · `Russell_L._Ackoff` · `Ruzena_Bajcsy` · `Set_(mathematics)` · [[Signal-flow_graph]] · `Social_system` · [[Sociotechnical_system]] · [[Stafford_Beer]] · [[Stephanie_Forrest]] · [[System]] · [[System_dynamics]] · `Systemics` · `Systems_analysis` · `Systems_art` · [[Systems_biology]] · [[Systems_ecology]] · [[Systems_engineering]] · [[Systems_neuroscience]] · [[Systems_pharmacology]] · `Systems_philosophy` · `Systems_psychology` · [[Systems_science]] · [[Systems_theory]] · `Systems_theory_in_anthropology` · [[Systems_theory_in_archaeology]] · [[Systems_theory_in_political_science]] · [[Systems_thinking]] · [[Talcott_Parsons]] · [[Thermodynamic_system]] · [[Twelve_leverage_points]] · [[Urban_metabolism]] · `Victor_Aladjev` · `Weather_map` · `World-systems_theory`
## From the Real GENERATIVE library

*Physical system — placed from the Real G.E.N.E.R.A.T.I.V.E. course library (Computation and Cybersecurity room). Source: Wikimedia Commons (via Wikipedia article media). [Details & license](https://commons.wikimedia.org/wiki/File:Physical_systems-en.svg).*
> A physical system is a collection of physical objects under study.[1] The collection differs from a set: all the objects must coexist and have some physical relationship.[2] In other words, it is a portion of the physical universe chosen for analysis. Everything outside the system is known as the environment, which is ignored except for its effects on the sy ([Wikipedia](https://en.wikipedia.org/wiki/Physical_system))
<!-- REAL-GENERATIVE-MEDIA:END -->
← Back to Spintronics · Branch: **S — Statics** · Standard: MicroSim Best Practices
> A **physical system** is the portion of the physical world chosen for study -- the bodies and fields enclosed by a chosen **boundary** -- with everything outside treated as its **environment** (or surroundings). Defining the [[System|system]] is the first and most consequential step of any mechanics problem: it fixes which interactions are **external** (forces that cross the boundary and govern the system's motion) and which are **internal** (action-reaction pairs wholly inside, which cancel and cannot move the whole). The same collection of bodies yields a different free-body diagram depending on where the boundary is drawn.
## Overview
A physical system is any well-defined collection of matter or region of space that an analyst isolates from the rest of the universe by an imaginary closed surface called the **system boundary**. Whatever lies inside is the system; whatever lies outside is the environment. Systems are classified by what the boundary lets through: an **isolated** system exchanges neither matter nor [[Energy|energy]], a **closed** system exchanges energy but not matter, and an **open** system exchanges both. In mechanics the decisive consequence of the choice is the free-body diagram: once the boundary is fixed, every force is either **external** (one end attached to something in the environment) or **internal** (both ends attached to bodies inside). By Newton's third law every internal interaction appears as an equal-and-opposite pair, so the internal forces sum to zero and the net force on the system -- the quantity that sets its acceleration -- is the sum of the **external** forces alone.
This is why "choose the system, then sum the external forces" is the opening move of statics and dynamics, and the whole art lies in the choice. Enclose a single block and the spring joining it to its neighbour is external; enclose both blocks and that same spring becomes internal and drops out of the balance; enclose the supporting wall as well and the wall's reaction disappears too. None of the [[Physics|physics]] changes -- only the bookkeeping -- yet a well-chosen boundary can turn an intractable tangle of internal forces into a one-line equation. The picture generalises far beyond mechanics: the same boundary-and-environment idea underlies the **control volume** of [[Fluid_dynamics|fluid dynamics]], the **[[Thermodynamic_system|thermodynamic system]]** of heat and work, and the "system under study" of every experimental [[Science|science]]. This MicroSim makes the choice tangible -- drag a boundary across a small chain of a wall, two blocks, and a pushing hand, and watch each force reclassify in real time: internal pairs grey out and cancel, external forces sum into a single net resultant.
## See also
- Hub: Spintronics · Branch: **S — Statics**
- Related statics sims: Statics · Mechanical equilibrium · [[Force]] · [[Newton's_laws_of_motion]] · Rigid body
- Standard: MicroSim Best Practices · editor workflow: P5 JS EDITOR
- Index: MAIN
_Poster image deferred to attended backfill: `SPINTRONICS_Statics_Images/Physical_system.png` (headless runs cannot capture the canvas)._
Letters: mined_system · force · tradeoff_balance · circuit_symbols_iec · energy · mined_science · equilibrium · kanji_radicals
See also (bridge energy x mined_system): Galileo Galilei
See also (bridge mined_system x rotation): Rotating reference frame
<!-- REAL-GENERATIVE-MEDIA:START -->
<!-- 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/Physical_system) : [Wikitube](https://en.wikitube.io/wiki/Physical_system)
## Previous hub tags
Tree parent: [[Phase_space]].
Legacy hubs: `SPINTRONICS`.
---
*Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*