> For the complete documentation index, see [llms.txt](https://docs.openbrim.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openbrim.org/developers/llm-guides/ai-bridge-alignment-guide.md).

# Bridge Alignment Guide

## Overview

Bridge alignments define the horizontal and vertical geometry of roadways and structures. In OpenBrIM, all 3D geometry and FEA models are positioned relative to alignments using station-based coordinates. This guide explains how to implement alignment-based positioning for bridge objects.

**Key Concepts:**

* **Alignment**: A 3D curve defined by horizontal geometry, vertical profile, and cross-slope (transverse)
* **Station**: Distance along the alignment centerline (longitudinal coordinate)
* **Offset**: Perpendicular distance from alignment centerline (transverse coordinate)
* **Elevation**: Vertical coordinate derived from vertical profile and superelevation
* **Alignment Modes**: How objects follow alignment geometry (Warp, Orient, Ignore)
* **Sub-Alignments**: Secondary alignments for edges, gridlines, and complex geometry

## Alignment Coordinate Systems

### 1. Global vs Alignment-Based Coordinates

**Global Coordinates (X, Y, Z):**

* Standard Cartesian coordinates
* Project-wide coordinate system
* Used for fixed geometry

**Alignment-Based Coordinates (Station, Offset, Elevation):**

* **Station (X)**: Distance along alignment centerline
* **Offset (Y)**: Perpendicular distance from centerline (positive typically = left)
* **Elevation (Z)**: Height relative to alignment vertical profile

### 2. Alignment Components

**Horizontal Alignment:**

* Tangents, curves, spirals
* Defines plan view geometry
* Accessed via `alignH()`, `alignHX()`, `alignHY()`, `alignHA()` functions

**Vertical Alignment:**

* Grades, vertical curves (parabolic)
* Defines profile elevation
* Accessed via `alignV()` function

**Transverse/Superelevation:**

* Cross-slope rotation of roadway
* Banking in curves
* Accessed via `alignT()`, `alignTA()` functions

***

## Alignment Modes

### 1. AlignH - Horizontal Alignment Mode

Controls how objects follow the horizontal alignment curvature.

**Values:**

* `AlignH="Warp"` - Follow alignment curvature (default for most bridge objects)
* `AlignH="Orient"` - Orient tangent to alignment but don't warp
* `AlignH="Ignore"` - Ignore horizontal alignment (straight in global coordinates)
* `AlignH="0"` (Right), `AlignH="1"` (Center), `AlignH="2"` (Left) - Alignment rule for girders

**Example - Deck Following Alignment:**

```xml
<O N="ConcreteDeck" T="Line"
   Alignment="deck_alignment"
   AlignH="Warp"
   AlignV="Warp"
   AlignT="Warp">
  <P N="Section" V="DeckSection" T="Section"/>
  <O T="Point" X="0" Y="0" Z="0"/>      <!-- Start station -->
  <O T="Point" X="1200" Y="0" Z="0"/>   <!-- End station -->
</O>
```

**Warp vs Orient:**

* **Warp**: Cross-section follows alignment curvature (curves with road)
* **Orient**: Cross-section rotates to be tangent but remains planar

### 2. AlignV - Vertical Alignment Mode

Controls how objects follow the vertical profile.

**Values:**

* `AlignV="Warp"` - Follow vertical profile elevation changes
* `AlignV="Ignore"` - Ignore vertical profile

**Example:**

```xml
<O N="Girder" T="Line" Alignment="deck_alignment" AlignV="Warp">
  <!-- Girder follows vertical grades and curves -->
</O>
```

### 3. AlignT - Transverse/Superelevation Mode

Controls how objects follow cross-slope rotation.

**Values:**

* `AlignT="Warp"` - Follow superelevation rotation
* `AlignT="Ignore"` - No superelevation rotation
* `AlignT="mid_grd_algnT"` - Custom transverse mode from parameter

**Example - Deck Section with Selective Transverse:**

```xml
<O N="DeckSection" T="Section">
  <O T="Shape" AlignH="Orient" AlignY="0">
    <!-- Top of deck - no transverse rotation -->
    <O T="Point" X="staDepLeftY3d" Y="0" AlignTB="No"/>

    <!-- Bottom of overhang - follow transverse rotation -->
    <O T="Point" X="staDepLeftY3d" Y="-sd_oh_left" AlignT="Warp" AlignTB="No"/>
  </O>
</O>
```

### 4. AlignTB - Transverse Banking

Controls transverse rotation behavior for individual points.

**Values:**

* `AlignTB="No"` or `AlignTB="0"` - Do not apply transverse banking to this point
* `AlignTB="Yes"` or `AlignTB="2"` - Apply transverse banking (default)

***

## Primary Alignment Reference

### Specifying the Alignment

Use the `Alignment` attribute to reference the alignment object:

```xml
<O N="DeckObject" T="Line" Alignment="deck_alignment">
  <!-- Object positioned relative to deck_alignment -->
</O>
```

**Parameter Definition:**

```xml
<P N="deck_alignment" V="bridge.centerlineAlignment" T="Alignment"/>
```

### Station-Based Geometry

Points are defined using station (X coordinate):

```xml
<O T="Line" Alignment="deck_alignment" AlignH="Warp" AlignV="Warp" AlignT="Warp">
  <O T="Point" X="100*12" Y="0" Z="0"/>   <!-- Station 100 ft (1200 in) -->
  <O T="Point" X="200*12" Y="0" Z="0"/>   <!-- Station 200 ft (2400 in) -->
</O>
```

**Key Points:**

* X = Station along alignment
* Y = Offset from centerline (+ = left, - = right typically)
* Z = Elevation offset from alignment vertical profile

***

## Sub-Alignments

Sub-alignments allow objects to follow secondary alignment paths (deck edges, girder paths, etc.).

### 1. SubAlignment Attribute

**Syntax:**

```xml
<O T="Point" X="0" Y="0"
   Alignment="deck_alignment"
   SubAlignment="left_edge_alignment"/>
```

**Use Cases:**

* Deck edge geometry following independent edge paths
* Girder paths that may vary from deck centerline
* Utility conduits with custom routing

### 2. Deck Edge Sub-Alignments

**Pattern:**

```xml
<P N="left_edge_alignment" V="..." T="Alignment" Role="Input"/>
<P N="right_edge_alignment" V="..." T="Alignment" Role="Input"/>

<O N="DeckSection" T="Section">
  <O T="Shape">
    <!-- Left edge points follow left edge alignment -->
    <O T="Point" X="-barrierWidth" Y="0"
       Alignment="deck_alignment"
       SubAlignment="left_edge_alignment"/>

    <!-- Right edge points follow right edge alignment -->
    <O T="Point" X="barrierWidth" Y="0"
       Alignment="deck_alignment"
       SubAlignment="right_edge_alignment"/>
  </O>
</O>
```

**When Using Sub-Alignments:**

* Primary `Alignment` provides base coordinate system
* `SubAlignment` provides local path to follow
* X coordinate on sub-alignment is relative to sub-alignment's station
* Useful for variable-width structures with independent edge geometries

### 3. Girder Path Sub-Alignments

**Pattern:**

```xml
<P N="gpath" V="grd.girder_path" T="Alignment"/>

<O T="Point" Y="GTz" X="lftH"
   SubAlignment="gpath"
   AlignH="g_a_rule"
   AlignmentLine="ref_no_elev"
   AlignmentLineX="algnXs"
   AlignT="mid_grd_algnT"
   AlignTB="mid_grd_algnTB"/>
```

**Purpose:**

* Deck section points follow girder paths for haunches
* Each girder can have unique horizontal geometry
* Creates variable deck thickness over girders

***

## Alignment Functions

### 1. Horizontal Alignment Functions

#### `alignH(alignment, station, offset)`

Returns all horizontal alignment data at once.

**Returns:** Object - `{X, Y, Angle}`

**Example:**

```xml
<P N="HData" V="alignH(deck_alignment, 600, 0)"/>
<P N="GlobalX" V="HData.X"/>
<P N="GlobalY" V="HData.Y"/>
<P N="Bearing" V="HData.Angle"/>
```

***

#### `alignHX(alignment, station, offset)`

Returns global X coordinate.

**Example:**

```xml
<P N="PierX" V="alignHX(deck_alignment, 100*12, 0)"/>
```

***

#### `alignHY(alignment, station, offset)`

Returns global Y coordinate.

**Example:**

```xml
<P N="PierY" V="alignHY(deck_alignment, 100*12, 0)"/>
```

***

#### `alignHZ(alignment, station, offset)`

Returns global Z coordinate (horizontal plane only, NOT vertical profile).

**Note:** Use `alignV()` for vertical profile elevation.

***

#### `alignHA(alignment, station, offset)`

Returns horizontal angle (bearing) at station.

**Example:**

```xml
<P N="BearingAngle" V="alignHA(deck_alignment, 600, 0)"/>
```

***

### 2. Vertical Alignment Functions

#### `alignV(alignment, station)`

Returns vertical profile elevation at station.

**Example:**

```xml
<P N="ProfileElev" V="alignV(deck_alignment, 100*12)"/>
```

***

### 3. Transverse/Superelevation Functions

#### `alignT(alignment, station, offset, mode?)`

Returns transverse elevation (superelevation) at station and offset.

**Parameters:**

* `alignment` (Alignment): The alignment object
* `station` (Number): Station value
* `offset` (Number): Transverse offset from centerline
* `mode` (Number, optional): Calculation mode

**Returns:** Number - Transverse elevation

**Example:**

```xml
<!-- Elevation difference between two offsets -->
<P N="alignTDifLeft" V="-alignT(deck_alignment, coord_x_left, staDepLeftY3d - leftTopChamfer)
                          + alignT(deck_alignment, coord_x_left, staDepLeftY3d - barrierWidth, 0)"/>
```

**Use Cases:**

* Computing deck cross-slope
* Variable deck thickness due to superelevation
* Barrier/rail positioning

***

#### `alignTA(alignment, station, offset)`

Returns transverse slope angle.

**Returns:** Number - Slope angle in radians

***

### 4. Coordinate Conversion Functions

#### `alignLocal(alignment, x, y, z)`

Converts global coordinates to local alignment coordinates.

**Returns:** Object - `{Station, Offset}`

**Example:**

```xml
<P N="LocalCoords" V="alignLocal(deck_alignment, 1000, 500, 0)"/>
<P N="Station" V="LocalCoords.Station"/>
<P N="Offset" V="LocalCoords.Offset"/>
```

***

## Station-Dependent Parameters

### 1. Station-Dependent Values

Parameters can vary along alignment station using the station-dependent format or `makestadep()` function.

**Array Format:**

```xml
<P N="Depth" V="[[0, 1200], 60, [1200, 2400], 72, [2400, 3600], 60]"/>
<!-- Station 0-1200: 60", Station 1200-2400: 72", Station 2400-3600: 60" -->
```

**makestadep Function:**

```xml
<P N="gstas" V="[0, 1200, 2400, 3600]"/>
<P N="off_list" V="[[10, 12], [12, 15], [15, 12], [12, 10]]"/>
<P N="variation" V="['linear', 'linear', 'linear']"/>
<P N="off_sd" V="makestadep(gstas, off_list, variation)"/>
```

***

### 2. Using atstation() with Alignment Values

Evaluate station-dependent parameters at specific locations:

```xml
<P N="DepthAtMidspan" V="atstation(600, Depth)"/>
```

***

## Alignment Lines for Sections

### 1. AlignmentLine and AlignmentLineX

For sections with multiple points following different paths, use alignment lines to map points to their respective paths.

**Syntax:**

```xml
<O T="Point" X="lftH" Y="GTz"
   AlignmentLine="ref_no_elev"
   AlignmentLineX="algnXs"/>
```

**Where:**

* `AlignmentLine`: Array of path coordinates defining the line to follow
* `AlignmentLineX`: Array of stations where alignment line is defined

**Example - Girder Haunch Points:**

```xml
<P N="ref_no_elev" V="map(grd.sPts, [x[0], x[1], 0])"/>  <!-- Girder path points -->
<P N="algnXs" V="map(grd.supports, x.gs_loc.s_sta)"/>     <!-- Support stations -->

<O T="Point" Y="GTz" X="lftH"
   SubAlignment="gpath"
   AlignH="g_a_rule"
   AlignmentLine="ref_no_elev"
   AlignmentLineX="algnXs"/>
```

**Purpose:**

* Section points follow girder paths instead of deck centerline
* Creates haunches, variable thickness over supports
* Each point can follow independent alignment path

***

### 2. Grid Lines and GridsYAlignH

For FEA meshing with multiple gridlines following different alignments.

**Syntax:**

```xml
<O T="FEMeshSurface"
   Alignment="deck_alignment"
   GridLinesY="gridlines"
   GridsYAlignH="gridalignlist">
```

**Where:**

* `GridLinesY`: Array of gridline paths (typically girder centerlines)
* `GridsYAlignH`: Array of alignment rules for each gridline (0=Right, 1=Center, 2=Left)

**Example:**

```xml
<P N="gridlines" V="concat([leftGridline], grd_lines_all_mod, [rightGridline])"/>
<P N="gridalignlist" V="concat([2], map(grd_lines_all, 1), [0])"/>
<!-- Left edge = 2 (Left), Girders = 1 (Center), Right edge = 0 (Right) -->

<O T="FEMeshSurface"
   Alignment="deck_alignment"
   GridLinesY="gridlines"
   GridsYAlignH="gridalignlist"
   AlignH="Warp"
   AlignV="Warp"
   AlignT="Warp">
</O>
```

***

## Skew and Rotation

### 1. Skew Angles

Apply skew angles at start and end of objects using `StartSkewX` and `EndSkewX`.

**Syntax:**

```xml
<O T="Line"
   Alignment="deck_alignment"
   StartSkewX="s_st_skew"
   EndSkewX="s_end_skew"
   SkewOnFacesOnly="1">
```

**Example - Computing Skew from Support Lines:**

```xml
<P N="s_st_sta" V="100*12"/>
<P N="s_end_sta" V="200*12"/>

<!-- Extract skew angles from support line data -->
<P N="s_st_skew" V="onlinex(sup_line_skews, s_st_sta)[1]"/>
<P N="s_end_skew" V="onlinex(sup_line_skews, s_end_sta)[1]"/>

<O N="ConcreteDeck" T="Line"
   Alignment="deck_alignment"
   StartSkewX="s_st_skew"
   EndSkewX="s_end_skew"
   SkewOnFacesOnly="1">
  <O T="Point" X="s_st_sta" Y="0" Z="0"/>
  <O T="Point" X="s_end_sta" Y="0" Z="0"/>
</O>
```

**SkewOnFacesOnly:**

* `SkewOnFacesOnly="1"`: Apply skew only to end faces (most common for bridges)
* `SkewOnFacesOnly="0"`: Skew entire object geometry

***

### 2. Skew Compensation in Section Points

When skew is applied, section points may need coordinate adjustments:

```xml
<P N="x_left_st" V="(staDepLeftY3d - leftTopChamfer) * tan(s_st_skew)"/>
<P N="x_left_end" V="(staDepLeftY3d - leftTopChamfer) * tan(s_end_skew)"/>

<!-- Station-dependent X coordinate accounting for skew -->
<P N="coord_x_left" V="[[s_st_sta, s_end_sta],
                        variation('linear', s_st_sta + x_left_st, s_end_sta + x_left_end)]"/>
```

***

## Complete Deck Alignment Example

### Deck Object with Full Alignment Implementation

```xml
<O N="OBPBase_GirderDeck" T="Project">
  <!-- Alignment references -->
  <P N="deck_alignment" V="bridge.centerlineAlignment" T="Alignment"/>
  <P N="left_edge_alignment" V="NULL" T="Alignment" Role="Input"/>
  <P N="right_edge_alignment" V="NULL" T="Alignment" Role="Input"/>

  <!-- Deck geometry parameters -->
  <P N="sd_thickness" V="8"/>
  <P N="sd_oh_left" V="36"/>
  <P N="sd_oh_right" V="36"/>

  <!-- Station extents -->
  <P N="s_st_sta" V="0"/>
  <P N="s_end_sta" V="1200"/>

  <!-- Skew angles -->
  <P N="s_st_skew" V="0"/>  <!-- radians -->
  <P N="s_end_skew" V="0.1"/>  <!-- 5.7 degrees -->

  <!-- 3D Deck Volume -->
  <O N="ConcreteDeck" T="Line"
     Alignment="deck_alignment"
     AlignH="Warp"
     AlignV="Warp"
     AlignT="Warp"
     StartSkewX="s_st_skew"
     EndSkewX="s_end_skew"
     SkewOnFacesOnly="1"
     SegmentsAlong="30">

    <P N="Section" V="DeckSection" T="Section"/>

    <O T="Point" X="s_st_sta" Y="0" Z="0"/>
    <O T="Point" X="s_end_sta" Y="0" Z="0"/>
  </O>

  <!-- Deck Section Definition -->
  <O N="DeckSection" T="Section" Is3DOnly="1">
    <O T="Shape" AlignH="Orient" AlignY="0">

      <!-- Left edge - follow left_edge_alignment if provided -->
      <O T="Point" X="-leftTopChamfer" Y="0"
         Guard="left_edge_alignment != NULL"
         Alignment="deck_alignment"
         SubAlignment="left_edge_alignment"/>

      <O T="Point" X="0" Y="-leftTopChamfer"
         AlignTB="No"
         Guard="left_edge_alignment != NULL"
         Alignment="deck_alignment"
         SubAlignment="left_edge_alignment"/>

      <O T="Point" X="0" Y="-sd_oh_left"
         AlignT="Warp"
         AlignTB="No"
         Guard="left_edge_alignment != NULL"
         Alignment="deck_alignment"
         SubAlignment="left_edge_alignment"/>

      <!-- Left edge - default (no sub-alignment) -->
      <O T="Point" X="staDepLeftY3d-leftTopChamfer" Y="0"
         Guard="left_edge_alignment == NULL"/>

      <O T="Point" X="staDepLeftY3d" Y="-leftTopChamfer"
         AlignTB="No"
         Guard="left_edge_alignment == NULL"/>

      <O T="Point" X="staDepLeftY3d" Y="-sd_oh_left"
         AlignT="Warp"
         AlignTB="No"
         Guard="left_edge_alignment == NULL"/>

      <!-- Girder haunch points (repeat for each girder) -->
      <O N="LREP" T="Repeat" S="0" E="length(girders_at_span)-1" I="1" CTRL="index" index="0">
        <P N="grd" V="girders_at_span[index]"/>
        <P N="gpath" V="grd.girder_path"/>
        <P N="ref_no_elev" V="map(grd.sPts, [x[0], x[1], 0])"/>
        <P N="algnXs" V="map(grd.supports, x.gs_loc.s_sta)"/>
        <P N="GTz" V="-sd_thickness + grd.top_off_3d + at_sd"/>
        <P N="lftH" V="off_sd + grd.tf_w * 0.5"/>

        <O T="Point" Y="GTz" X="lftH"
           SubAlignment="gpath"
           AlignH="g_a_rule"
           AlignmentLine="ref_no_elev"
           AlignmentLineX="algnXs"
           AlignT="Ignore"
           AlignTB="0"/>
      </O>

      <!-- Right edge - similar to left edge -->
      <O T="Point" X="0" Y="-sd_oh_right"
         AlignT="Warp"
         AlignTB="No"
         Guard="right_edge_alignment != NULL"
         Alignment="deck_alignment"
         SubAlignment="right_edge_alignment"/>
    </O>
  </O>
</O>
```

***

## FEA Mesh Alignment Implementation

### FEMeshSurface with Multiple Gridlines

```xml
<O N="DECK" T="FEMeshSurface"
   Alignment="deck_alignment"
   AlignH="Warp"
   AlignV="Warp"
   AlignT="Warp"
   GridLinesY="gridlines"
   GridsYAlignH="gridalignlist"
   SubAlignments="all_sub_algn"
   AlignmentLine="mesh_align_lines"
   AlignmentLineX="mesh_align_lines_x"
   MeshDirection="[[0,0,0], [1,0,0], [1,1,0]]"
   CX="longMeshSize"
   CY="120"
   Thickness="sd_thickness"
   Material="@d_mat|Material">

  <!-- Mesh boundary surface -->
  <O T="Surface"
     EndNodeTx="tx_stadep"
     EndNodeTy="ty_stadep"
     EndNodeTz="tz_stadep"
     EndNodeRx="rx_stadep"
     EndNodeRy="ry_stadep"
     EndNodeRz="rz_stadep">

    <O T="Repeat" S="0" E="length(meshboundary_)-1" I="1" CTRL="index" index="0">
      <O T="Point"
         X="meshboundary_[index][0]"
         Y="meshboundary_[index][1]"
         Z="meshboundary_[index][2]"/>
    </O>
  </O>

  <!-- Mesh regions with thickness overrides -->
  <O T="FEMeshRegion"
     Node1OffZ="lOffZ"
     Node2OffZ="lOffZ"
     Node3OffZ="lOffZ"
     Node4OffZ="lOffZ"
     Thickness="sd_oh_left">
    <!-- Left overhang region -->
  </O>

  <O T="FEMeshRegion"
     Node1OffZ="rOffZ"
     Node2OffZ="rOffZ"
     Node3OffZ="rOffZ"
     Node4OffZ="rOffZ"
     Thickness="sd_oh_right">
    <!-- Right overhang region -->
  </O>
</O>
```

**Key FEA Alignment Parameters:**

* `GridLinesY`: Array of gridline paths (girder centerlines, deck edges)
* `GridsYAlignH`: Alignment rule for each gridline (0/1/2)
* `SubAlignments`: Array of sub-alignment objects for gridlines
* `AlignmentLine`/`AlignmentLineX`: Station-dependent alignment path
* `MeshDirection`: Orientation of mesh quad elements

***

## Best Practices

### 1. Alignment Reference Organization

**Organize alignment parameters in a dedicated group:**

```xml
<O N="AlignmentRefs" T="Group">
  <P N="deck_alignment" V="bridge.centerlineAlignment" T="Alignment"/>
  <P N="left_edge_alignment" V="NULL" T="Alignment" Role="Input"/>
  <P N="right_edge_alignment" V="NULL" T="Alignment" Role="Input"/>
</O>
```

***

### 2. Station Extent Calculations

**Always compute station extents from span data:**

```xml
<P N="s_st_sta" V="iif(sp[0] == d_css[0][0],
                       d_css[0][0].s_sta + d_css[0][1],
                       sp[0].s_sta) - iif(si == 0, cantLengStart, 0)"/>

<P N="s_end_sta" V="iif(sp[1] == last(d_css)[0],
                        last(d_css)[0].s_sta + last(d_css)[1],
                        sp[1].s_sta) + iif(si == length(spans)-1, cantLengEnd, 0)"/>
```

***

### 3. Conditional Sub-Alignments

**Use guards to switch between centerline and edge alignments:**

```xml
<!-- With sub-alignment -->
<O T="Point" X="0" Y="-sd_oh_left"
   Guard="left_edge_alignment != NULL"
   Alignment="deck_alignment"
   SubAlignment="left_edge_alignment"
   AlignT="Warp"
   AlignTB="No"/>

<!-- Without sub-alignment -->
<O T="Point" X="staDepLeftY3d" Y="-sd_oh_left"
   Guard="left_edge_alignment == NULL"
   AlignT="Warp"
   AlignTB="No"/>
```

***

### 4. Station-Dependent Paths

**Use makestadep for girder paths with varying offsets:**

```xml
<P N="gstas" V="map(grd.supports, x.gs_loc.s_sta)"/>
<P N="offsets" V="map(ref_corr_forstadep, x[1])"/>
<P N="off_list" V="filter(map(offsets, [offsets[xi-1], x]), xi > 0)"/>
<P N="variation" V="map(off_list, 'linear')"/>
<P N="off_sd" V="makestadep(gstas, off_list, variation)"/>
```

***

### 5. Transverse Elevation Differences

**Compute relative transverse elevations for variable thickness:**

```xml
<P N="alignTDifLeft" V="-alignT(deck_alignment, coord_x_left, staDepLeftY3d-leftTopChamfer)
                        + alignT(deck_alignment, coord_x_left, staDepLeftY3d-barrierWidth, 0)"/>

<O T="Point" X="staDepLeftY3d-barrierWidth" Y="additionalTh+alignTDifLeft"/>
```

***

### 6. Mesh Alignment Lines

**Provide alignment lines for complex mesh geometry:**

```xml
<P N="mesh_align_lines" V="concat([leftGridline], girder_paths, [rightGridline])"/>
<P N="mesh_align_lines_x" V="concat([left_stations], girder_stations, [right_stations])"/>

<O T="FEMeshSurface"
   AlignmentLine="mesh_align_lines"
   AlignmentLineX="mesh_align_lines_x">
</O>
```

***

## Common Pitfalls

### 1. Missing Alignment Mode Specifications

**Problem:** Not specifying AlignH/AlignV/AlignT

```xml
<!-- Wrong - no alignment modes -->
<O T="Line" Alignment="deck_alignment">
```

**Solution:** Always specify alignment modes explicitly

```xml
<!-- Correct -->
<O T="Line" Alignment="deck_alignment" AlignH="Warp" AlignV="Warp" AlignT="Warp">
```

***

### 2. Incorrect AlignTB Usage

**Problem:** Forgetting AlignTB="No" for points that shouldn't rotate

```xml
<!-- Wrong - top of deck will rotate with superelevation -->
<O T="Point" X="0" Y="0"/>
```

**Solution:** Explicitly disable transverse banking where needed

```xml
<!-- Correct - top of deck stays level -->
<O T="Point" X="0" Y="0" AlignTB="No"/>
```

***

### 3. Sub-Alignment Without Primary Alignment

**Problem:** Using SubAlignment without Alignment

```xml
<!-- Wrong - no primary alignment -->
<O T="Point" X="0" Y="0" SubAlignment="left_edge_alignment"/>
```

**Solution:** Always specify both

```xml
<!-- Correct -->
<O T="Point" X="0" Y="0"
   Alignment="deck_alignment"
   SubAlignment="left_edge_alignment"/>
```

***

### 4. Station vs Global Coordinates Confusion

**Problem:** Using global coordinates when alignment is specified

```xml
<!-- Wrong - X should be station, not global coordinate -->
<O T="Line" Alignment="deck_alignment">
  <O T="Point" X="1000000" Y="500000" Z="100"/>
</O>
```

**Solution:** Use station-based coordinates

```xml
<!-- Correct - X is station along alignment -->
<O T="Line" Alignment="deck_alignment">
  <O T="Point" X="1200" Y="0" Z="0"/>  <!-- Station 1200 inches -->
</O>
```

***

### 5. Skew Angle Units

**Problem:** Using degrees instead of radians

```xml
<!-- Wrong - skew angles in degrees -->
<P N="s_st_skew" V="30"/>  <!-- 30 degrees? -->
```

**Solution:** Convert to radians

```xml
<!-- Correct - skew in radians -->
<P N="s_st_skew" V="30 * PI / 180"/>  <!-- 30 degrees = 0.524 radians -->
```

***

## Summary

Bridge alignment implementation in OpenBrIM uses station-based positioning to create complex 3D geometry and FEA models:

**Core Concepts:**

* **Alignment Modes**: AlignH, AlignV, AlignT control how objects follow alignment geometry
* **Station Coordinates**: X = station, Y = offset, Z = elevation offset
* **Sub-Alignments**: Secondary paths for edges, girders, and complex geometry
* **Alignment Functions**: alignH(), alignV(), alignT() for coordinate transformation

**Key Patterns:**

* Primary alignment reference with `Alignment="deck_alignment"`
* Alignment modes: `AlignH="Warp"`, `AlignV="Warp"`, `AlignT="Warp"`
* Sub-alignments for deck edges: `SubAlignment="left_edge_alignment"`
* Girder path following: `AlignmentLine`, `AlignmentLineX`, `SubAlignment`
* Skew angles: `StartSkewX`, `EndSkewX`, `SkewOnFacesOnly`
* Transverse banking control: `AlignTB="No"` for level surfaces

**FEA Mesh Alignment:**

* `GridLinesY` and `GridsYAlignH` for multi-path meshing
* `SubAlignments` array for gridline alignments
* `AlignmentLine`/`AlignmentLineX` for station-dependent paths
* Thickness and offset overrides with `FEMeshRegion`

**Best Practices:**

* Always specify alignment modes explicitly
* Use guards for conditional sub-alignments
* Compute station extents from span data
* Use `makestadep()` for station-dependent geometry
* Specify `AlignTB="No"` for non-rotating surfaces
* Convert skew angles to radians

By following these patterns, AI agents can create accurate bridge geometry that follows roadway alignments through horizontal curves, vertical grades, and superelevation transitions.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.openbrim.org/developers/llm-guides/ai-bridge-alignment-guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
