Les briques élémentaires sur lesquelles repose tout le moteur : aire, point-dans-polygone, angle principal, géométrie des portes. Pur stdlib Python — aucune dépendance externe.
Calculer l'aire d'un polygone quelconque à partir de ses sommets, sans trigonométrie.
On parcourt les sommets dans l'ordre. Pour chaque arête (xᵢ, yᵢ) → (xᵢ₊₁, yᵢ₊₁), on calcule le produit croisé des coordonnées consécutives. La somme de ces produits donne le double de l'aire signée.
Complexité O(n) où n = nombre de sommets. Aucune allocation mémoire.
test_polygon_area compare le résultat à Shapely sur les 4 pièces de référence. Écart maximal : 10⁻¹⁰ m².Le test fondamental du moteur : est-ce qu'une emprise est « dedans » ?
Lancer un rayon horizontal depuis le point vers l'infini (+∞). Compter le nombre d'intersections avec les arêtes du polygone.
Coût O(n) par requête, où n = nombre d'arêtes. Le constructeur appelle cette fonction des centaines de fois par implantation.
Les cas limites (point exactement sur une arête, sommet partagé) sont gérés par la condition stricte > plutôt que >=.
L'angle qui aligne les rangées sur le « mur dominant » de la pièce.
L'arête la plus longue correspond en général au mur principal de la pièce. Aligner les rangées dessus maximise le nombre d'emprises sur la longueur disponible. Le modulo π assure que les deux directions d'un même mur sont équivalentes.
Le constructeur teste systématiquement θ et θ + π/2 (les rangées perpendiculaires au mur dominant). C'est un des « 8 combinaisons » du M2.
Comment calculer le dégagement de porte et le nœud d'accès — en 4 étapes.
La porte est située sur une arête du polygone. On projette le centre de la porte sur l'arête la plus proche pour obtenir le vecteur tangent à la paroi.
Perpendiculaire au vecteur tangent, orientée vers le centroïde du polygone. C'est la direction « vers l'intérieur de la pièce ».
Rectangle de 1,20 m de profondeur devant la porte, centré sur l'ouverture. Aucune emprise ne peut être placée dans cette zone.
Point d'ancrage pour le graphe de circulation (M4). Position = centre de la porte + 0,15 m vers l'intérieur (un pas de grille).
Le décalage de 0,15 m correspond à un pas de la grille fine du module de circulation (M4). Il garantit que le nœud est bien à l'intérieur du polygone et sur un nœud de la grille.
Une frontière de dépendance claire et volontaire.
io, core.geometry) est stdlib pur — aucun import de shapely ni de numpy. Ces dépendances ne sont autorisées que dans room_model.py et viz/.| Module | Dépendances | Justification |
|---|---|---|
| core.geometry | math (stdlib) |
Portabilité maximale, exécutable dans pyRevit (IronPython) |
| io.loader | json (stdlib) |
Chargement JSON sans dépendance tierce |
| room_model | shapely |
Opérations booléennes complexes (intersection, buffer) pour la décomposition L/T |
| viz/ | matplotlib, numpy |
Rendu PNG des implantations — optionnel en production |
| nsga2 | random (stdlib) |
Déterminisme via Random(seed) — pas de numpy.random |
Shoelace formula. Sert à estimer la capacité théorique et à valider les polygones.
Ray-casting. Vérifie que chaque emprise est bien à l'intérieur de la pièce.
Angle principal. Aligne les rangées sur le mur dominant.
Dégagement + nœud d'accès. Points d'ancrage pour M4.