// Point-to-segment projection primitives used by geometry hit testing.

///|
pub(all) struct SegmentProjection {
  point : Vec2
  parameter : Double
  distance_squared : Double
} derive(Eq, Debug)

///|
pub fn project_point_to_segment(
  point : Vec2,
  start : Vec2,
  end : Vec2,
) -> SegmentProjection {
  let direction = end.sub(start)
  let length_squared = direction.length_sq()
  if length_squared <= 0.000000000000000000000001 {
    { point: start, parameter: 0.0, distance_squared: point.distance_sq(start) }
  } else {
    let raw_parameter = point.sub(start).dot(direction) / length_squared
    let parameter = clamp_double(raw_parameter, 0.0, 1.0)
    let projected = start.add(direction.scale(parameter))
    {
      point: projected,
      parameter,
      distance_squared: point.distance_sq(projected),
    }
  }
}

///|
pub fn distance_squared_to_segment(
  point : Vec2,
  start : Vec2,
  end : Vec2,
) -> Double {
  project_point_to_segment(point, start, end).distance_squared
}