Commits

bergsoe committed 14dfa7b

Better support for zero-length trajectories.

  • Participants
  • Parent commits 22f2299

Comments (0)

Files changed (2)

File src/PaplTrajectory.ml

 
 type range_t = float * float
 
+let sprintf = Printf.sprintf
+
+let fmt_range traj = sprintf "range = (%f, %f)" traj.t0 traj.t1
+
 let range_is_empty (t0, t1) = t1 < t0
 
 let range_is_within (t0, t1) (t0', t1') = t0' <= t0 && t1 <= t1'
     traj.get t
   else
     invalid_arg
-      (Printf.sprintf
-         "PaplTrajectory.get: t out of range. (t = %f, range = (%f, %f))"
-         t traj.t0 traj.t1)
+      (sprintf
+         "PaplTrajectory.get: t out of range. (t = %f, %s)"
+         t (fmt_range traj))
 
 let t0 traj = traj.t0
 
 let shift_t1_to traj t1_new = shift traj (t1_new -. traj.t1)
 
 let scale { t0; t1; get } s =
-  if s <= 0. then
-    invalid_arg
-      ("PaplTrajectory.scale: s <= 0. " ^
-         "(s = " ^ (string_of_float s) ^ ")")
+  if s < 0.
+  then invalid_arg
+    (sprintf "PaplTrajectory.scale: s < 0. (s = %f)" s)
+  else if s = 0.
+  then make_fixed (t0, t0) (get t1)
   else make
     (t0, t0 +. (t1 -. t0) *. s)
     (fun t -> get ((t -. t0) /. s +. t0))
 
 let scale_to traj d =
   let d' = duration traj in
-    if d' <= 0. then invalid_arg "PaplTrajectory.scale_to: duration <= 0"
+    if d' < 0. then invalid_arg
+      (sprintf "PaplTrajectory.scale_to: duration < 0 (%s)" (fmt_range traj))
     else
-      scale traj (d /. d')
+      if d' = 0.
+      then let t0 = t0 traj in make_fixed (t0, t0 +. d) (x1 traj)
+      else scale traj (d /. d')
 
 let of_interpolate (t0, t1) ip =
   if t1 < t0 then invalid_arg "PaplTrajectory.of_interpolate: t1 < t0";
     invalid_arg "PaplTrajectory.repeat: trajectory is empty."
   else
     let len = duration traj in
-      if len = 0. then
-        invalid_arg "PaplTrajectory.repeat: trajectory has duration zero."
+    let t0 = traj.t0 in
+    let range = (t0, infinity) in
+      if len = 0. then make_fixed range (x1 traj)
       else
-        let t0 = traj.t0 in
-        let get t =
-          get traj (t0 +. mod_float (t -. t0) len)
-        in
-          make (t0, infinity) get
+        let get t = get traj (t0 +. mod_float (t -. t0) len) in
+          make range get
 
 let repeat_n n traj =
   let t0 = traj.t0 in

File src/PaplTrajectory.mli

 
     The starting time of the new trajectory is unchanged.
 
-    [s] must be greater than zero.
+    [s] must be greater than or equal to [0.].
+
+    If [s = 0.] then a fixed trajectory containing the last element of
+    [trajectory] is returned.
 *)
 
 val scale_to : 'a t -> float -> 'a t
     [scale_to trajectory d] is equivalent to [scale trajectory (d /. duration
     trajectory)].
 
-    The duration of [trajectory] must be greater than [0.0].
+    The duration of [trajectory] must be greater than or equal to [0.].
+
+    If the duration of [trajectory] is [0.] then a fixed trajectory containing
+    the last element of [trajectory] is returned.
 *)
 
 val place : 'a t -> 'a t -> 'a t
     The trajectory wraps around to the start such that [get traj' (t1 traj)]
     becomes equal to [x0 traj].
 
-    [traj] must have a duration greater than zero or an exception is thrown.
+    [traj] must have a duration greater than or equal to [0.] or an exception is
+    thrown.
+
+    If the duration of [traj] is [0.] then then a fixed trajectory containing
+    the last element of [traj] is returned.
 *)
 
 val repeat_n : int -> 'a t -> 'a t