///|
/// Interpolate camera poses with endpoint clamping.
pub fn interpolate_camera_pose_clamped(
  a : CameraPose,
  b : CameraPose,
  amount : Double,
) -> CameraPose {
  CameraPose::interpolate(a, b, amount.max(0.0).min(1.0))
}

///|
pub fn sample_camera_poses(
  poses : ArrayView[CameraPose],
  count : Int,
) -> Array[CameraPose] {
  let result : Array[CameraPose] = []
  if poses.length() == 0 || count <= 0 {
    return result
  }
  if poses.length() == 1 {
    for _ in 0.. CameraPose {
  if poses.length() == 0 {
    return CameraPose::identity()
  }
  if poses.length() == 1 {
    return poses[0]
  }
  let position = amount.max(0.0).min(1.0) * (poses.length() - 1).to_double()
  let lower = position.floor().to_int().min(poses.length() - 1)
  let upper = position.ceil().to_int().min(poses.length() - 1)
  if lower == upper {
    poses[lower]
  } else {
    CameraPose::interpolate(
      poses[lower],
      poses[upper],
      position - lower.to_double(),
    )
  }
}

///|
pub fn pose_translation_distance(a : CameraPose, b : CameraPose) -> Double {
  a.camera_center().minus(b.camera_center()).norm()
}

///|
pub fn pose_path_distances(poses : ArrayView[CameraPose]) -> Array[Double] {
  let result : Array[Double] = []
  if poses.length() < 2 {
    return result
  }
  for i in 0..<(poses.length() - 1) {
    result.push(pose_translation_distance(poses[i], poses[i + 1]))
  }
  result
}

///|
pub fn pose_path_length2(poses : ArrayView[CameraPose]) -> Double {
  let mut result = 0.0
  for distance in pose_path_distances(poses) {
    result += distance
  }
  result
}

///|
pub fn pose_speed_estimates(
  poses : ArrayView[CameraPose],
  timestamps : ArrayView[Double],
) -> Array[Double] {
  let result : Array[Double] = []
  let distances = pose_path_distances(poses)
  let count = distances.length().min((timestamps.length() - 1).max(0))
  for i in 0.. Bool {
  for distance in pose_path_distances(poses) {
    if distance > tolerance {
      return false
    }
  }
  true
}

///|
pub fn pose_subsequence(
  poses : ArrayView[CameraPose],
  start : Int,
  end : Int,
) -> Array[CameraPose] {
  let result : Array[CameraPose] = []
  let lower = start.max(0).min(poses.length())
  let upper = end.max(lower).min(poses.length())
  for i in lower.. Array[CameraPose] {
  let result : Array[CameraPose] = []
  for i in 0.. Array[CameraPose] {
  let result : Array[CameraPose] = []
  for _ in 0..