UnsizedSegmentation.hxx
Go to the documentation of this file.00001 #ifndef UnsizedSegmentation_hxx
00002 #define UnsizedSegmentation_hxx
00003
00004 #include "Segmentation.hxx"
00005
00006 namespace CLAM
00007 {
00008 class UnsizedSegmentation : public Segmentation
00009 {
00010 public:
00011 class InsertedOutOfBounds : public std::exception
00012 {
00013 public:
00014 const char * what() const throw () { return "Segmentation point inserted out of limits";}
00015 };
00016 typedef std::vector<double> TimePositions;
00017 public:
00018 UnsizedSegmentation()
00019 : Segmentation(0)
00020 {
00021 }
00022 UnsizedSegmentation(double maxPosition)
00023 : Segmentation(maxPosition)
00024 {
00025 }
00026
00027 UnsizedSegmentation(double maxPosition, const TData * begin, const TData * end)
00028 : Segmentation(maxPosition)
00029 {
00030 takeArray(begin, end);
00031 }
00035 void takeArray(const TData * begin, const TData * end)
00036 {
00037 for (const TData * it=begin; it!=end; it++)
00038 insert(*it);
00039 }
00040 ~UnsizedSegmentation()
00041 {
00042 }
00046 unsigned insert(double timePosition)
00047 {
00048 if (timePosition<0.0) throw InsertedOutOfBounds();
00049 if (timePosition>=maxPosition()) throw InsertedOutOfBounds();
00050 TimePositions::iterator insertPoint =
00051 std::lower_bound(_offsets.begin(), _offsets.end(), timePosition);
00052 if (insertPoint==_offsets.end())
00053 {
00054 _offsets.push_back(timePosition);
00055 _onsets.push_back(timePosition);
00056 _selection.push_back(false);
00057 return _offsets.size()-1;
00058 }
00059 unsigned position = insertPoint - _offsets.begin();
00060 _offsets.insert(insertPoint, timePosition);
00061 _onsets.insert(_onsets.begin()+position, timePosition);
00062 _selection.insert(_selection.begin()+position, false);
00063 if (position<=_current) _current++;
00064 return position;
00065 }
00072 void remove(unsigned segment)
00073 {
00074 _offsets.erase(_offsets.begin()+segment);
00075 _onsets.erase(_onsets.begin()+segment);
00076 _selection.erase(_selection.begin()+segment);
00077 if (_current!=0 && segment<=_current) _current--;
00078 }
00085 unsigned pickOffset(double timePosition, double tolerance) const
00086 {
00087 return pickPosition(_offsets, timePosition, tolerance);
00088 }
00095 unsigned pickOnset(double timePosition, double tolerance) const
00096 {
00097 return pickPosition(_onsets, timePosition, tolerance);
00098 }
00102 unsigned pickSegmentBody(double timePosition) const
00103 {
00104 if (timePosition<0) return _offsets.size();
00105 TimePositions::const_iterator upperBound =
00106 std::lower_bound(_offsets.begin(), _offsets.end(), timePosition);
00107 if (upperBound == _offsets.begin()) return 0;
00108 if (timePosition - *(upperBound-1) > *upperBound - timePosition) return upperBound - _offsets.begin();
00109 return upperBound - _offsets.begin()-1;
00110 }
00116 void dragOnset(unsigned segment, double newTimePosition)
00117 {
00118
00119 dragOffset(segment, newTimePosition);
00120 }
00126 void dragOffset(unsigned segment, double newTimePosition)
00127 {
00128 if (segment==_offsets.size()) return;
00129
00130
00131 double leftLimit = segment!=0 ?
00132 _onsets[segment-1] : 0.0;
00133 double rightLimit = segment+1<_offsets.size()?
00134 _onsets[segment+1] : maxPosition();
00135 if (newTimePosition<leftLimit)
00136 newTimePosition = leftLimit;
00137
00138 if (newTimePosition>rightLimit)
00139 newTimePosition = rightLimit;
00140
00141
00142 _offsets[segment]=newTimePosition;
00143 _onsets[segment]=newTimePosition;
00144 }
00148 void fillArray(DataArray& segmentation) const
00149 {
00150 unsigned nSegments = _onsets.size();
00151 segmentation.Resize(nSegments);
00152 segmentation.SetSize(nSegments);
00153 for (unsigned i=0; i<nSegments; i++)
00154 segmentation[i]=_onsets[i];
00155 }
00156
00157 const char * GetClassName() const { return "UnsizedSegmentation"; }
00158
00159 private:
00167 unsigned pickPosition(const TimePositions & positions, double timePosition, double tolerance) const
00168 {
00169 TimePositions::const_iterator lowerBound =
00170 std::lower_bound(positions.begin(), positions.end(), timePosition-tolerance);
00171 TimePositions::const_iterator upperBound =
00172 std::upper_bound(lowerBound, positions.end(), timePosition+tolerance);
00173
00174 if (lowerBound==upperBound) return positions.size();
00175
00176
00177 unsigned lowerSegment = lowerBound - positions.begin();
00178 unsigned upperSegment = upperBound - positions.begin();
00179 double lastDifference = std::fabs(timePosition-positions[lowerSegment]);
00180 for (unsigned i=lowerSegment; i<upperSegment; i++)
00181 {
00182 double newDifference = std::fabs(timePosition-positions[i]);
00183 if (newDifference>lastDifference) break;
00184 lastDifference = newDifference;
00185 lowerSegment = i;
00186 }
00187 return lowerSegment;
00188 }
00189 };
00190
00191 }
00192
00193
00194
00195 #endif//UnsizedSegmentation_hxx
00196