Writes an overhead line study as a .DON XML file in meters and decanewtons for another line program, and reads such a file back into a line.
How the precision is kept
The values written are computed in 64-bit and then fixed to the format's decimals: 3 for coordinates and lengths, 2 for forces in daN, 4 for angles and 1 for temperatures. A file read back therefore carries millimeter coordinates. The file header says the layout is untested with the program that reads it.
Calculations under this policy
7 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.
Turns a value into the fixed-decimal text the file carries, and newtons into decanewtons.
text = v.toFixed(d); daN = N ÷ 10, 2 decimals
Every exported number is rounded by toFixed to the decimals its field uses. A negative zero is written without its sign. Non-finite values are left out.
powerline/don.js
lines 70 to 71
CivilCraft 0.8.1
const fx = (v, d) => { if (!fin(v)) return null; const s = v.toFixed(d); return /^-0\.0*$/.test(s) ? s.slice(1) : s; };
const daN = (N) => fx(fin(N) ? N / N_PER_DAN : NaN, 2);
Signed line angle at each support
64-bit
The turn of the line at each support in degrees, counter-clockwise positive.
turn = atan2 of the span ahead − atan2 of the span behind, wrapped to ±180°
A difference of two Math.atan2 bearings wrapped by 2π and multiplied by 180 ÷ Math.PI; it is then written with 4 decimals.
powerline/don.js
lines 75 to 85
CivilCraft 0.8.1
/** Signed turn at each support in degrees, counter-clockwise positive (0 at the ends). */
function signedTurns(line) {
const P = line.supports;
return P.map((p, i) => {
if (i === 0 || i === P.length - 1) return 0;
let d = Math.atan2(P[i + 1].y - p.y, P[i + 1].x - p.x) - Math.atan2(p.y - P[i - 1].y, p.x - P[i - 1].x);
while (d > Math.PI) d -= 2 * Math.PI;
while (d < -Math.PI) d += 2 * Math.PI;
return d * 180 / Math.PI;
});
}
Support coordinates and heights written
64-bit
Each support's position, ground level, pole length, height above ground and line angle as written to the file.
X = x × m per unit, 3 decimals; Hauteur = typed height × m per unit + embedment
Project coordinates are multiplied by the unit factor and fixed to 3 decimals, one millimeter. Large grid coordinates keep their full size in the file; no origin is subtracted.
Turns a field's text into a number, accepting a decimal comma.
The text is checked against a number pattern and converted with the unary plus, which gives the nearest 64-bit value. Values of 1e12 or more in magnitude are refused.
powerline/don.js
lines 301 to 308
CivilCraft 0.8.1
function numOf(s) {
if (s == null) return null;
let t = String(s).replace(/\s+/g, '');
if (/^[+-]?\d*,\d+$/.test(t)) t = t.replace(',', '.');
if (!/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d{1,3})?$/.test(t)) return null;
const v = +t;
return Number.isFinite(v) && Math.abs(v) < 1e12 ? v : null;
}
Angles in grades
64-bit
Converts a line angle given in grades to degrees.
degrees = grades × 0.9
0.9 is the exact ratio 360 ÷ 400, applied as one multiplication; 0.9 itself is not exactly representable in binary, so the product is rounded once.
powerline/don.js
line 342
CivilCraft 0.8.1
angle_deg: ang != null ? (grades ? ang * 0.9 : ang) : null,
A study file into a line
64-bit
Turns the supports read from a file into a line in project units.
x = X (m) ÷ m per unit; voltage kV = V ÷ 1000
Meters are divided by the unit factor, 0.3048 for feet. The inputs carry the 3 decimals the file was written with. Coordinates of 1e9 or more in magnitude are refused.
Fixed-decimal text through toFixed. Project units are converted to meters with unitM from units.js (0.3048 per foot) on writing and divided by it on reading. Angles in grades are multiplied by 0.9 on reading.
Number types
64-bit numbers, written as fixed-decimal text.
Tolerances
Coordinates and lengths 3 decimals of a meter; forces 2 decimals of a decanewton; angles 4 decimals of a degree; temperatures 1 decimal.
Limits
Numbers read must be below 1e12 in magnitude. A decimal comma is accepted. Integer fields that hold a fraction are rounded.
Approach: 64-bit, stated limit
The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.