diff --git a/src/data/fleetModels.js b/src/data/fleetModels.js index 6a3749561..360c59af3 100644 --- a/src/data/fleetModels.js +++ b/src/data/fleetModels.js @@ -343,18 +343,22 @@ export function aircraftModelSpec(set, { typeCode, type, category } = {}) { * @returns {object} {@link fleetModelSpec} */ export function vesselModelSpec(set, { type, length, beam, name } = {}) { + // A beam counts only beside a reported length: a vessel drawn at its type's + // typical length keeps the model's proportions. + const reported = hullLength(length ?? undefined); + const hullWidth = reported === undefined ? undefined : (beam ?? undefined); const resolved = resolveVessel( set.types, aisShipTypeCode(type), - length ?? undefined, - beam ?? undefined, + reported, + hullWidth, name ?? undefined, ); return specOf( set, resolved, (r) => ({ model: set.types.default_vessel, length: r.length }), - { beam: beam ?? undefined }, + { beam: hullWidth }, ); } diff --git a/src/data/fleetModels.test.mjs b/src/data/fleetModels.test.mjs index f0387e65d..8d773901f 100644 --- a/src/data/fleetModels.test.mjs +++ b/src/data/fleetModels.test.mjs @@ -291,6 +291,12 @@ test('vessel specs read AIS codes and text families, stretched to the reported b const [sx, sy, sz] = box.scaleXYZ; assert.ok(Math.abs(sy - 51 / catalog.container_ship.beam) < 1e-12); assert.ok(Math.abs(sz - (sx + sy) / 2) < 1e-12); + // A beam with no reported length: the type's typical length, in the model's + // own proportions, not a typical-length hull squeezed to that beam. + const unsized = vesselModelSpec(set, { type: '70', length: 0, beam: 14 }); + assert.equal(unsized.model, 'container_ship'); + const [ux, uy, uz] = unsized.scaleXYZ; + assert.ok(Math.abs(uy - ux) < 1e-12 && Math.abs(uz - ux) < 1e-12); assert.equal(vesselModelSpec(set, { type: 'Tug', length: 30 }).model, 'tug'); assert.equal(vesselModelSpec(set, { type: '36' }).model, 'sailboat'); // No type, no size: the generic vessel as built.