COMPO 1.05 / Point rhythm / Sequence generator

Ритм и
последовательности

Модуль превращает набор точек в управляемую последовательность: задаёт интервалы, ускорение, замедление, размерный ритм, направление, фазу, повтор и контролируемую вариативность. Это уже не кластер, а траектория чтения.

Назначение

00 / scope

Что такое последовательность

Последовательность — упорядоченный набор точек P0...Pn, для которого важен порядок. Алгоритм должен знать, какая точка первая, какая следующая и как меняются расстояния, размеры и направление.

  • создать путь взгляда;
  • соединить две массы;
  • построить «хвост»;
  • обозначить ускорение или затухание;
  • сделать технический маркер движения;
  • сформировать повторяемый модуль.

Главное отличие от кластера

Кластер оценивается как группа. Последовательность — как функция по индексу i.

cluster: unordered {P} sequence: ordered [P0,P1,...,Pn] sequence properties: spacing(i) size(i) path_tangent(i) contrast(i) phase(i)

Математическая модель

01 / model
N
count

Количество точек.

dᵢ
gap

Расстояние между соседями.

rᵢ
radius

Размер точки по индексу.

κ
curvature

Кривизна траектории.

Given ordered points Pi = (xi, yi), i = 0..N-1 gap_i = distance(Pi, P(i+1)) - (ri + r(i+1)) normalized_gap_i = gap_i / min(W,H) gap_ratio_i = gap_(i+1) / max(gap_i, ε) size_ratio_i = r_(i+1) / max(r_i, ε) Direction vector: v_i = normalize(P(i+1) - Pi) Turn angle: θ_i = acos( clamp(dot(v_(i-1), v_i), -1, 1) ) Rhythm consistency: CV_gap = std(gap_i) / max(mean(gap_i), ε) Important: CV_gap ≈ 0 → mechanical uniform rhythm moderate CV → controlled variation high CV → broken rhythm / possible cluster

Типы ритма

02 / rhythm modes
ModeФункция интервалаЭффектКогда использовать
uniformd(i)=d0стабильность / механикасетка, интерфейс, технический паттерн
acceleratingd(i+1)<d(i)сгущение к целиподвести взгляд к доминанте
deceleratingd(i+1)>d(i)рассыпание / затуханиехвост, распад, уход в пустоту
progressived(i)=d0·q^iчёткая экспоненциальная динамикакороткие последовательности 4–9 точек
alternatingdA,dB,dA,dB...пульсациядекоративный ритм
groupedмалые gaps внутри / большие между группамифразы и паузысложный ритм, 8+ точек
controlled_randombase + bounded noiseживость без хаосаeditorial / experimental poster
Важно: равномерный ритм не считается плохим автоматически. Он плох только тогда, когда текущая роль требует живого или направленного движения.

Интервалы

03 / spacing profile

Нормализованный профиль

S = min(W,H) base_gap = 0.012..0.060 × S For i=0..N-2: gap_i = base_gap × rhythm_multiplier(i) Suggested multipliers: uniform: 1 accelerating: lerp(1.60, 0.55, t) decelerating: lerp(0.55, 1.60, t) progressive: q^i, q ≈ 0.72..0.90 or 1.12..1.38 alternating: [0.75,1.35] random: 1 + noise[-0.22,+0.22]

Касание — внешняя проверка

Compo 1.05 может породить интервалы, которые приводят к касанию, но не владеет метрикой tangency. Геометрический конфликт проверяет Compo 1.09.

surface_gap = center_distance - (r1+r2) // DERIVED geometry conflict = consume(Compo1.09.conflict_result) if conflict.hardReject: reject candidate elif conflict.repairRequested: regenerate gaps / radii // NO tangent penalty is added here

Размерный ритм

04 / size rhythm

Рост

r_i = lerp(r_min, r_max, ease(t)) r_max / r_min ≈ 1.8..4.5

Локально задаёт нарастающий size-profile. Влияние на маршрут взгляда оценивается внешним eye-flow модулем.

Затухание

r_i = r0 · q^i q ≈ 0.72..0.92

Локальный decay-profile. Смысловое направление к/от доминанты передаётся как DEFERRED context.

Пульсация

r_i = r0 × [1, 1.35, .9, 1.25...]

Использовать умеренно: слишком сильная пульсация разрушает путь.

Размерный ритм не должен автоматически дублировать интервальный. Если и расстояние, и размер одновременно меняются слишком сильно, sequence становится чрезмерно «объяснённой» и механической.

Траектория

05 / path geometry

Linear

Минимальная неоднозначность. Хорошо для направления.

Curved

Более органичный маршрут. Требует контроля поворотов.

Broken / L

Работает как маршрут по сетке или между блоками.

Path constraints: mean_turn_angle <= 35° for smooth directional rhythm single strong turn <= 95° if composition uses L/Z structure avoid repeated micro-zigzags: if sign(turn_i) changes > 3 times per 6 points and role != technical_noise: add instability_penalty

Контролируемая вариативность

06 / bounded randomness

Рандом не выбирает структуру

Сначала задаётся тип ритма. Рандом только слегка искажает его.

ideal_gap_i = rhythm(i) noise_i = random(-1,1) noise_i = lowpass(noise_i) actual_gap_i = ideal_gap_i × (1 + noise_i × jitter) jitter: 0.00..0.06 = technical / strict 0.06..0.14 = calm editorial 0.14..0.22 = expressive > 0.22 = risky; validate heavily

Seed и воспроизводимость

Каждый вариант должен сохранять seed. Один и тот же набор входных данных + seed обязан давать один и тот же ритм.

sequence_seed = hash(composition_seed, object_id, "Compo1.05") RNG = seeded_random(sequence_seed)

Context interactions

07 / deferred context
Архитектурное правило: Compo 1.05 не вычисляет плотность поля, negative space, hierarchy, balance, typography collision или eye-flow. Он может только потреблять эти сигналы от их owner-модулей и на их основе генерировать новый локальный candidate.
DEFERRED signalЛокальная реакция-кандидатСтатус
local_density_highпредложить меньше N или увеличить gapsproposal only
target_focus_anchorпредложить monotonic gap/radius profile к anchorproposal only
typography_protected_zoneснизить jitter или reroute pathhard/soft по upstream policy
negative_space_pressureпредложить сокращение sequence или sparse profileDEFERRED_INPUT
grid_route_candidateпересэмплировать sequence по предоставленному grid routeconsume only
global_eye_flow_targetпредложить orientation/path variant, не оценивать глобальный eye-flowDEFERRED_INPUT
context does NOT mutate final layout directly context owner metric → Compo 1.05 receives signal → generate/re-generate local rhythm candidate → local rhythm metrics recomputed → candidate returned to global solver → global solver accepts / rejects / requests another pass

Rule priority / overrides

08 / ownership boundary

Compo 1.05 ВЛАДЕЕТ

  • порядком точек в sequence;
  • gap profile;
  • локальной interval variation;
  • monotonicity выбранного профиля;
  • bounded jitter;
  • локальной trajectory consistency;
  • rhythm.local_score.

НЕ ВЛАДЕЕТ

DEFERRED / EXTERNAL OWNERS: negative_space grid_global_fit dominance hierarchy global_balance global_eye_flow typography_readability point_collision / tangency global_scoring Rule: external metrics may cause REGENERATION, but are never redefined inside Compo 1.05.

Scoring

09 / owned local metrics only

Собственные метрики

profile_match = 1 - normalized_error(actualGapProfile, targetGapProfile) interval_variation = CV(gap_i) monotonicity = monotonic_transition_ratio(gap_i, target_direction) trajectory_consistency = 1 - normalized_turn_variance size_profile_match = 1 - normalized_error(actualRadiusProfile, targetRadiusProfile) rhythm_local_score = w_profile * profile_match + w_mono * monotonicity + w_turn * trajectory_consistency + w_size * size_profile_match - w_over * overregularity_penalty - w_chaos * local_chaos_penalty // all weights = STYLE_PRESET / ENGINE_DEFAULT // score contains NO global hierarchy/balance/negative-space metrics

Внешние проверки

Collision, tangency, protected zones и глобальные композиционные свойства не штрафуются повторно здесь.

external_validation = { collision_result: consume(Compo1.09), grid_result: consume(Compo1.06), hierarchy: DEFERRED_INPUT, negative_space: DEFERRED_INPUT, balance: DEFERRED_INPUT, eye_flow: DEFERRED_INPUT } if external HARD violation: reject candidate else: keep rhythm_local_score unchanged pass all external metrics separately to global solver
Anti-double-counting: если tangency уже дал штраф/REJECT в Compo 1.09, Compo 1.05 не добавляет второй tangent_penalty.

Примеры

10 / visual examples

GOOD — нарастание

Размер и направление ведут к финальной точке; интервалы растут умеренно.

NEUTRAL — метроном

Хорошо для технической системы, слабее для выразительной композиции.

GOOD — сгущение к доминанте

Sequence сам уменьшается, а конечная доминанта принимает внимание.

BAD — хаотичный зигзаг

Нет устойчивой траектории, размеры спорят, последовательность превращается в набор событий.

Интерактивная лаборатория

11 / live lab
Лаборатория иллюстрирует локальный Compo 1.05. Глобальный solver позже имеет право изменить параметры.

Алгоритм

12 / deterministic local pipeline
1. INPUT
Нормализовать role, N, anchors, path candidate, seed.
2. PROFILE
Выбрать gap/radius profile из role + preset.
3. GENERATE
Создать K bounded variants.
4. SAMPLE
Разместить ordered points на path.
5. LOCAL METRICS
Profile / monotonicity / turn consistency.
6. EXTERNAL VALIDATE
Consume collision/grid/protected-zone results.
7. REPAIR
При необходимости regenerate candidate.
8. PROVIDE
Вернуть candidates global solver.
function proposePointRhythm(input, external, preset): role = input.role path = input.pathCandidate seed = hash(input.sceneSeed, input.objectId, "Compo1.05") targetGap = buildGapProfile(role, input.N, preset) targetSize = buildRadiusProfile(role, input.N, preset) candidates = [] for variantIndex in 0..K-1: rng = seededRng(seed, variantIndex) gaps = boundedVariation(targetGap, preset.gapJitter, rng) radii = boundedVariation(targetSize, preset.sizeJitter, rng) points = sampleOrderedPoints(path, gaps, radii) local = computeOwnedRhythmMetrics(points, targetGap, targetSize) externalResult = consumeExternalValidation(points, external) if externalResult.hardReject: continue candidates.push({ points, gapProfile:gaps, radiusProfile:radii, localMetrics:local, externalMetrics:externalResult.metrics, seed, variantIndex }) return candidates // NO argmax here; global solver decides

Тест-кейсы

13 / deterministic + integration
T01
Uniform technical
N=6, mode=uniform, jitter=0.04. Ожидается profile_match ≥ 0.90 и CV_gap ≤ 0.08. Статус порогов: INITIAL_HEURISTIC.
T02
Monotonic decay
N=7, target gap profile increasing. Ожидается monotonicity ≥ 5/6 переходов.
T03
Seed reproducibility
Одинаковые input + sceneSeed + variantIndex обязаны давать идентичные gaps, radii и coordinates.
T04
Anti-zigzag local
Если sign(turnAngle) меняется более 3 раз на N=8, trajectory_consistency должен уменьшиться; конкретный penalty задаётся preset.
T05
External collision integration
Compo 1.09 возвращает hardReject=true. Ожидается: candidate удаляется без дополнительного collision penalty в Compo 1.05.
T06
No global metric leakage
При одинаковом локальном sequence изменение global.balance_score не должно менять rhythm.local_score; оно влияет только на global solver.

DATA FOR LAYOUT ENGINE

14 / canonical contract
{ "module": "Compo 1.05", "version": "1.1", "name": "point_sequence_rhythm", "finality": "LOCAL_PROPOSAL_ONLY", "consumes": [ "Compo0.Scene.seed", "Compo0.StylePreset", "Point[]", "PathCandidate", "Compo1.06.grid_result?", "Compo1.09.conflict_result?", "ProtectedZones?", "global.* as DEFERRED_INPUT only" ], "provides": [ "RhythmCandidate[]", "RhythmCandidate.points[]", "RhythmCandidate.gapProfile[]", "RhythmCandidate.radiusProfile[]", "RhythmCandidate.seed", "RhythmCandidate.localMetrics" ], "owns_metrics": [ "rhythm.profile_match", "rhythm.interval_variation", "rhythm.monotonicity", "rhythm.trajectory_consistency", "rhythm.size_profile_match", "rhythm.local_score" ], "does_not_own": [ "point_collision", "point_tangency", "grid_global_fit", "global.negative_space_score", "global.hierarchy_score", "global.balance_score", "global.eye_flow_score", "typography.readability_score" ], "deferred_inputs": [ "global.negative_space_score", "global.hierarchy_score", "global.balance_score", "global.eye_flow_score" ], "numeric_status": { "gap_ranges": "INITIAL_HEURISTIC", "jitter_ranges": "STYLE_PRESET", "score_weights": "STYLE_PRESET_OR_ENGINE_DEFAULT", "distance_and_CV_formulas": "DERIVED" }, "rules": [ "local score contains only owned metrics", "external hard conflict rejects candidate without duplicate penalty", "same input + seed + variantIndex is reproducible", "module returns candidates; global solver selects winner", "external context triggers regeneration, not hidden metric redefinition" ] }

Чек-лист

15 / final check
  • У sequence есть роль и направление.
  • Точки упорядочены, а не просто лежат рядом.
  • Gap profile соответствует выбранному mode.
  • Нет случайных касаний.
  • Нет лишних микро-зигзагов.
  • Размерный ритм не спорит с интервальным.
  • Jitter ограничен и воспроизводим seed.
  • Endpoint связан с реальным объектом или смысловой зоной.
  • Ритм не забивает типографику.
  • Global solver может переопределить локальные решения.

Core contract

COMPO 0.00 / API

SCOPE

Compo 1.05 генерирует и оценивает локальную ритмическую структуру упорядоченной последовательности точек. Он не решает глобальный баланс, иерархию, negative space или eye-flow.

FINALITY

LOCAL_PROPOSAL_ONLY The module MAY: generate measure locally score request regeneration The module MUST NOT: finalize composition redefine external metrics select global winner

METRIC OWNERSHIP

OWNER: rhythm.profile_match rhythm.interval_variation rhythm.monotonicity rhythm.trajectory_consistency rhythm.size_profile_match rhythm.local_score

DEFERRED POLICY

if owner_available(externalMetric): consume(externalMetric) else: omit(externalMetric) NEVER create surrogate formula locally. NEVER fold deferred metric into rhythm.local_score.
Anti-double-counting: collision/tangency принадлежат Compo 1.09; grid relation — Compo 1.06; глобальные композиционные метрики — соответствующим глобальным модулям. Compo 1.05 не дублирует их штрафы.