Resources Numerical accuracy Calculation policy

Cores of a cable on a schematic

Finds which wires a cable marker's slash crosses, in order, for the cable list.

How the precision is kept

A wire belongs to a cable when one of its segments crosses the marker's slash. The crossing test takes the signs of four cross products computed in 64-bit numbers; it is not an exact predicate. A wire end that only touches the slash counts when it lies within 1e-6 drawing units of it.

Open item. Order the cores by the crossing point on the slash instead of by the projection of the wire segment's first point.

Calculations under this policy

2 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.

addons/electrical/lib/reports.js CadCraft 0.8.2 64-bit 2 calculations Reviewed

Tests None found by the review

Does a wire segment cross the slash

64-bit

Whether two segments cross or touch.

o(p, q, r) = sign((q − p) × (r − p)); cross when o₁ ≠ o₂ and o₃ ≠ o₄

Each orientation is the sign of a 64-bit cross product with no tolerance, so for nearly collinear points rounding decides the sign. The touching case is reached only when an orientation is exactly zero, and then uses an absolute squared distance of 1e-12.

  • addons/electrical/lib/reports.js
  • lines 62 to 69
  • CadCraft 0.8.2
/** Does segment ab cross segment cd (touching counts)? */
function crosses(a, b, c, d) {
  const o = (p, q, r) => Math.sign((q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x));
  const o1 = o(a, b, c), o2 = o(a, b, d), o3 = o(c, d, a), o4 = o(c, d, b);
  if (o1 !== o2 && o3 !== o4) return true;
  const on = (p, q, r) => segDist2(r, p, q).d2 < 1e-12;
  return (o1 === 0 && on(a, b, c)) || (o2 === 0 && on(a, b, d)) || (o3 === 0 && on(c, d, a)) || (o4 === 0 && on(c, d, b));
}

Wires of a cable in order

64-bit

The wires a cable marker crosses, sorted along the marker, which gives each core its number.

The sort key is the position along the slash of the wire segment's first point projected onto the slash and clamped to its ends, not the crossing point. Wires whose first points project beyond the same end of the slash get the same key, and their order is then the order they were found in.

  • addons/electrical/lib/reports.js
  • lines 71 to 86
  • CadCraft 0.8.2
/** The wires a cable marker's slash crosses, in order along the slash. → [wire]. */
export function cableCores(model, cable) {
  const out = [];
  for (const w of model.wires) {
    if (w.space.key !== cable.space.key) continue;
    for (let i = 0; i + 1 < w.pts.length; i++) {
      if (crosses(cable.a, cable.b, w.pts[i], w.pts[i + 1])) {
        // where along the slash
        const r = segDist2(w.pts[i], cable.a, cable.b);
        out.push({ w, u: r.u });
        break;
      }
    }
  }
  return out.sort((x, y) => x.u - y.u).map((x) => x.w);
}

In detail

Method
Segment crossing by orientation signs, with touching ends accepted. Cores are numbered in order along the slash.
Number types
64-bit numbers.
Tolerances
Touching: squared distance below 1e-12 drawing units squared (absolute), tested only when an orientation is exactly zero.
Limits
The orientation sign of three nearly collinear points is decided by rounding.

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