Works out the matrix that puts a linked IFC model in the right place beside the open one, from both files' map positions or from two pairs of picked points.
How the precision is kept
Both methods build a 4 × 4 matrix in 64-bit, in millimeters. Through the maps, six matrices are multiplied and the two large map positions largely cancel in the product. From picked points, the matrix is a turn about the vertical and a move. The matrix is saved with each entry rounded to 9 decimals.
Open item. Save the link matrix with full 64-bit precision instead of 9 decimals.
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.
The matrix from the linked file's millimeters to the open model's, through the map grid both are placed on.
m = S(host unit) × host map⁻¹ × S(1 ÷ host map unit) × S(link map unit) × link map × S(1 ÷ link unit)
Six 4 × 4 products and one general inverse. Map eastings and northings are large and nearly equal for two models on one site, so the product subtracts nearly equal large numbers; the unit scalings are multiplications and divisions by the files' own unit factors.
model-links.js
lines 91 to 97
BimCraft 0.8.1
export function mapMatrix(hg, lg, hostUnitMm, linkUnitMm) {
if (!hg || !lg || hg.kind !== 'map' || lg.kind !== 'map') return null;
// link mm → link file units → its map (metres) → the model's map units → the model's file units → mm
const linkToMetres = mul4(S(lg.mapUnitM), mul4(lg.matrix, S(1 / linkUnitMm)));
const metresToHost = mul4(S(hostUnitMm), mul4(inv4(hg.matrix), S(1 / hg.mapUnitM)));
return mul4(metresToHost, linkToMetres);
}
Link matrix from two pairs of points
64-bit
The turn and move that carry two picked points of the linked model onto two picked points of the open one.
a = atan2(h₁ − h₀) − atan2(l₁ − l₀); t = h₀ − R(a) × l₀
The turn is the difference of two atan2 angles, then one cosine and sine. The move is the first host point minus the turned first link point, so the first pair matches and the second only sets the direction.
Each of the 16 entries is rounded to 9 decimals. The translation is in millimeters and keeps 1e-9 mm; the rotation entries have no unit, so a point 1 km from the origin can shift by up to 0.0005 mm for each rounded entry it is multiplied by.
Map: link mm → link units → map meters → host map units → host units → mm. Points: angle = direction of the host pair − direction of the link pair; translation = host point − R × link point.
Number types
64-bit numbers; a matrix is an array of 16, column-major.
Tolerances
Saved entries rounded to 1e-9, absolute.
Checked by
tools/bimcraft-test/draw06-test.mjs calls mapMatrix, pairsMatrix, sceneAdjust and fileOfScene in Node.
Limits
The picked-points method solves a turn about the vertical and a move only; it does not solve a scale, and the second pair gives a direction, not a distance.
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.