% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/R-trajectory.R
\name{build_similar_trajectories}
\alias{build_similar_trajectories}
\title{Build parallel spot lines around a central segment}
\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{
\item{df}{A data frame of candidate spots containing at least columns `x` and
`y`. Additional columns are preserved.}

\item{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.}

\item{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.}

\item{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.}

\item{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.}

\item{side}{Character; which side(s) to build relative to the vector
\eqn{A \rightarrow B}. One of `"left"`, `"right"`, or `"both"`.}

\item{lane_width_factor}{Numeric scalar; multiplier applied to the estimated
spot spacing to obtain the inter-line offset (default `1.15`).}

\item{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).
}
\description{
Constructs 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.
}
\details{
The inter-line distance is computed as:
\deqn{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 \eqn{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)
unique(out$trajectory_id)

}
