diff --git a/scripts/engendrer_livrables.js b/scripts/engendrer_livrables.js index 4bc5162..9637f22 100644 --- a/scripts/engendrer_livrables.js +++ b/scripts/engendrer_livrables.js @@ -28,9 +28,11 @@ // plus grande à égalité ; une table d'une autre capacité porte la sienne // en surcharge (§ 6.1) ; // - les tables rondes, rangées en grille dans l'ordre de la configuration, -// rangée par rangée, leurs centres espacés de 300 cm ; la grille a la plus -// petite largeur dont le carré contient toutes les tables, et seule sa -// dernière rangée est incomplète ; +// rangée par rangée, leurs rangées espacées de 300 cm ; la grille a la +// plus petite largeur dont le carré contient toutes les tables, et seule +// sa dernière rangée est incomplète. Ses colonnes s'écartent assez pour +// que le bloc de noms d'une table, de toute sa largeur, tienne entre deux +// colonnes : aucune liste ne passe sur une autre table (§ 7.4) ; // - les contraintes de la configuration, les sièges non attribués, la // génération par défaut de la recherche ; // - chaque réservation, celle d'un animateur, au siège 1 de sa table pour @@ -47,6 +49,8 @@ import { decoder } from '../src/csv/encodage.js'; import { SEPARATEUR, ecrireCsv, exporterParticipants } from '../src/csv/export.js'; import { decouper } from '../src/csv/lecture.js'; import { CATALOGUE } from '../src/demo/catalogue.js'; +import { constante } from '../src/geometrie/constantes.js'; +import { ECART_LISTE, geometrieTable } from '../src/geometrie/tables.js'; import { serialiser, serialiserCharge } from '../src/stockage/canonique.js'; import { analyser, creerCharge } from '../src/stockage/document.js'; import { VERSION } from '../src/version.genere.js'; @@ -66,8 +70,8 @@ const DEMONSTRATIONS_EN_CSV = ['petite', 'grande']; // Séparateur de la variante windows-1252 (§ 10.3). const VIRGULE = ','; -// Écart entre les centres de deux tables voisines de la grille, en cm. -const ECART_CM = 300; +// Écart entre les centres de deux rangées de la grille, en cm. +const ECART_RANGEES_CM = 300; // Le siège de l'animateur, et le titre qu'il porte. const SIEGE_ANIMATEUR = 1; @@ -96,6 +100,21 @@ function colonnesDe(nombre) { return colonnes; } +// Écart entre les centres de deux colonnes de la grille, en cm entiers : le +// bloc de noms d'une table commence à ECART_LISTE de son emprise et s'étend +// sur LARGEUR_BLOC_NOMS_CM, où toute ligne s'abrège ; il s'achève à +// ECART_LISTE de l'emprise de la colonne suivante, pour la plus grande +// emprise des capacités données. Aucune emprise, d'aucune rangée, ne +// rencontre ainsi la bande du bloc. +function ecartColonnes(capacites) { + const emprise = Math.max( + ...capacites.map( + (places) => geometrieTable({ id: 0, numero: 0, forme: 'ronde', position: { x: 0, y: 0 } }, places).rayonEmprise, + ), + ); + return Math.ceil(2 * emprise + 2 * ECART_LISTE + constante('LARGEUR_BLOC_NOMS_CM')); +} + // Plus grand identifiant d'une liste d'enregistrements ; 0 pour une liste // vide. const plusGrandId = (enregistrements) => enregistrements.reduce((plus, { id }) => Math.max(plus, id), 0); @@ -134,6 +153,7 @@ export function chargeDeDemonstration({ cle, nom, construire }) { const animateurs = animateursDe(reservations, cle); const reserves = new Set(animateurs.values()); const colonnes = colonnesDe(tables.length); + const ecart = ecartColonnes(tables.map(({ capacite }) => capacite)); const { separerAppartenances, nouveauxVoisins, nouvelleTable, varierAppartenances } = contraintes; return { ...neuve, @@ -154,7 +174,7 @@ export function chargeDeDemonstration({ cle, nom, construire }) { numero, sieges: capacite === siegesParDefaut ? null : capacite, forme: 'ronde', - position: { x: (rang % colonnes) * ECART_CM, y: Math.floor(rang / colonnes) * ECART_CM }, + position: { x: (rang % colonnes) * ecart, y: Math.floor(rang / colonnes) * ECART_RANGEES_CM }, })), reservations: [...animateurs].map(([table, participant]) => ({ participant, diff --git a/scripts/engendrer_livrables.test.js b/scripts/engendrer_livrables.test.js index 2be9eaf..39dfe81 100644 --- a/scripts/engendrer_livrables.test.js +++ b/scripts/engendrer_livrables.test.js @@ -209,18 +209,22 @@ describe("engendrer_livrables : la charge d'une démonstration (§ 15)", () => { }); }); - test('les tables : rondes, en grille rangée par rangée, centres à 300 cm, la dernière rangée seule incomplète', () => { + test('les tables : rondes, en grille rangée par rangée, la dernière rangée seule incomplète ; rangées à 300 cm, colonnes assez écartées pour le bloc de noms', () => { + // Écart des colonnes : 2 × l'emprise de la plus grande table, deux écarts + // de liste (36 cm) et la largeur du bloc de noms (500 cm), arrondi au cm + // supérieur — petite, 3 places, emprise 79 : 158 + 72 + 500 = 730 ; + // grande, 8 places, emprise 120,39 : ⌈240,79 + 72 + 500⌉ = 813. assert.deepEqual(chargeDeDemonstration(entreeDe('petite')).tables, [ { id: 1, numero: 1, sieges: null, forme: 'ronde', position: { x: 0, y: 0 } }, - { id: 2, numero: 2, sieges: null, forme: 'ronde', position: { x: 300, y: 0 } }, + { id: 2, numero: 2, sieges: null, forme: 'ronde', position: { x: 730, y: 0 } }, { id: 3, numero: 3, sieges: null, forme: 'ronde', position: { x: 0, y: 300 } }, - { id: 4, numero: 4, sieges: null, forme: 'ronde', position: { x: 300, y: 300 } }, + { id: 4, numero: 4, sieges: null, forme: 'ronde', position: { x: 730, y: 300 } }, ]); // 33 tables : six colonnes, cinq rangées pleines, puis trois tables. const { tables } = chargeDeDemonstration(entreeDe('grande')); const positions = tables.map(({ position: { x, y } }) => [x, y]); - assert.deepEqual(positions.slice(0, 7), [[0, 0], [300, 0], [600, 0], [900, 0], [1200, 0], [1500, 0], [0, 300]]); - assert.deepEqual(positions.slice(-4), [[1500, 1200], [0, 1500], [300, 1500], [600, 1500]]); + assert.deepEqual(positions.slice(0, 7), [[0, 0], [813, 0], [1626, 0], [2439, 0], [3252, 0], [4065, 0], [0, 300]]); + assert.deepEqual(positions.slice(-4), [[4065, 1200], [0, 1500], [813, 1500], [1626, 1500]]); assert.equal(new Set(positions.map(String)).size, 33); assert.ok(tables.every(({ forme }) => forme === 'ronde')); assert.deepEqual(tables.map(({ id, numero }) => [id, numero]), positions.map((_, rang) => [rang + 1, rang + 1])); diff --git a/src/demo/livrees.test.js b/src/demo/livrees.test.js index 28b8d2d..22ca076 100644 --- a/src/demo/livrees.test.js +++ b/src/demo/livrees.test.js @@ -19,6 +19,8 @@ import { versionVoisine } from '../../test/version_voisine.js'; import { apercevoir } from '../csv/apercu.js'; import { decoder } from '../csv/encodage.js'; import { exporterParticipants } from '../csv/export.js'; +import { constante } from '../geometrie/constantes.js'; +import { geometrieTable } from '../geometrie/tables.js'; import { serialiser } from '../stockage/canonique.js'; import { analyser } from '../stockage/document.js'; import { examiner } from '../stockage/placements.js'; @@ -155,6 +157,25 @@ describe('démonstrations livrées : les fichiers (§ 15.5, point 5)', () => { assert.deepEqual([charge.propositions, charge.retenu], [[], null], cle); } }); + + test("le bloc de noms d'une table, de toute sa largeur, ne rencontre l'emprise d'aucune autre table, d'aucune rangée (§ 7.4)", () => { + // Le bloc s'étend de origineListe.x sur LARGEUR_BLOC_NOMS_CM, où toute + // ligne s'abrège ; sa hauteur, mesurée sur la police, ne se connaît pas + // ici : l'épreuve exige la bande verticale entière libre de toute emprise. + const largeur = constante('LARGEUR_BLOC_NOMS_CM'); + for (const { cle, texte } of LIVREES) { + const { charge } = analyser(texte); + const geometries = charge.tables.map((table) => geometrieTable(table, table.sieges ?? charge.evenement.siegesParDefaut)); + const rencontres = geometries.flatMap((g) => + geometries + .filter((autre) => autre !== g) + .filter((autre) => autre.centre.x - autre.rayonEmprise < g.origineListe.x + largeur && autre.centre.x + autre.rayonEmprise > g.origineListe.x) + .map((autre) => `table ${g.numero} sur la table ${autre.numero}`), + ); + assert.ok(geometries.length > 1, cle); + assert.deepEqual(rencontres, [], cle); + } + }); }); describe('démonstrations livrées : aller-retour sur la petite (§ 8.9, § 14.4)', () => { diff --git a/src/demo/livrees/grande-sans-exception.gtt.json b/src/demo/livrees/grande-sans-exception.gtt.json index 3e4c42a..c5407bc 100644 --- a/src/demo/livrees/grande-sans-exception.gtt.json +++ b/src/demo/livrees/grande-sans-exception.gtt.json @@ -268,38 +268,38 @@ ], "tables": [ {"id":1,"numero":1,"sieges":null,"forme":"ronde","position":{"x":0,"y":0}}, - {"id":2,"numero":2,"sieges":null,"forme":"ronde","position":{"x":300,"y":0}}, - {"id":3,"numero":3,"sieges":null,"forme":"ronde","position":{"x":600,"y":0}}, - {"id":4,"numero":4,"sieges":null,"forme":"ronde","position":{"x":900,"y":0}}, - {"id":5,"numero":5,"sieges":null,"forme":"ronde","position":{"x":1200,"y":0}}, - {"id":6,"numero":6,"sieges":null,"forme":"ronde","position":{"x":1500,"y":0}}, + {"id":2,"numero":2,"sieges":null,"forme":"ronde","position":{"x":813,"y":0}}, + {"id":3,"numero":3,"sieges":null,"forme":"ronde","position":{"x":1626,"y":0}}, + {"id":4,"numero":4,"sieges":null,"forme":"ronde","position":{"x":2439,"y":0}}, + {"id":5,"numero":5,"sieges":null,"forme":"ronde","position":{"x":3252,"y":0}}, + {"id":6,"numero":6,"sieges":null,"forme":"ronde","position":{"x":4065,"y":0}}, {"id":7,"numero":7,"sieges":null,"forme":"ronde","position":{"x":0,"y":300}}, - {"id":8,"numero":8,"sieges":null,"forme":"ronde","position":{"x":300,"y":300}}, - {"id":9,"numero":9,"sieges":null,"forme":"ronde","position":{"x":600,"y":300}}, - {"id":10,"numero":10,"sieges":null,"forme":"ronde","position":{"x":900,"y":300}}, - {"id":11,"numero":11,"sieges":null,"forme":"ronde","position":{"x":1200,"y":300}}, - {"id":12,"numero":12,"sieges":null,"forme":"ronde","position":{"x":1500,"y":300}}, + {"id":8,"numero":8,"sieges":null,"forme":"ronde","position":{"x":813,"y":300}}, + {"id":9,"numero":9,"sieges":null,"forme":"ronde","position":{"x":1626,"y":300}}, + {"id":10,"numero":10,"sieges":null,"forme":"ronde","position":{"x":2439,"y":300}}, + {"id":11,"numero":11,"sieges":null,"forme":"ronde","position":{"x":3252,"y":300}}, + {"id":12,"numero":12,"sieges":null,"forme":"ronde","position":{"x":4065,"y":300}}, {"id":13,"numero":13,"sieges":null,"forme":"ronde","position":{"x":0,"y":600}}, - {"id":14,"numero":14,"sieges":null,"forme":"ronde","position":{"x":300,"y":600}}, - {"id":15,"numero":15,"sieges":null,"forme":"ronde","position":{"x":600,"y":600}}, - {"id":16,"numero":16,"sieges":null,"forme":"ronde","position":{"x":900,"y":600}}, - {"id":17,"numero":17,"sieges":null,"forme":"ronde","position":{"x":1200,"y":600}}, - {"id":18,"numero":18,"sieges":null,"forme":"ronde","position":{"x":1500,"y":600}}, + {"id":14,"numero":14,"sieges":null,"forme":"ronde","position":{"x":813,"y":600}}, + {"id":15,"numero":15,"sieges":null,"forme":"ronde","position":{"x":1626,"y":600}}, + {"id":16,"numero":16,"sieges":null,"forme":"ronde","position":{"x":2439,"y":600}}, + {"id":17,"numero":17,"sieges":null,"forme":"ronde","position":{"x":3252,"y":600}}, + {"id":18,"numero":18,"sieges":null,"forme":"ronde","position":{"x":4065,"y":600}}, {"id":19,"numero":19,"sieges":null,"forme":"ronde","position":{"x":0,"y":900}}, - {"id":20,"numero":20,"sieges":null,"forme":"ronde","position":{"x":300,"y":900}}, - {"id":21,"numero":21,"sieges":null,"forme":"ronde","position":{"x":600,"y":900}}, - {"id":22,"numero":22,"sieges":null,"forme":"ronde","position":{"x":900,"y":900}}, - {"id":23,"numero":23,"sieges":null,"forme":"ronde","position":{"x":1200,"y":900}}, - {"id":24,"numero":24,"sieges":null,"forme":"ronde","position":{"x":1500,"y":900}}, + {"id":20,"numero":20,"sieges":null,"forme":"ronde","position":{"x":813,"y":900}}, + {"id":21,"numero":21,"sieges":null,"forme":"ronde","position":{"x":1626,"y":900}}, + {"id":22,"numero":22,"sieges":null,"forme":"ronde","position":{"x":2439,"y":900}}, + {"id":23,"numero":23,"sieges":null,"forme":"ronde","position":{"x":3252,"y":900}}, + {"id":24,"numero":24,"sieges":null,"forme":"ronde","position":{"x":4065,"y":900}}, {"id":25,"numero":25,"sieges":null,"forme":"ronde","position":{"x":0,"y":1200}}, - {"id":26,"numero":26,"sieges":null,"forme":"ronde","position":{"x":300,"y":1200}}, - {"id":27,"numero":27,"sieges":null,"forme":"ronde","position":{"x":600,"y":1200}}, - {"id":28,"numero":28,"sieges":null,"forme":"ronde","position":{"x":900,"y":1200}}, - {"id":29,"numero":29,"sieges":null,"forme":"ronde","position":{"x":1200,"y":1200}}, - {"id":30,"numero":30,"sieges":null,"forme":"ronde","position":{"x":1500,"y":1200}}, + {"id":26,"numero":26,"sieges":null,"forme":"ronde","position":{"x":813,"y":1200}}, + {"id":27,"numero":27,"sieges":null,"forme":"ronde","position":{"x":1626,"y":1200}}, + {"id":28,"numero":28,"sieges":null,"forme":"ronde","position":{"x":2439,"y":1200}}, + {"id":29,"numero":29,"sieges":null,"forme":"ronde","position":{"x":3252,"y":1200}}, + {"id":30,"numero":30,"sieges":null,"forme":"ronde","position":{"x":4065,"y":1200}}, {"id":31,"numero":31,"sieges":null,"forme":"ronde","position":{"x":0,"y":1500}}, - {"id":32,"numero":32,"sieges":null,"forme":"ronde","position":{"x":300,"y":1500}}, - {"id":33,"numero":33,"sieges":null,"forme":"ronde","position":{"x":600,"y":1500}} + {"id":32,"numero":32,"sieges":null,"forme":"ronde","position":{"x":813,"y":1500}}, + {"id":33,"numero":33,"sieges":null,"forme":"ronde","position":{"x":1626,"y":1500}} ], "reservations": [ {"participant":2,"table":17,"siege":1,"portee":"tous","tour":null}, diff --git a/src/demo/livrees/grande.gtt.json b/src/demo/livrees/grande.gtt.json index 905bfc7..05c5f6b 100644 --- a/src/demo/livrees/grande.gtt.json +++ b/src/demo/livrees/grande.gtt.json @@ -268,38 +268,38 @@ ], "tables": [ {"id":1,"numero":1,"sieges":null,"forme":"ronde","position":{"x":0,"y":0}}, - {"id":2,"numero":2,"sieges":null,"forme":"ronde","position":{"x":300,"y":0}}, - {"id":3,"numero":3,"sieges":null,"forme":"ronde","position":{"x":600,"y":0}}, - {"id":4,"numero":4,"sieges":null,"forme":"ronde","position":{"x":900,"y":0}}, - {"id":5,"numero":5,"sieges":null,"forme":"ronde","position":{"x":1200,"y":0}}, - {"id":6,"numero":6,"sieges":null,"forme":"ronde","position":{"x":1500,"y":0}}, + {"id":2,"numero":2,"sieges":null,"forme":"ronde","position":{"x":813,"y":0}}, + {"id":3,"numero":3,"sieges":null,"forme":"ronde","position":{"x":1626,"y":0}}, + {"id":4,"numero":4,"sieges":null,"forme":"ronde","position":{"x":2439,"y":0}}, + {"id":5,"numero":5,"sieges":null,"forme":"ronde","position":{"x":3252,"y":0}}, + {"id":6,"numero":6,"sieges":null,"forme":"ronde","position":{"x":4065,"y":0}}, {"id":7,"numero":7,"sieges":null,"forme":"ronde","position":{"x":0,"y":300}}, - {"id":8,"numero":8,"sieges":null,"forme":"ronde","position":{"x":300,"y":300}}, - {"id":9,"numero":9,"sieges":null,"forme":"ronde","position":{"x":600,"y":300}}, - {"id":10,"numero":10,"sieges":null,"forme":"ronde","position":{"x":900,"y":300}}, - {"id":11,"numero":11,"sieges":null,"forme":"ronde","position":{"x":1200,"y":300}}, - {"id":12,"numero":12,"sieges":null,"forme":"ronde","position":{"x":1500,"y":300}}, + {"id":8,"numero":8,"sieges":null,"forme":"ronde","position":{"x":813,"y":300}}, + {"id":9,"numero":9,"sieges":null,"forme":"ronde","position":{"x":1626,"y":300}}, + {"id":10,"numero":10,"sieges":null,"forme":"ronde","position":{"x":2439,"y":300}}, + {"id":11,"numero":11,"sieges":null,"forme":"ronde","position":{"x":3252,"y":300}}, + {"id":12,"numero":12,"sieges":null,"forme":"ronde","position":{"x":4065,"y":300}}, {"id":13,"numero":13,"sieges":null,"forme":"ronde","position":{"x":0,"y":600}}, - {"id":14,"numero":14,"sieges":null,"forme":"ronde","position":{"x":300,"y":600}}, - {"id":15,"numero":15,"sieges":null,"forme":"ronde","position":{"x":600,"y":600}}, - {"id":16,"numero":16,"sieges":null,"forme":"ronde","position":{"x":900,"y":600}}, - {"id":17,"numero":17,"sieges":null,"forme":"ronde","position":{"x":1200,"y":600}}, - {"id":18,"numero":18,"sieges":null,"forme":"ronde","position":{"x":1500,"y":600}}, + {"id":14,"numero":14,"sieges":null,"forme":"ronde","position":{"x":813,"y":600}}, + {"id":15,"numero":15,"sieges":null,"forme":"ronde","position":{"x":1626,"y":600}}, + {"id":16,"numero":16,"sieges":null,"forme":"ronde","position":{"x":2439,"y":600}}, + {"id":17,"numero":17,"sieges":null,"forme":"ronde","position":{"x":3252,"y":600}}, + {"id":18,"numero":18,"sieges":null,"forme":"ronde","position":{"x":4065,"y":600}}, {"id":19,"numero":19,"sieges":null,"forme":"ronde","position":{"x":0,"y":900}}, - {"id":20,"numero":20,"sieges":null,"forme":"ronde","position":{"x":300,"y":900}}, - {"id":21,"numero":21,"sieges":null,"forme":"ronde","position":{"x":600,"y":900}}, - {"id":22,"numero":22,"sieges":null,"forme":"ronde","position":{"x":900,"y":900}}, - {"id":23,"numero":23,"sieges":null,"forme":"ronde","position":{"x":1200,"y":900}}, - {"id":24,"numero":24,"sieges":null,"forme":"ronde","position":{"x":1500,"y":900}}, + {"id":20,"numero":20,"sieges":null,"forme":"ronde","position":{"x":813,"y":900}}, + {"id":21,"numero":21,"sieges":null,"forme":"ronde","position":{"x":1626,"y":900}}, + {"id":22,"numero":22,"sieges":null,"forme":"ronde","position":{"x":2439,"y":900}}, + {"id":23,"numero":23,"sieges":null,"forme":"ronde","position":{"x":3252,"y":900}}, + {"id":24,"numero":24,"sieges":null,"forme":"ronde","position":{"x":4065,"y":900}}, {"id":25,"numero":25,"sieges":null,"forme":"ronde","position":{"x":0,"y":1200}}, - {"id":26,"numero":26,"sieges":null,"forme":"ronde","position":{"x":300,"y":1200}}, - {"id":27,"numero":27,"sieges":null,"forme":"ronde","position":{"x":600,"y":1200}}, - {"id":28,"numero":28,"sieges":null,"forme":"ronde","position":{"x":900,"y":1200}}, - {"id":29,"numero":29,"sieges":null,"forme":"ronde","position":{"x":1200,"y":1200}}, - {"id":30,"numero":30,"sieges":7,"forme":"ronde","position":{"x":1500,"y":1200}}, + {"id":26,"numero":26,"sieges":null,"forme":"ronde","position":{"x":813,"y":1200}}, + {"id":27,"numero":27,"sieges":null,"forme":"ronde","position":{"x":1626,"y":1200}}, + {"id":28,"numero":28,"sieges":null,"forme":"ronde","position":{"x":2439,"y":1200}}, + {"id":29,"numero":29,"sieges":null,"forme":"ronde","position":{"x":3252,"y":1200}}, + {"id":30,"numero":30,"sieges":7,"forme":"ronde","position":{"x":4065,"y":1200}}, {"id":31,"numero":31,"sieges":7,"forme":"ronde","position":{"x":0,"y":1500}}, - {"id":32,"numero":32,"sieges":7,"forme":"ronde","position":{"x":300,"y":1500}}, - {"id":33,"numero":33,"sieges":7,"forme":"ronde","position":{"x":600,"y":1500}} + {"id":32,"numero":32,"sieges":7,"forme":"ronde","position":{"x":813,"y":1500}}, + {"id":33,"numero":33,"sieges":7,"forme":"ronde","position":{"x":1626,"y":1500}} ], "reservations": [ {"participant":2,"table":17,"siege":1,"portee":"tous","tour":null}, diff --git a/src/demo/livrees/petite-conflit.gtt.json b/src/demo/livrees/petite-conflit.gtt.json index 9c320c2..a288009 100644 --- a/src/demo/livrees/petite-conflit.gtt.json +++ b/src/demo/livrees/petite-conflit.gtt.json @@ -20,9 +20,9 @@ ], "tables": [ {"id":1,"numero":1,"sieges":null,"forme":"ronde","position":{"x":0,"y":0}}, - {"id":2,"numero":2,"sieges":null,"forme":"ronde","position":{"x":300,"y":0}}, + {"id":2,"numero":2,"sieges":null,"forme":"ronde","position":{"x":730,"y":0}}, {"id":3,"numero":3,"sieges":null,"forme":"ronde","position":{"x":0,"y":300}}, - {"id":4,"numero":4,"sieges":null,"forme":"ronde","position":{"x":300,"y":300}} + {"id":4,"numero":4,"sieges":null,"forme":"ronde","position":{"x":730,"y":300}} ], "reservations": [], "titres": [], diff --git a/src/demo/livrees/petite.gtt.json b/src/demo/livrees/petite.gtt.json index b5aa42b..44f928b 100644 --- a/src/demo/livrees/petite.gtt.json +++ b/src/demo/livrees/petite.gtt.json @@ -20,9 +20,9 @@ ], "tables": [ {"id":1,"numero":1,"sieges":null,"forme":"ronde","position":{"x":0,"y":0}}, - {"id":2,"numero":2,"sieges":null,"forme":"ronde","position":{"x":300,"y":0}}, + {"id":2,"numero":2,"sieges":null,"forme":"ronde","position":{"x":730,"y":0}}, {"id":3,"numero":3,"sieges":null,"forme":"ronde","position":{"x":0,"y":300}}, - {"id":4,"numero":4,"sieges":null,"forme":"ronde","position":{"x":300,"y":300}} + {"id":4,"numero":4,"sieges":null,"forme":"ronde","position":{"x":730,"y":300}} ], "reservations": [], "titres": [], diff --git a/src/geometrie/tables.js b/src/geometrie/tables.js index 361d8b7..e418136 100644 --- a/src/geometrie/tables.js +++ b/src/geometrie/tables.js @@ -35,8 +35,11 @@ export const RAYON_CHAISE = 22; export const RAYON_POIGNEE = 15; /** Distance entre l'emprise et le bord de la poignée, en cm. */ export const ECART_POIGNEE = 8; -/** Distance entre l'emprise et le bloc de noms, en cm. */ -export const ECART_LISTE = 10; +/** Distance entre l'emprise et le bloc de noms, en cm : le carré du focus + * que l'interface pose autour de l'emprise, ou d'une chaise, s'étend à + * 26 cm d'elle, plus la moitié de son trait ; le bloc commence au-delà, et + * aucune marque ne couvre la liste. */ +export const ECART_LISTE = 36; /** Distance entre deux cases de la grille des tables créées, en cm. */ export const PAS_GRILLE = 300; diff --git a/src/geometrie/tables.test.js b/src/geometrie/tables.test.js index 0b2c09a..befc550 100644 --- a/src/geometrie/tables.test.js +++ b/src/geometrie/tables.test.js @@ -49,7 +49,7 @@ describe('constantes', () => { assert.equal(RAYON_CHAISE, 22); assert.equal(RAYON_POIGNEE, 15); assert.equal(ECART_POIGNEE, 8); - assert.equal(ECART_LISTE, 10); + assert.equal(ECART_LISTE, 36); assert.equal(PAS_GRILLE, 300); }); }); @@ -119,7 +119,7 @@ describe('geometrieTable, ronde', () => { proche(g.rayonEmprise, r + 44, 'rayon d’emprise'); const ecart = (r + 44 + 23) / Math.SQRT2; procheDuPoint(g.poignee, { x: 300 + ecart, y: 600 + ecart }, 'poignée'); - procheDuPoint(g.origineListe, { x: 300 + r + 54, y: 600 - r }, 'origine de la liste'); + procheDuPoint(g.origineListe, { x: 300 + r + 80, y: 600 - r }, 'origine de la liste'); }); test('ronde de 3 : plancher de 70 cm, pas 70π/3', () => { @@ -163,10 +163,10 @@ describe('geometrieTable, carrée', () => { }); }); - test('emprise 104, poignée au-delà du coin, liste en (414, 540)', () => { + test('emprise 104, poignée au-delà du coin, liste en (440, 540)', () => { assert.equal(g.rayonEmprise, 104); procheDuPoint(g.poignee, { x: 404 + 23 / Math.SQRT2, y: 704 + 23 / Math.SQRT2 }, 'poignée'); - procheDuPoint(g.origineListe, { x: 414, y: 540 }, 'origine de la liste'); + procheDuPoint(g.origineListe, { x: 440, y: 540 }, 'origine de la liste'); }); test('carrée de 3 : côtés garnis 1, 1, 1, 0 et pas 70', () => { diff --git a/src/interface/evenement/CadreMode.svelte b/src/interface/evenement/CadreMode.svelte index 35030cd..d4f6bfa 100644 --- a/src/interface/evenement/CadreMode.svelte +++ b/src/interface/evenement/CadreMode.svelte @@ -38,12 +38,15 @@ // forme de la lecture, et n'a pas de libellé. const cadre = $derived(cadreDeMode($seance)); const forme = $derived(cadre?.forme ?? 'tirets'); + // Le trait du cadre est une marque (§ 14.5) : data-marque nomme l'entrée + // du registre (marques.js) qui porte le jeton de sa couleur. + const MARQUE_DE_LA_FORME = { tirets: 'cadreLecture', plein: 'cadreEcriture', double: 'cadreBloque' }; const commande = $derived(commandeFixe($seance)); const verrou = $derived($seance.mode === 'lecture' ? $seance.verrouAutre : null); const reprise = $derived(repriseOfferte($seance)); -