gestion_table_tournante_libre/src/geometrie/designation.js
Mathieu Benoit eec14bdcb0 [ADD] geometry: tables, their chairs, designating a seat
A table's tabletop, chairs, footprint and handle derive from its number of
places, chairs numbered clockwise from the top, in drawing centimetres.
The seat a pointer designates is read from the same chairs the drawing
places, through one implementation, so what is drawn and where a drop
lands cannot disagree. No table rotates.
Checked: 1681 node tests.

--- FR ---

[ADD] géométrie : les tables, leurs chaises, la désignation d'un siège

Le plateau, les chaises, l'emprise et la poignée d'une table dérivent de son
nombre de places, chaises numérotées depuis le haut dans le sens horaire,
en centimètres de dessin. Le siège que désigne un pointeur se lit sur les
chaises mêmes que le dessin pose, par une seule implémentation : ce qui est
dessiné et l'endroit où tombe un dépôt ne peuvent diverger. Aucune table ne
tourne.
Vérifié : 1681 épreuves node.

Assisted-by: Claude Opus 5.5
2026-10-07 02:32:47 -04:00

75 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// © 2026 TechnoLibre (http://www.technolibre.ca)
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
// La désignation d'un siège (§ 7.3, § 14.10) : ce que contient un point de
// dessin, lu sur les géométries de tables.js, celles mêmes que le dessin pose.
// Le dépôt d'un glissement ne cherche pas sa cible dans le DOM : il convertit
// le point en coordonnées de dessin et le passe à designer.
/** Taille d'écran minimale d'une cible de siège, en px (§ 7.3). */
export const CIBLE_MIN_PX = 24;
// Vrai quand le point est dans le disque (ronde) ou le carré aux côtés
// parallèles aux axes (carrée) de demi-taille donnée, centré sur la table,
// bord compris.
function dans(point, { centre, forme }, demiTaille) {
const dx = point.x - centre.x;
const dy = point.y - centre.y;
return forme === 'ronde' ? Math.hypot(dx, dy) <= demiTaille : Math.max(Math.abs(dx), Math.abs(dy)) <= demiTaille;
}
/**
* Régime des cibles d'une table au zoom k : 'sieges' quand k × pas ≥
* CIBLE_MIN_PX, 'table' sinon. Le seuil se décide table par table, sur le
* pas de chacune.
*
* @param {number} k px/cm
* @param {import('./tables.js').GeometrieTable} geometrie
* @returns {'sieges'|'table'}
*/
export function regimeCibles(k, geometrie) {
return k * geometrie.pas >= CIBLE_MIN_PX ? 'sieges' : 'table';
}
/**
* Ce que désigne un point de dessin au zoom k.
*
* Les tables s'examinent de la dernière reçue à la première, l'ordre inverse
* de la peinture : la première dont la surface peinte contient le point
* décide. En régime table, la surface est l'emprise — disque d'une ronde,
* carré d'une carrée — et la table est désignée. En régime sièges, elle est
* le plateau et les chaises : un point dans une chaise désigne son siège ;
* un point sur le plateau ne désigne rien, et cache les chaises des tables
* peintes dessous ; entre les chaises, le point passe aux tables de dessous.
* Deux chaises d'une même table ne se recouvrent pas.
*
* @param {{x: number, y: number}} point cm
* @param {import('./tables.js').GeometrieTable[]} geometries dans l'ordre du dessin
* @param {number} k px/cm
* @returns {{table: number, siege: number}|{table: number}|null}
*/
export function designer(point, geometries, k) {
for (let i = geometries.length - 1; i >= 0; i -= 1) {
const geometrie = geometries[i];
if (regimeCibles(k, geometrie) === 'table') {
if (dans(point, geometrie, geometrie.rayonEmprise)) return { table: geometrie.id };
continue;
}
const chaise = geometrie.chaises.find((c) => Math.hypot(point.x - c.x, point.y - c.y) <= c.rayon);
if (chaise !== undefined) return { table: geometrie.id, siege: chaise.siege };
if (dans(point, geometrie, geometrie.demiTaille)) return null;
}
return null;
}
/**
* Vrai quand le point n'est dans l'emprise — disque ou carré — d'aucune
* table : le sol, où un dépôt retire la personne du tour.
*
* @param {{x: number, y: number}} point cm
* @param {import('./tables.js').GeometrieTable[]} geometries
* @returns {boolean}
*/
export function surLeSol(point, geometries) {
return !geometries.some((geometrie) => dans(point, geometrie, geometrie.rayonEmprise));
}