Polish movement hall interiors: clear doors and bay columns, tone floors and windows.

Document hang keep-outs and period-module fixes; leave columns fixed while packing frames into gaps.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Danila KhodjaefandCursor committed 2026-09-15 12:02:10 +03:00
1 parent 1b760faf0d
commit 13f6f088b6
25 files changed
+1147 -318

No files matched your search

+58
View File
@@ -0,0 +1,58 @@
import type { MovementDetailKind } from '../data/movement-interior-styles';
/**
* Even bay centres along the depth axis — same formula as historic `useBayZ`.
* Pure (no React) so hang layout can reserve the same Z as period columns.
*/
export function bayPositions(depth: number, halfD: number, spacing = 4.2, max = 9): number[] {
const count = Math.max(2, Math.min(max, Math.floor(depth / spacing)));
const step = depth / (count + 1);
return Array.from({ length: count }, (_, i) => -halfD + step * (i + 1));
}
export type SideColumnRhythm = {
/** Bay spacing passed to bayPositions (matches the period module). */
spacing: number;
max: number;
/**
* Half-width along the wall (Z) of the keep-out around each bay centre.
* Covers shaft/base/capital plus a small gap so frames do not kiss the column.
*/
halfClear: number;
};
/**
* Mid-wall vertical members that share the hang line on left/right walls.
* Corner-only orders are omitted — WALL_PADDING already clears the pockets.
*/
export const SIDE_WALL_COLUMN_RHYTHMS = {
gothic: { spacing: 4.2, max: 9, halfClear: 0.42 },
roman: { spacing: 4.0, max: 9, halfClear: 0.3 },
quattrocento: { spacing: 3.8, max: 9, halfClear: 0.34 },
// Paired pilasters sit at bay±0.19 with r≈0.11
cinquecento: { spacing: 5.2, max: 6, halfClear: 0.44 },
mannerist: { spacing: 4.8, max: 6, halfClear: 0.36 },
neoclassical: { spacing: 4.8, max: 6, halfClear: 0.3 },
'gothic-revival': { spacing: 3.8, max: 8, halfClear: 0.24 },
'art-nouveau': { spacing: 3.0, max: 10, halfClear: 0.22 },
} as const satisfies Partial<Record<MovementDetailKind, SideColumnRhythm>>;
export type SideColumnDetailKind = keyof typeof SIDE_WALL_COLUMN_RHYTHMS;
export function sideColumnRhythm(details: MovementDetailKind | undefined): SideColumnRhythm | null {
if (!details) return null;
return (SIDE_WALL_COLUMN_RHYTHMS as Partial<Record<MovementDetailKind, SideColumnRhythm>>)[details] ?? null;
}
/** Merged [z0, z1] intervals that side-wall paintings (and windows) must avoid. */
export function sideColumnKeepOutIntervals(
details: MovementDetailKind | undefined,
depth: number,
halfD: number
): [number, number][] {
const rhythm = sideColumnRhythm(details);
if (!rhythm) return [];
return bayPositions(depth, halfD, rhythm.spacing, rhythm.max).map(
(z) => [z - rhythm.halfClear, z + rhythm.halfClear] as [number, number]
);
}