# `BB.IK.TestHelpers.Chain`
[🔗](https://github.com/beam-bots/bb_ik_fabrik/blob/main/test/support/chain_helpers.ex#L5)

Test helpers for creating chain point tensors.

These helpers make it easier to reason about test data by providing
semantic functions for common chain configurations.

# `bent_chain`

```elixir
@spec bent_chain(keyword()) :: Nx.Tensor.t()
```

Generate points for a chain with bends at each joint.

Each joint bends in the XY plane (around Z axis) by the specified angle.
Angles are cumulative - each segment's direction is the previous direction
plus the bend angle.

## Options

- `:lengths` - list of segment lengths (required)
- `:angles` - list of bend angles in radians, one per segment (required)
              First angle is absolute direction from origin,
              subsequent angles are relative bends.
- `:start` - starting point (default: `{0, 0, 0}`)

## Example

    # Straight arm then 90° elbow bend
    iex> bent_chain(lengths: [0.3, 0.2], angles: [0.0, :math.pi/2])
    # Points at: {0,0,0}, {0.3,0,0}, {0.3,0.2,0}

# `collapsed`

```elixir
@spec collapsed(non_neg_integer(), {number(), number(), number()}) :: Nx.Tensor.t()
```

Generate points that are all at the same location (degenerate case).

Useful for testing edge cases where direction vectors have zero length.

# `elbow_bend`

```elixir
@spec elbow_bend(keyword()) :: Nx.Tensor.t()
```

Generate a chain that's straight for the first segment, then bends.

Convenience function for the common case of testing elbow-like joints.

## Options

- `:lengths` - list of segment lengths (required)
- `:bend_at` - index of joint where bend occurs (0-indexed, default: 1)
- `:bend_angle` - angle of bend in radians (required)

## Example

    iex> elbow_bend(lengths: [0.3, 0.2], bend_angle: :math.pi/2)
    # Straight along X, then bent 90° at elbow

# `points`

```elixir
@spec points([{number(), number(), number()}]) :: Nx.Tensor.t()
```

Convert a list of {x, y, z} tuples to an Nx tensor.

## Example

    iex> points([{0, 0, 0}, {1, 0, 0}, {2, 0, 0}])
    #Nx.Tensor<f64[3][3]>

# `rotate`

```elixir
@spec rotate(Nx.Tensor.t(), number(), :x | :y | :z) :: Nx.Tensor.t()
```

Rotate all points around an axis passing through the origin.

## Parameters

- `points` - Nx tensor of shape {n, 3}
- `angle` - rotation angle in radians
- `axis` - `:x`, `:y`, or `:z`

## Example

    iex> straight_chain(lengths: [1.0]) |> rotate(:math.pi/2, :z)
    # Rotates from +X to +Y direction

# `straight_chain`

```elixir
@spec straight_chain(keyword()) :: Nx.Tensor.t()
```

Generate points for a straight chain along the +X axis starting at origin.

## Options

- `:lengths` - list of segment lengths (required)
- `:start` - starting point (default: `{0, 0, 0}`)

## Example

    iex> straight_chain(lengths: [0.3, 0.2])
    # Points at: {0,0,0}, {0.3,0,0}, {0.5,0,0}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
