Clusters, anchors and constraints
Three ways to say that placements are related to each other rather than independent, which is what most real scenes actually are.
Cluster rules#
Sample a set of cluster centres, then place a local population around each.
cluster count how many groups
actors per cluster how large each is
cluster radius how tight
zone where centres may fall
minimum spacing within the cluster
asset pool what fills it
placement distribution how members spread around the centre
Useful for pedestrian groups, pallet stacks, vehicles in a lot, props around a work area. The finalised output preserves cluster provenance, so an instance can be traced back to the group it belonged to.
Relative and anchor placement#
Place one class relative to another:
worker 2–5 m from truck
The semantic boundary that matters:
Relative anchors are eligible actors already present in the captured scene under the adopted anchor contract. Do not assume a dependent rule can anchor to an object that another rule has not materialised yet. A missing required anchor fails rather than silently placing at the world origin, which would put your workers at the map centre and look like a physics bug.
Anchor selectors may target explicit actors or tags where supported.
Inter-class distance constraints#
Use these when the relationship between two populations is part of the dataset design rather than decoration:
people at least 1 m from forklifts
cones 0.5–2 m from vehicles
workers within a region around equipment
Each rule keeps a from-class, a to-class, a minimum distance and an optional maximum.
The maximum is the interesting half. A minimum keeps objects apart; a maximum is how you say "this only counts as a near-miss if they are actually near", which is how you generate the specific case a safety model needs to learn.
Nested groups#
Structured multi-object units, with recursion:
Convoy
├── LeadVehicle
├── EscortGroup
│ ├── EscortA
│ └── EscortB
└── ConeRing
Recursive validation is bounded, and the adopted limits come from the code and its tests rather than being hidden. Group provenance stays visible in the output and metadata, so an instance knows which unit it was part of.