1010#include " KinKal/General/MomBasis.hh"
1111#include " KinKal/General/TimeRange.hh"
1212#include < deque>
13+ #include < array>
1314#include < memory>
1415#include < ostream>
1516#include < stdexcept>
@@ -20,6 +21,8 @@ namespace KinKal {
2021 public:
2122 using KTRAJPTR = std::shared_ptr<KTRAJ>;
2223 using DKTRAJ = std::deque<KTRAJPTR>;
24+ using DKTRAJITER = DKTRAJ::iterator;
25+ using DKTRAJCITER = DKTRAJ::const_iterator;
2326 // forward calls to the pieces
2427 VEC3 position3 (double time) const { return nearestPiece (time).position3 (time); }
2528 VEC3 velocity (double time) const { return nearestPiece (time).velocity (time); }
@@ -55,6 +58,8 @@ namespace KinKal {
5558 KTRAJ& back () { return *pieces_.back (); }
5659 KTRAJPTR const & frontPtr () const { return pieces_.front (); }
5760 KTRAJPTR const & backPtr () const { return pieces_.back (); }
61+ void pieceRange (TimeRange const & range, DKTRAJCITER& first, DKTRAJCITER& last ) const ;
62+ void pieceRange (TimeRange const & range,DKTRAJITER& first, DKTRAJITER& last );
5863 size_t nearestIndex (double time) const ;
5964 DKTRAJ const & pieces () const { return pieces_; }
6065 // test for spatial gaps
@@ -68,13 +73,17 @@ namespace KinKal {
6873 template <class KTRAJ > void PiecewiseTrajectory<KTRAJ>::setRange(TimeRange const & trange, bool trim) {
6974 // trim pieces as necessary
7075 if (trim){
71- while (pieces_.size () > 1 && trange.begin () > pieces_.front ()->range ().end () ) pieces_.pop_front ();
72- while (pieces_.size () > 1 && trange.end () < pieces_.back ()->range ().begin () ) pieces_.pop_back ();
76+ auto ipiece = pieces_.begin ();
77+ while (ipiece != pieces_.end () && !(trange.overlaps ((*ipiece)->range ())))++ipiece;
78+ if (ipiece != pieces_.begin ())pieces_.erase (pieces_.begin (),--ipiece);
79+ auto jpiece=pieces_.rbegin ();
80+ while (jpiece != pieces_.rend () && !(trange.overlaps ((*jpiece)->range ())))++jpiece;
81+ pieces_.erase (jpiece.base (),pieces_.end ());
7382 } else if (trange.begin () > pieces_.front ()->range ().end () || trange.end () < pieces_.back ()->range ().begin ())
74- throw std::invalid_argument (" Invalid Range" );
83+ throw std::invalid_argument (" PiecewiseTrajectory::setRange; Invalid Range" );
7584 // update piece range
76- pieces_.front ()->setRange ( TimeRange (trange. begin (),pieces_. front ()-> range ().end ()) );
77- pieces_.back ()->setRange ( TimeRange (pieces_. back ()-> range ().begin (), trange. end ()) );
85+ pieces_.front ()->range ().restrict (trange );
86+ pieces_.back ()->range ().restrict ( trange);
7887 }
7988
8089 template <class KTRAJ > PiecewiseTrajectory<KTRAJ>::PiecewiseTrajectory(KTRAJ const & piece) : pieces_(1 ,std::make_shared<KTRAJ>(piece))
@@ -89,13 +98,13 @@ namespace KinKal {
8998 prepend (newpiece,allowremove);
9099 break ;
91100 default :
92- throw std::invalid_argument (" Invalid direction" );
101+ throw std::invalid_argument (" PiecewiseTrajectory::add; Invalid direction" );
93102 }
94103 }
95104
96105 template <class KTRAJ > void PiecewiseTrajectory<KTRAJ>::prepend(KTRAJ const & newpiece, bool allowremove) {
97106 // new piece can't have null range
98- if (newpiece.range ().null ())throw std::invalid_argument (" Can't prepend null range traj" );
107+ if (newpiece.range ().null ())throw std::invalid_argument (" PiecewiseTrajectory::prepend; Can't prepend null range traj" );
99108 if (pieces_.empty ()){
100109 pieces_.push_back (std::make_shared<KTRAJ>(newpiece));
101110 } else {
@@ -104,7 +113,7 @@ namespace KinKal {
104113 if (allowremove)
105114 *this = PiecewiseTrajectory (newpiece);
106115 else
107- throw std::invalid_argument (" range overlap" );
116+ throw std::invalid_argument (" PiecewiseTrajector::prepend; range overlap" );
108117 } else {
109118 // find the piece that needs to be modified
110119 size_t ipiece = nearestIndex (newpiece.range ().end ());
@@ -122,15 +131,15 @@ namespace KinKal {
122131 pieces_.push_front (std::make_shared<KTRAJ>(newpiece));
123132 pieces_.front ()->range () = TimeRange (tmin,pieces_.front ()->range ().end ());
124133 } else {
125- throw std::invalid_argument (" range error" );
134+ throw std::invalid_argument (" PiecewiseTrajectory::prepend; range error" );
126135 }
127136 }
128137 }
129138 }
130139
131140 template <class KTRAJ > void PiecewiseTrajectory<KTRAJ>::append(KTRAJ const & newpiece, bool allowremove) {
132141 // new piece can't have null range
133- if (newpiece.range ().null ())throw std::invalid_argument (" Can't append null range traj" );
142+ if (newpiece.range ().null ())throw std::invalid_argument (" PiecewiseTrajectory::append; Can't append null range traj" );
134143 if (pieces_.empty ()){
135144 pieces_.push_back (std::make_shared<KTRAJ>(newpiece));
136145 } else {
@@ -139,7 +148,7 @@ namespace KinKal {
139148 if (allowremove)
140149 *this = PiecewiseTrajectory (newpiece);
141150 else
142- throw std::invalid_argument (" range overlap" );
151+ throw std::invalid_argument (" PiecewiseTrajectory::append; range overlap" );
143152 } else {
144153 // find the piece that needs to be modified
145154 size_t ipiece = nearestIndex (newpiece.range ().begin ());
@@ -159,7 +168,7 @@ namespace KinKal {
159168 pieces_.push_back (std::make_shared<KTRAJ>(newpiece));
160169 pieces_.back ()->range () = TimeRange (pieces_.back ()->range ().begin (),tmax);
161170 } else {
162- throw std::invalid_argument (" range error" );
171+ throw std::invalid_argument (" PiecewiseTrajectory::append; range error" );
163172 }
164173 }
165174 }
@@ -253,6 +262,35 @@ namespace KinKal {
253262 return ost;
254263 }
255264
265+ template <class KTRAJ > void PiecewiseTrajectory<KTRAJ>::pieceRange(TimeRange const & range,
266+ std::deque<std::shared_ptr<KTRAJ>>::const_iterator& first,
267+ std::deque<std::shared_ptr<KTRAJ>>::const_iterator& last ) const {
268+ first = last = pieces_.end ();
269+ // check for no overlap
270+ if (this ->range ().overlaps (range)){
271+ // find the first and last pieces which overlap with the range. They can be the same piece.
272+ first = pieces_.cbegin ();
273+ while (first != pieces_.cend () && !((*first)->range ().overlaps (range))) ++first;
274+ auto rlast = pieces_.crbegin ();
275+ while (rlast != pieces_.crend () && !((*rlast)->range ().overlaps (range))) ++rlast;
276+ last = (rlast+1 ).base (); // convert back to forwards-iterator
277+ }
278+ }
279+
280+ template <class KTRAJ > void PiecewiseTrajectory<KTRAJ>::pieceRange(TimeRange const & range,
281+ std::deque<std::shared_ptr<KTRAJ>>::iterator& first,
282+ std::deque<std::shared_ptr<KTRAJ>>::iterator& last) {
283+ first = last = pieces_.end ();
284+ // check for no overlap
285+ if (this ->range ().overlaps (range)){
286+ first = pieces_.begin ();
287+ while (first != pieces_.end () && !((*first)->range ().overlaps (range))) ++first;
288+ auto rlast = pieces_.rbegin ();
289+ while (rlast != pieces_.rend () && !((*rlast)->range ().overlaps (range))) ++rlast;
290+ last= (rlast+1 ).base ();
291+ }
292+ }
293+
256294 // clone op for reinstantiation
257295 template <class KTRAJ >
258296 PiecewiseTrajectory<KTRAJ>::PiecewiseTrajectory(PiecewiseTrajectory<KTRAJ> const & rhs){
0 commit comments