struct

  type t = point option array

  let empty n = Array.create n None

  let iter f =
    Array.iter
      (function
         | None -> ()
         | Some x -> f x)

  
  (** Utilities, that only apply to non-None elements. *)


  let fold f =
    Array.fold_left
      (fun v -> function
         | None -> v
         | Some x -> f v x) 

  let map f =
    Array.map
      (function
         | None -> None
         | Some x -> Some (f x))

  
  (** Higher level utilities. *)


  let length c =
    let l = ref 0. in
    let norm (x,y,z) = sqrt (x*.x +. y*.y +. z*.z) in
      iter (fun x -> l := !l +. (norm x)) c ;
      sqrt !l

  let add c d =
    assert (Array.length c = Array.length d) ;
    let a = Array.make (Array.length c) None in
      for i = 1 to (Array.length c)-1 do
        match c.(i), d.(i) with
          | None, _
          | _, None -> assert false
          | (Some (x,y,z)), (Some (m,n,o)) ->
              a.(i) <- Some (x+.m, y+.n, z+.o)
      done ;
      a

  let sub c d =
    assert (Array.length c = Array.length d) ;
    let a = Array.make (Array.length c) None in
      for i = 1 to (Array.length c)-1 do
        match c.(i), d.(i) with
          | None, _
          | _, None -> assert false
          | (Some (x,y,z)), (Some (m,n,o)) ->
              a.(i) <- Some (x-.m, y-.n, z-.o)
      done ;
      a

end