# Oblique & Skewed Joints

*Oblique tenons between splayed legs and skewed crossing members*

**Names:** `cross_lap` `tilt` `heading`

## When to use

- A diagonal member between two legs: a hayrake or splayed stretcher, a raked brace. Tenon
  each end into the leg face at the member's own slope.
- Two members crossing at an angle in one plane (the X of a hayrake, a St Andrew's cross):
  halve them into each other with a `cross_lap`.
- A compound mitre at the corner of a splayed or canted frame, when both boards are mirror
  images across the mitre plane.

Not covered: a skewed `bridle` (unsupported), crossings shallower than 15° (error), and a
coped shoulder to a curved surface (the shoulder is flat on the tangent plane, standing off
the curve; ADR-0027).

## Syntax

- **Oblique tenon:** an ordinary `mortise_and_tenon`. The male mark is on the member's end
  face; the member is placed with `rot y=` at its slope. The tenon runs along the member
  as placed, may meet the female face up to **45° off square**, and the shoulder is
  scribed flush to that face.
- **Skewed crossing:** an ordinary `cross_lap` (or `half_lap`). Marks sit on the shared
  cheek and face each other. Each member is notched to the parallelogram the other casts on
  the cheek. Keep `depth_ratio` agreeing with the mark depth.
- **Compound mitre:** an ordinary `miter`; `angle` is checked as for a plain mitre.
- **`tilt=` / `heading=`** on a `mark` orient a mark that is on no stock face (a turned
  surface's tangent). A mark on a stock face needs neither.

## Example

```kdl
project name="Hayrake" units=mm schema_version=1 {
    materials { material Oak type=hardwood }

    component LegLeft {
        stock Oak 34.0 34.0 230.0
        mark RailHigh x=34.0 y=17.0 z=-40.0 normal=pos_x
        mark RailLow  x=34.0 y=17.0 z=-190.0 normal=pos_x
    }
    component LegRight {
        stock Oak 34.0 34.0 230.0
        mark RailHigh x=0.0 y=17.0 z=-40.0 normal=neg_x
        mark RailLow  x=0.0 y=17.0 z=-190.0 normal=neg_x
    }
    component Brace {
        stock Oak 250.0 19.0 30.0
        mark Lap x=125.0 y=9.5 z=-15.0 normal=pos_y
        mark TenonStart x=0.0 y=9.5 z=-15.0 normal=neg_x
        mark TenonEnd x=250.0 y=9.5 z=-15.0 normal=pos_x
    }
    component BraceBack {
        stock Oak 250.0 19.0 30.0
        mark Lap x=125.0 y=9.5 z=-15.0 normal=neg_y
        mark TenonStart x=0.0 y=9.5 z=-15.0 normal=neg_x
        mark TenonEnd x=250.0 y=9.5 z=-15.0 normal=pos_x
    }
    joinery cross_lap name=Lap {}
    joinery mortise_and_tenon name=RailTenon {
        tenon_thickness 8.0
        tenon_width 20.0
        tenon_length 20.0
        clearance 0.0
        centering axis=z
    }

    assembly Frame {
        part LegL instance=LegLeft {
            by top_center
            pos x=17.0 y=17.0 z=0.0
        }
        part LegR instance=LegRight {
            by top_center
            pos x=251.0 y=17.0 z=0.0
        }
        part Lower instance=Brace {
            by center
            pos x=134.0 y=17.0 z=-115.0
            rot y=36.8699
        }
        part Upper instance=BraceBack {
            by center
            pos x=134.0 y=17.0 z=-115.0
            rot y=-36.8699
        }
        join joint=RailTenon male=Lower@TenonStart female=LegL@RailHigh
        join joint=RailTenon male=Lower@TenonEnd female=LegR@RailLow
        join joint=RailTenon male=Upper@TenonStart female=LegL@RailLow
        join joint=RailTenon male=Upper@TenonEnd female=LegR@RailHigh
        join joint=Lap male=Lower@Lap female=Upper@Lap
    }
}
```

The inside faces of the legs are 200 apart and the tenon marks 150 apart in height, so each
brace is exactly 250 on its centre line and leans 36.8699° (a 3-4-5 run). Compiled: five
joins synthesised, no clashes (`docs/styles/models/hayrake-stretcher.kdl` is the same
model).

## Pitfalls and diagnostics

- **`faces-overlap`, "shallower than the 15°":** the members cross at less than 15°. Move
  them apart, or make the slope steeper.
- **`unsupported` on a `bridle`:** a skewed bridle is not laid out; use a `cross_lap` or
  `half_lap`.
- **`corner`, "a compound mitre, and the boards are not mirror images":** the two boards'
  sections on the mitre plane differ by the stated mm. Give both the same section and lean.
- **Shoulder gap on a round leg:** a tenon into a turned surface has a flat shoulder on the
  tangent plane, so it stands off the curve. Put the tenon on a flat (the square pommel).
- The tenon must lie within 45° of square to the female face, and `centering axis=` checks
  that the mark is centred on the member.
- Both lap members' marks must lie on the cheek and face each other, or the join is
  rejected (`facing` / `contact`).

## See also

- `docs/rfc/0142-oblique-tenon-between-legs.md`, `docs/rfc/0144-skewed-crossing-joint.md`,
  `docs/adr/0027-oblique-and-skewed-joints.md`, RFC-0022 (oriented marks).
- `docs/KDL_AUTHORING.md` §7 (tenons, laps, bridles and mitres) and the `mark` section.
- `crates/ww-build/tests/oblique_skewed.rs` for the measured geometry.

## Names

Every name this page declares, how the example library uses it, and the shortest real use.

### `cross_lap`

joinery kind; value in 3 of 116 examples (3 uses).

Shortest real use, from `mid_century_slat_bench.kdl`:

```kdl
joinery cross_lap name=SlatLap {
    depth_ratio 0.25
    clearance glue_clearance
}
```

### `tilt`

property; property in 2 of 116 examples (6 uses).

Shortest real use, from `primary_grid_lath_armchair.kdl`:

```kdl
mark Seat x=0.0 y="lath / 2.0" z="0.0 - dm" normal=neg_x tilt=0.01 heading=0.0
```

### `heading`

property; property in 2 of 116 examples (6 uses).

Shortest real use, from `primary_grid_lath_armchair.kdl`:

```kdl
mark Seat x=0.0 y="lath / 2.0" z="0.0 - dm" normal=neg_x tilt=0.01 heading=0.0
```

## Related terms

- [Cross-lap joint](/almanac/techniques#cross-lap-joint)
- [Half-lap joint](/almanac/techniques#half-lap-joint)
