An OrientedPoint can be used as a virtual anchor to establish a local coordinate system for placing other objects. This is useful when you want to place objects relative to a specific heading or orientation.
When placing objects relative to an OrientedPoint, you can use specifiers like left of, right of, ahead of, or behind combined with a facing specifier to define their orientation relative to the anchor's heading.
Example of creating a bottleneck using an OrientedPoint:
bottleneck = new OrientedPoint at ego offset by Range(-1.5, 1.5) @ Range(0.5, 1.5), facing Range(-30, 30) deg
# Define edges relative to the bottleneck's heading
gap = 1.2 * ego.width
halfGap = gap / 2
leftEdge = new OrientedPoint left of bottleneck by halfGap, \
facing Range(60, 120) deg relative to bottleneck.heading
rightEdge = new OrientedPoint right of bottleneck by halfGap, \
facing Range(-120, -60) deg relative to bottleneck.heading
# Place pipes relative to those edges
new Pipe ahead of leftEdge, with length Range(1, 2), on ground, facing leftEdge, with parentOrientation 0
new Pipe ahead of rightEdge, with length Range(1, 2), on ground, facing rightEdge, with parentOrientation 0
bottleneck = new OrientedPoint at ego offset by Range(-1.5, 1.5) @ Range(0.5, 1.5), facing Range(-30, 30) deg
gap = 1.2 * ego.width
halfGap = gap / 2
leftEdge = new OrientedPoint left of bottleneck by halfGap, \
facing Range(60, 120) deg relative to bottleneck.heading
rightEdge = new OrientedPoint right of bottleneck by halfGap, \
facing Range(-120, -60) deg relative to bottleneck.heading
new Pipe ahead of leftEdge, with length Range(1, 2), on ground, facing leftEdge, with parentOrientation 0
new Pipe ahead of rightEdge, with length Range(1, 2), on ground, facing rightEdge, with parentOrientation 0