Resources Numerical accuracy Calculation policy

User coordinate system set by command

Works out the origin and angle of the user coordinate system that UCS and the quarter-turn commands set, and what they print.

How the precision is kept

The origin is the picked point as stored and the angle is one atan2 toward a second point, or the current angle plus a typed angle or plus or minus π ÷ 2, in 64-bit. ucs.js setUcs then normalizes the angle to 0…2π. Objects keep their world coordinates; the system only changes how coordinates are typed and read out.

Open item. Use one tolerance for the X-axis point in the UCS command and in ucs.js threePoint, and keep the current angle when threePoint returns nothing.

Calculations under this policy

4 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.

commands.js CadCraft 0.8.2 64-bit 4 calculations Reviewed

Tests bin/test-cadcraft.mjs

Origin and X axis from two points

64-bit

The coordinate system with its origin at a picked point and its X axis toward a second point.

origin = o; angle = atan2(pₓ − o) (ucs.js threePoint)

The origin is the picked point with no arithmetic. A second point more than 1e-12 drawing units (absolute) away is passed to ucs.js threePoint, which takes the angle by atan2 but returns nothing for a distance under 1e-9; a point between the two tolerances therefore sets the world system. With no second point the current angle is kept.

  • commands.js
  • lines 3471 to 3474
  • CadCraft 0.8.2
const o = { x: r.x, y: r.y };
c.preview((p) => [{ type: 'line', x1: o.x, y1: o.y, x2: p.x, y2: p.y }]);
const px = await c.point(t('cmd.ucs.xaxis'), { base: o, none: true });
setUcs(c.doc, px && dist(o, px) > 1e-12 ? threePoint(o, px) : { x: o.x, y: o.y, ang: cur ? cur.ang : 0 });

Rotation about Z

64-bit

The coordinate system turned by a typed angle about its own origin.

angle = current angle + a (a defaults to π ÷ 2)

One addition in radians; the typed angle was converted from degrees with × π ÷ 180. The origin is unchanged. ucs.js setUcs normalizes the sum to 0…2π.

  • commands.js
  • lines 3483 to 3485
  • CadCraft 0.8.2
if (key === 'Z') {
  const a = await c.angle(t('cmd.ucs.zangle'), { default: Math.PI / 2 });
  setUcs(c.doc, { x: cur ? cur.x : 0, y: cur ? cur.y : 0, ang: (cur ? cur.ang : 0) + (typeof a === 'number' ? a : Math.PI / 2) });

Quarter turn

64-bit

The coordinate system turned a quarter left or right, or set back to the world.

angle = current angle ± π ÷ 2

Adds or subtracts Math.PI ÷ 2 from the current angle; a sign of 0 sets the world system outright. The sum is not normalized here.

  • commands.js
  • lines 3530 to 3537
  • CadCraft 0.8.2
// View › More: turn the view a quarter (= UCS Z ∓90, then the view follows) or back to the world; their own names, so
// the aliases file can give them a key (ALIASEDIT: TL=TURNLEFT)
function quarterTurn(c, sign) {
  if (!c.doc.inModel) { c.print(t('cmd.ucs.sheet')); return; }
  const cur = c.doc.ucs;
  setUcs(c.doc, sign ? { x: cur ? cur.x : 0, y: cur ? cur.y : 0, ang: (cur ? cur.ang : 0) + sign * Math.PI / 2 } : null);
  afterUcs(c);
}

What UCS prints

64-bit

The origin and angle of the coordinate system as printed in the command history.

angle shown = (angle mod 2π) × 180 ÷ π, at most 4 decimals

The origin is written with the drawing's length format and the angle in degrees through fmt, which keeps at most 4 decimals. The stored system is not rounded.

  • commands.js
  • line 3458
  • CadCraft 0.8.2
const ucsLabel = (c, u) => (u ? t('cmd.ucs.is', { at: fmtLen(c, u.x) + ', ' + fmtLen(c, u.y), ang: fmt(deg(normAngle(u.ang))) }) : t('cmd.ucs.world'));

In detail

Method
Origin and X-axis point, rotation about Z by an angle, or a quarter turn; the angle is kept in radians.
Number types
64-bit numbers.
Tolerances
1e-12 drawing units, absolute, in this file: an X-axis point closer than this to the origin keeps the current angle. ucs.js threePoint returns no system below 1e-9.
Limits
The two tolerances differ: after a new origin, an X-axis point between 1e-12 and 1e-9 drawing units from it passes this file's test, gets no system from threePoint, and sets the world system.

Approach: 64-bit, direct

Every value is a 64-bit number from input to result. Formulas are closed form or a direct solve, and every comparison uses a stated tolerance.

Every policy that takes this approach