
Build parallel spot lines around a central segment
Source:R/R-trajectory.R
build_similar_trajectories.RdConstructs a central line of spots near the segment defined by endpoints `A` and `B`, then builds additional parallel lines on the left, right, or both sides by translating the segment along its left unit normal. After each line is built, its spots are removed from the remaining pool to avoid reuse.
Usage
build_similar_trajectories(
df,
A,
B,
top_n = 19,
n_extra = 2,
side = c("left", "right", "both"),
lane_width_factor = 1.15,
max_dist = NULL
)Arguments
- df
A data frame of candidate spots containing at least columns `x` and `y`. Additional columns are preserved.
- A
A data frame with columns `x` and `y` defining endpoint A of the central segment. If it contains multiple rows, only the first row is used.
- B
A data frame with columns `x` and `y` defining endpoint B of the central segment. If it contains multiple rows, only the first row is used.
- top_n
Integer; number of closest spots to keep per line (default `19`). If `NULL`, no top-N truncation is applied in the underlying selection.
- n_extra
Integer; number of additional lines to build on each requested side (default `2`). For example, `n_extra = 2` with `side = "both"` yields 1 center line + 2 left + 2 right.
- side
Character; which side(s) to build relative to the vector \(A \rightarrow B\). One of `"left"`, `"right"`, or `"both"`.
- lane_width_factor
Numeric scalar; multiplier applied to the estimated spot spacing to obtain the inter-line offset (default `1.15`).
- max_dist
Numeric; if not `NULL`, only spots with distance to each (translated) segment `<= max_dist` are considered when building each line.
Value
A data frame containing all selected spots from all lines, stacked together, with additional columns `trajectory_id` (e.g., `"main"`, `"left_1"`, `"right_1"`) and `offset` (signed offset used for that line).
Details
The inter-line distance is computed as: $$w = lane\_width\_factor \cdot spacing$$ where `spacing` is the median nearest-neighbor distance estimated from `df`.
Lines are generated by shifting both endpoints `A` and `B` by `offset * n`, where `n` is the left unit normal of \(A \rightarrow B\). Positive offsets correspond to the left side; negative offsets correspond to the right side.
This function relies on helpers such as `estimate_spot_spacing()`, `unit_normal_left()`, `shift_point()`, `build_one_line()`, and `remove_used_points()`.
The implementation uses the base R pipe `|>` and `dplyr::mutate()` / `dplyr::bind_rows()`. Ensure `dplyr` is installed.
Examples
df <- data.frame(
x = rep(1:10, each = 3),
y = rep(1:3, times = 10),
id = seq_len(30)
)
A <- data.frame(x = 1, y = 2)
B <- data.frame(x = 10, y = 2)
out <- build_similar_trajectories(df, A, B, top_n = 5, n_extra = 1, side =
"both")
head(out)
#> x y id dist_to_seg pos_on_seg trajectory_id offset
#> 1 1 2 2 0.00 0.0000000 main 0.00
#> 2 2 2 5 0.00 0.1111111 main 0.00
#> 3 3 2 8 0.00 0.2222222 main 0.00
#> 4 4 2 11 0.00 0.3333333 main 0.00
#> 5 5 2 14 0.00 0.4444444 main 0.00
#> 6 1 3 3 0.15 0.0000000 left_1 1.15
unique(out$trajectory_id)
#> [1] "main" "left_1" "right_1"