COMPO · 24.01 · OBJECT ORIENTATION VS DIAGONAL

Orientation is relative.
Alignment is descriptive.

24.01 измеряет явную ориентацию объекта относительно конкретного diagonal axis candidate из 24.00. Он различает undirected object axis и directed vector, сохраняет точную угловую геометрию и не превращает aligned / counter-aligned / perpendicular / oblique в оценку качества.

ModuleCompo 24.01
Inputexplicit axis + object orientation
Angleexact descriptor
Tolerancenone
Metricsnone
NextSTOP

Compare object orientation to one explicit axis

24.01 consumes 24.00 candidate geometry. It does not select which diagonal is “main”.

00 / contract
24.00 DiagonalAxisCandidateSet + DiagonalCompositionSeed + explicit object-orientation request[] + owner-qualified object orientation evidence → ObjectOrientationEvidenceResolution[] → DiagonalObjectOrientationDescriptor[] → DiagonalObjectOrientationSet → ObjectOrientationAttachment NO main-axis selection NO mass distribution NO counter-diagonal / tension NO score / generator

What “orientation vs diagonal” means

Визуальные схемы отделяют геометрию объекта от интерпретации композиции.

01 / visual explainer

Undirected object axis

Для длинной формы направление оси часто не имеет “головы”. Разворот вектора на 180° остаётся той же object axis.

UNDIRECTED_AXIS: v and −v are equivalent
diagonal object axis

Directed orientation vector

Если owner явно говорит, что orientation directed, то совпадающее и противоположное направление различаются.

ALIGNEDCOUNTERDIRECTED_VECTOR: sign of dot product matters

Perpendicular is exact

dot(axis, object) === 0 — только тогда класс EXACT_PERPENDICULAR. “Почти 90°” остаётся OBLIQUE.

dot = 0No hidden ±5° / ±10° bucket

Oblique keeps the angle

Обlique — это наблюдаемое отношение. Сам по себе меньший angular deviation не означает “лучше”.

θangle descriptor ≠ quality score

One owner for orientation relation

24.01 owns only the relation between explicit object orientation and explicit 24.00 axis candidate.

02 / ownership
OWNS

Orientation evidence

Owner-qualified object orientation semantics, vector and exact evidence resolution.

OWNS

Relative descriptor

Exact dot/cross relation, angle descriptor, class and lineage.

DOES NOT OWN

Scene interpretation

Main/counter role, mass projection, tension, desirability, score and candidate generation remain downstream.

Orientation semantics must be explicit

Object axis and directed vector are not interchangeable.

03 / semantics
UNDIRECTED_AXIS

Line-like orientation

v and −v denote the same orientation. Counter-aligned collapses into EXACT_ALIGNED because the object has no directional head.

DIRECTED_VECTOR

Heading-like orientation

Direction sign is meaningful. Exact collinearity splits into EXACT_ALIGNED and EXACT_COUNTER_ALIGNED by the dot-product sign.

Firewall
24.01 never guesses whether an object is directed from shape, text reading direction, arrowheads, faces, motion cues or semantics. That declaration must come from the owning source.

Evidence resolves inside exact scope + frame

Contradictory orientation declarations remain N_A. Confidence cannot choose a winner.

04 / evidence
ObjectOrientationEvidence {
  scopeRef, snapshotRef,
  subjectRef,
  coordinateFrameRef,
  orientationSemantics: UNDIRECTED_AXIS | DIRECTED_VECTOR,
  direction: {dx,dy},
  sourceRef, sourceOwnerRef,
  confidence, provenance,
  status,
  mutationAllowed: false
}
Vectorfinite, non-zero
Semanticsexplicit, never inferred
ConflictN_A, no confidence winner
Framemust equal 24.00 candidate frame

Dot, cross and angular deviation

Numerics describe geometry; they do not vote on quality.

05 / exact math
cross = axis.dx * object.dy − axis.dy * object.dx dot = axis.dx * object.dx + axis.dy * object.dy DIRECTED_VECTOR: angleDeg = acos(clamp(dot / (|axis||object|), -1, 1)) · 180/π range = [0, 180] UNDIRECTED_AXIS: axisAngleDeviationDeg = acos(abs(clamp(cosine, -1, 1))) · 180/π range = [0, 90] NO tolerance bucket NO “near aligned” class NO score
CROSS = 0, DOT > 0Directed: EXACT_ALIGNED
CROSS = 0, DOT < 0Directed: EXACT_COUNTER_ALIGNED; undirected: EXACT_ALIGNED
DOT = 0EXACT_PERPENDICULAR
OTHERWISEOBLIQUE with exact numeric angle

Four relation classes, no desirability

Only DIRECTED_VECTOR can produce EXACT_COUNTER_ALIGNED.

06 / classes
ClassExact conditionSemanticsNot implied
EXACT_ALIGNEDcross=0 and compatible direction semanticssame line orientationgood, dominant, strong, main
EXACT_COUNTER_ALIGNEDDIRECTED_VECTOR + cross=0 + dot<0opposite heading on same linebad, conflict, counter-diagonal role
EXACT_PERPENDICULARdot=090° relationstable, tense, weak
OBLIQUEall other valid casesnumeric angle retainedmisaligned, error, penalty

Explicit bounded relation set

No object×axis Cartesian product is generated.

07 / set policy
1 · Request

Exact subjectRef + exact axisCandidateRef + orientationSemantics.

→
2 · Resolve

Exact object evidence in candidate frame. Conflict/missing stays N_A.

→
3 · Describe

dot/cross, cosine, angle, class and immutable lineage.

DiagonalObjectOrientationDescriptor {
  subjectRef,
  axisCandidateRef,
  axisRef,
  orientationSemantics,
  objectDirection,
  axisDirection,
  cross,
  dot,
  cosine,
  angleDeg,
  axisAngleDeviationDeg,
  relationClass,
  evidenceRefs[],
  massDistributionRef: null,
  tensionProfileRef: null,
  scoreRef: null,
  status,
  mutationAllowed: false
}

Immutable attachment to 24.00 seed

24.00 records stay unchanged.

08 / attachment
ObjectOrientationAttachment { diagonalCompositionSeedRef, objectOrientationSetRef, status, mutationAllowed: false } 24.00 DiagonalCompositionSeed remains unchanged.

Next owners remain separate

Orientation is one channel of diagonal composition, not the whole composition.

09 / next owners
ModuleOwns next24.01 explicitly does not do it
24.02Mass distribution along diagonalNo mass projection coordinate, density, side mass or centroid-along-axis.
24.03Counter-diagonal and tension profilesNo main/counter role assignment or controlled diagonal tension.
24.04Scoring, candidates and testsNo target fit, MetricResult, independent numeric vote or repair generator.
25.*Flow-template routesNo S/C/L/Z path matching or reading-route inference.

Alignment ≠ quality

These separations are normative and regression-tested.

10 / firewalls
Aligned ≠ main

An object may align to a candidate that never becomes the scene’s main diagonal.

Counter-aligned ≠ counter-diagonal

Opposite object heading on one axis is not the same as a second counter-axis.

Small angle ≠ better

Angular deviation is a descriptor. No hidden preference is introduced.

No score

24.01 owns zero MetricResult records and zero independent numeric votes.

object orientation != mass orientation object orientation != movement direction unless explicitly declared directed object alignment != hierarchy object alignment != dominance object alignment != tension angle 0 != quality 1 angle 90 != quality 0 N_A != 0 INVALID != 0

CANON → LAB → DATA → IDEAS

Perceptual thresholds and style preferences remain hypotheses until LAB/data supports them.

11 / mandatory hooks
IDEAS_REFS[]Perceived alignment thresholds, directional semantics.
DATA_CAPTURE[]Object vectors, semantics, exact angle descriptors.
DEFERRED_SEMANTIC_INPUTS[]Target alignment, style preference, main-axis choice.
HUMAN_FEEDBACK_HOOKS[]Correct semantics/vector/request pair.
CONFLICT_PRIORITY_ASSUMPTIONS[]Confidence is not a contradiction winner.
LAB_HOOKS[]Perceived near-alignment and diagonal tension studies.

24.01 regression suite

Tests cover exact 24.00 lineage, directed/undirected orientation semantics, evidence conflicts, dot/cross math, exact relation classes, angle ranges, explicit bounded request selection, immutable attachment and strict 24.02–24.04 / Topic25 firewalls.

12 / deterministic tests
Tests not run yet.

DATA FOR LAYOUT ENGINE

Machine-readable contract for integration and cross-module audit.

13 / machine contract
{
  "module": "Compo 24.01",
  "name": "object_orientation_vs_diagonal",
  "version": "1.0-canonical",
  "canonical_main_title": "Object orientation vs diagonal",
  "topic": "24_ДИАГОНАЛЬНАЯ_КОМПОЗИЦИЯ",
  "scope": "EXPLICIT_OBJECT_ORIENTATION_SEMANTICS_OWNER_QUALIFIED_DIRECTION_EVIDENCE_AND_EXACT_RELATION_TO_EXPLICIT_24_00_DIAGONAL_AXIS_CANDIDATES_ONLY_WITHOUT_MASS_DISTRIBUTION_COUNTER_DIAGONAL_TENSION_SCORING_OR_GENERATION",
  "main_topic_contract": {
    "topic_title": "Диагональная композиция",
    "topic_goal": "Описывает диагональную структуру всей сцены: main diagonal, counter-diagonal, проекции масс на ось и controlled diagonal tension.",
    "expected_output": "DiagonalCompositionDescriptor, main/counter axes, projection distribution",
    "planned_files": [
      "24.00 Diagonal axis candidates",
      "24.01 Object orientation vs diagonal",
      "24.02 Mass distribution along diagonal",
      "24.03 Counter-diagonal and tension profiles",
      "24.04 Scoring, candidates and tests"
    ]
  },
  "ownership": {
    "owner": "Compo24.01",
    "owns": [
      "ObjectOrientationSemantics taxonomy",
      "ObjectOrientationEvidence",
      "ObjectOrientationEvidenceResolution",
      "DiagonalObjectOrientationRequest",
      "DiagonalObjectOrientationRelationClass taxonomy",
      "DiagonalObjectOrientationDescriptor",
      "DiagonalObjectOrientationSetPolicy",
      "DiagonalObjectOrientationSet",
      "ObjectOrientationAttachment",
      "exact directed/undirected orientation equivalence rules",
      "dot/cross/cosine/angular-deviation descriptors relative to exact 24.00 axis candidate",
      "explicit-only bounded object-orientation relation selection",
      "identity/status/provenance rules for Topic24 object-orientation layer",
      "non-mutating correction request for object orientation evidence/request errors"
    ],
    "does_not_own": [
      "24.00 axis candidate identity or geometry — Compo24.00",
      "automatic object principal-axis extraction from shape/pixels — upstream geometry owner",
      "automatic directedness inference from arrowheads/faces/text/motion/semantics — foreign owner",
      "main diagonal or counter-diagonal role selection — Compo24.03/24.04 as explicitly modeled",
      "mass projection/distribution along diagonal — Compo24.02",
      "controlled diagonal tension profile — Compo24.03",
      "target profile, MetricResult, candidate generator or final scoring — Compo24.04",
      "flow-template diagonal path matching — Topic25",
      "dominance / hierarchy / beautyScore / final-layout ranking",
      "foreign geometry/style/semantic mutation"
    ]
  },
  "consumes": [
    "exact 24.00 DiagonalAxisCandidateSet and DiagonalCompositionSeed lineage",
    "explicit DiagonalObjectOrientationRequest[]",
    "owner-qualified ObjectOrientationEvidence[]",
    "exact shared scope/snapshot/coordinate-frame identity"
  ],
  "provides": [
    "ObjectOrientationEvidenceResolution[]",
    "DiagonalObjectOrientationDescriptor[]",
    "DiagonalObjectOrientationSet",
    "ObjectOrientationAttachment"
  ],
  "owns_metrics": [],
  "independent_numeric_votes": 0,
  "orientation_semantics": {
    "UNDIRECTED_AXIS": "v and -v are equivalent; exact opposite collinear orientation is EXACT_ALIGNED",
    "DIRECTED_VECTOR": "direction sign matters; exact opposite collinear orientation is EXACT_COUNTER_ALIGNED"
  },
  "relation_classes": ["EXACT_ALIGNED","EXACT_COUNTER_ALIGNED","EXACT_PERPENDICULAR","OBLIQUE"],
  "math": {
    "cross": "axis.dx*object.dy - axis.dy*object.dx",
    "dot": "axis.dx*object.dx + axis.dy*object.dy",
    "directedAngleRangeDeg": [0,180],
    "undirectedAxisDeviationRangeDeg": [0,90],
    "tolerance": null,
    "nearAlignedClass": null
  },
  "status_semantics": {
    "OK": "valid exact explicit lineage and relation geometry",
    "N_A": "missing/conflicting evidence or bounded-policy overflow; never numeric zero",
    "INVALID": "malformed/impossible record; never numeric zero"
  },
  "policy": {
    "selectionMode": "EXPLICIT_RELATION_REQUESTS_ONLY",
    "maxRelations": [1,4096],
    "overflow": "N_A_WITHOUT_TRUNCATION",
    "duplicateExactRequest": "N_A_NO_WINNER",
    "autoObjectOrientationExtraction": false,
    "autoDirectednessInference": false,
    "autoCartesianObjectAxisPairing": false,
    "autoMainAxisSelection": false,
    "autoScoring": false
  },
  "attachment_contract": {
    "diagonalCompositionSeedRef": "exact 24.00 seed identity",
    "objectOrientationSetRef": "exact",
    "mutationAllowed": false
  },
  "firewalls": [
    "object orientation != mass distribution",
    "object orientation != movement direction unless explicitly DIRECTED_VECTOR",
    "aligned != main diagonal",
    "counter-aligned object != counter-diagonal axis",
    "perpendicular != stable or unstable",
    "oblique != error",
    "smaller angular deviation != automatically better",
    "angle descriptor != score",
    "N_A != 0",
    "INVALID != 0",
    "local != global"
  ],
  "visual_explanation": {
    "diagrams": [
      "undirected object axis vs diagonal",
      "directed aligned and counter-aligned vectors",
      "exact perpendicular firewall",
      "oblique angle descriptor without quality inference"
    ]
  },
  "topic24ProgressAfterThisModule": "2/5 local",
  "next_module": "Compo 24.02 — Mass distribution along diagonal",
  "hard_stop": "No 24.02–24.04 implementation in this file"
}
VISITS / ...