10#include <QtCore/QList>
25template <
typename ValueType>
85 bool IsInside(ValueType point)
const;
158 void Erode(ValueType leftValue, ValueType rightValue);
165 void Dilate(ValueType leftValue, ValueType rightValue);
172 void RemoveGaps(ValueType value,
bool gapState =
false);
198template <
typename ValueType>
205template <
typename ValueType>
216template <
typename ValueType>
219 m_switchPoints.clear();
220 m_beginState =
false;
224template <
typename ValueType>
227 return m_switchPoints.empty() && (m_beginState ==
false);
231template <
typename ValueType>
234 return m_switchPoints;
238template <
typename ValueType>
241 return m_switchPoints;
245template <
typename ValueType>
248 std::pair<typename SwitchPoints::iterator, bool> insertionStatus = m_switchPoints.insert(point);
249 if (!insertionStatus.second){
250 m_switchPoints.erase(insertionStatus.first);
255template <
typename ValueType>
262template <
typename ValueType>
265 m_beginState = state;
269template <
typename ValueType>
272 bool state = m_beginState;
273 for (
typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
274 iter != m_switchPoints.end();
287template <
typename ValueType>
290 bool state = m_beginState;
291 for (
typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
292 iter != m_switchPoints.end();
299 return (iter == m_switchPoints.end()) || (*iter >= range.
GetMaxValue());
313template <
typename ValueType>
316 typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
317 typename SwitchPoints::const_iterator listIter = rangesList.m_switchPoints.begin();
319 bool state = m_beginState;
320 bool listState = rangesList.m_beginState;
323 bool isListCovered = state || !listState;
328 if (iter != m_switchPoints.end()){
329 ValueType point = *iter;
331 if (listIter != rangesList.m_switchPoints.end()){
332 ValueType listPoint = *listIter;
334 if (point <= listPoint){
339 if (listPoint <= point){
341 listState = !listState;
350 return listIter == rangesList.m_switchPoints.end();
356template <
typename ValueType>
359 if (clipRangePtr !=
NULL){
361 result.m_beginState =
false;
365 bool state = m_beginState;
367 for (
typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
368 iter != m_switchPoints.end();
370 ValueType position = *iter;
375 if (position > prevPosition){
377 result.m_switchPoints.insert(prevPosition);
378 result.m_switchPoints.insert(position);
381 prevPosition = position;
388 result.m_switchPoints.insert(prevPosition);
389 result.m_switchPoints.insert(clipRangePtr->
GetMaxValue());
393 result.m_switchPoints = m_switchPoints;
394 result.m_beginState = !m_beginState;
399template <
typename ValueType>
402 if (clipRangePtr !=
NULL){
405 bool state = m_beginState;
408 for (
typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
409 (iter != m_switchPoints.end()) && (*iter < prevPosition);
410 m_switchPoints.erase(iter++)){
414 typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
417 if ((iter != m_switchPoints.end()) && (*iter > prevPosition)){
418 m_switchPoints.insert(prevPosition);
422 for (; iter != m_switchPoints.end(); ++iter){
423 ValueType position = *iter;
425 m_switchPoints.erase(iter, m_switchPoints.end());
434 m_switchPoints.insert(clipRangePtr->
GetMaxValue());
437 m_beginState =
false;
440 m_beginState = !m_beginState;
445template <
typename ValueType>
450 GetUnion(rangesList, retVal);
456template <
typename ValueType>
459 typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
460 typename SwitchPoints::const_iterator listIter = rangesList.m_switchPoints.begin();
462 bool state = m_beginState;
463 bool listState = rangesList.m_beginState;
465 bool resultState = state || listState;
467 result.m_beginState = resultState;
468 result.m_switchPoints.clear();
471 if (iter != m_switchPoints.end()){
472 ValueType point = *iter;
474 if (listIter != rangesList.m_switchPoints.end()){
475 ValueType listPoint = *listIter;
477 if (point <= listPoint){
482 if (listPoint <= point){
484 listState = !listState;
487 bool unitedStateAfter = state || listState;
488 if (unitedStateAfter != resultState){
489 result.m_switchPoints.insert(qMin(point, listPoint));
491 resultState = unitedStateAfter;
496 result.m_switchPoints.insert(iter, m_switchPoints.end());
503 if (!state && (listIter != rangesList.m_switchPoints.end())){
504 result.m_switchPoints.insert(listIter, rangesList.m_switchPoints.end());
513template <
typename ValueType>
516 typename SwitchPoints::iterator iter = m_switchPoints.begin();
517 typename SwitchPoints::const_iterator listIter = rangesList.m_switchPoints.begin();
519 bool state = m_beginState;
520 bool listState = rangesList.m_beginState;
522 m_beginState = state || listState;
525 if (iter != m_switchPoints.end()){
526 ValueType point = *iter;
528 if (listIter != rangesList.m_switchPoints.end()){
529 ValueType listPoint = *listIter;
531 if (point == listPoint){
535 listState = !listState;
537 else if (point < listPoint){
539 iter = m_switchPoints.erase(iter);
548 iter = m_switchPoints.insert(iter, listPoint);
551 listState = !listState;
556 m_switchPoints.erase(iter, m_switchPoints.end());
563 if (!state && (listIter != rangesList.m_switchPoints.end())){
564 m_switchPoints.insert(listIter, rangesList.m_switchPoints.end());
573template <
typename ValueType>
580 bool firstPointState = m_beginState;
581 typename SwitchPoints::const_iterator firstIter = m_switchPoints.begin();
582 for (;firstIter != m_switchPoints.end(); ++firstIter){
587 firstPointState = !firstPointState;
590 bool secondPointState = firstPointState;
591 typename SwitchPoints::const_iterator secondIter = firstIter;
592 for (;secondIter != m_switchPoints.end(); ++secondIter){
597 secondPointState = !secondPointState;
600 if (firstIter != secondIter){
603 m_switchPoints.erase(m_switchPoints.begin(), firstIter);
604 m_switchPoints.erase(m_switchPoints.begin(), secondIter);
607 m_switchPoints.erase(firstIter, secondIter);
612 m_switchPoints.clear();
616 m_beginState = m_beginState || isInverted;
618 if (firstPointState == isInverted){
622 if (secondPointState == isInverted){
628template <
typename ValueType>
633 GetIntersection(rangesList, retVal);
639template <
typename ValueType>
642 typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
643 typename SwitchPoints::const_iterator listIter = rangesList.m_switchPoints.begin();
645 bool state = m_beginState;
646 bool listState = rangesList.m_beginState;
648 bool resultState = state && listState;
650 result.m_beginState = resultState;
651 result.m_switchPoints.clear();
654 if (iter != m_switchPoints.end()){
655 ValueType point = *iter;
657 if (listIter != rangesList.m_switchPoints.end()){
658 ValueType listPoint = *listIter;
660 if (point <= listPoint){
665 if (listPoint <= point){
667 listState = !listState;
670 bool unitedStateAfter = state && listState;
671 if (unitedStateAfter != resultState){
672 result.m_switchPoints.insert(qMin(point, listPoint));
674 resultState = unitedStateAfter;
679 result.m_switchPoints.insert(iter, m_switchPoints.end());
686 if (state && (listIter != rangesList.m_switchPoints.end())){
687 result.m_switchPoints.insert(listIter, rangesList.m_switchPoints.end());
696template <
typename ValueType>
699 typename SwitchPoints::iterator iter = m_switchPoints.begin();
700 typename SwitchPoints::const_iterator listIter = rangesList.m_switchPoints.begin();
702 bool state = m_beginState;
703 bool listState = rangesList.m_beginState;
705 m_beginState = state && listState;
708 if (iter != m_switchPoints.end()){
709 ValueType point = *iter;
711 if (listIter != rangesList.m_switchPoints.end()){
712 ValueType listPoint = *listIter;
714 if (point == listPoint){
718 listState = !listState;
720 else if (point < listPoint){
722 iter = m_switchPoints.erase(iter);
731 iter = m_switchPoints.insert(iter, listPoint);
734 listState = !listState;
739 m_switchPoints.erase(iter, m_switchPoints.end());
746 if (state && (listIter != rangesList.m_switchPoints.end())){
747 m_switchPoints.insert(listIter, rangesList.m_switchPoints.end());
756template <
typename ValueType>
759 m_beginState = !m_beginState;
761 Union(range, !isInverted);
763 m_beginState = !m_beginState;
767template <
typename ValueType>
774template <
typename ValueType>
777 if (leftValue * rightValue < 0){
778 Dilate(leftValue, 0);
779 Dilate(0, rightValue);
784 ValueType absoluteSum = std::abs(leftValue + rightValue);
785 if (absoluteSum <= 0){
789 bool isErosion = (leftValue + rightValue < 0);
790 ValueType leftValueAbs = std::abs(leftValue);
791 ValueType rightValueAbs = std::abs(rightValue);
793 typename SwitchPoints::iterator iter = m_switchPoints.begin();
794 while (iter != m_switchPoints.end()){
795 ValueType point = *iter;
797 const bool state = std::distance(m_switchPoints.begin(), iter) % 2 > 0 ? m_beginState : !m_beginState;
798 if (!state == isErosion){
800 if (iter != m_switchPoints.begin()){
801 auto prevIter = std::prev(iter);
803 if (*prevIter > point - absoluteSum){
805 m_switchPoints.erase(prevIter);
806 m_switchPoints.erase(iter++);
813 m_switchPoints.erase(iter++);
814 iter = m_switchPoints.insert(iter, point - leftValueAbs);
818 auto nextIter = std::next(iter);
820 if (nextIter != m_switchPoints.end()){
821 if (*nextIter < point + absoluteSum){
823 m_switchPoints.erase(nextIter);
824 m_switchPoints.erase(iter++);
831 m_switchPoints.erase(iter++);
832 iter = m_switchPoints.insert(iter, point + rightValueAbs);
840template <
typename ValueType>
844 Dilate(value, value);
849 Dilate(value, value);
854template <
typename ValueType>
858 for (
typename SwitchPoints::iterator iter = m_switchPoints.begin();
859 iter != m_switchPoints.end();
861 newSwitchPoints.insert(*iter + offset);
864 m_switchPoints.swap(newSwitchPoints);
868template <
typename ValueType>
873 bool state = m_beginState;
875 for (
typename SwitchPoints::const_iterator iter = m_switchPoints.begin();
876 iter != m_switchPoints.end();
878 ValueType position = *iter;
883 if (position > prevPosition){
888 prevPosition = position;
900template <
typename ValueType>
903 return (m_beginState == ranges.m_beginState) && (m_switchPoints == ranges.m_switchPoints);
907template <
typename ValueType>
910 return (m_beginState != ranges.m_beginState) || (m_switchPoints != ranges.m_switchPoints);
914template <
typename ValueType>
924 iter != m_switchPoints.end();
926 const ValueType& pos = *iter;
928 retVal = retVal ^ uint(pos);
937template <
typename ValueType>
Implementation of a abstract range defined by two values - minimum and maximum.
ValueType GetMaxValue() const
Get the top value.
ValueType GetMinValue() const
Get the bottom value.
bool IsEmpty() const
Return true if the bottom value is equal to the top value.
void Invert(const TRange< ValueType > *clipRangePtr)
Invert this range in place.
bool IsInside(ValueType point) const
Check if some point belongs to set.
std::vector< TRange< ValueType > > RangeVector
void Dilate(ValueType leftValue, ValueType rightValue)
Calculate dilatation of this range list.
SwitchPoints & GetSwitchPointsRef()
Allows access to stored switch points.
void SetBeginState(bool state)
Set begin state.
void InsertSwitchPoint(ValueType point)
Insert new switch point.
bool IsEmpty() const
Check if this set is empty.
void Erode(ValueType leftValue, ValueType rightValue)
Calculate erosion of this range list.
std::set< ValueType > SwitchPoints
bool operator==(const TRanges< ValueType > &ranges) const
bool GetBeginState() const
Get begin state.
uint GetHashValue(uint seed=0) const
TRanges< ValueType > GetUnion(const TRanges< ValueType > &rangesList) const
Get union of two range list.
void ShiftRanges(ValueType offset)
ShiftRanges all points in this set using specified offset.
bool operator!=(const TRanges< ValueType > &ranges) const
const SwitchPoints & GetSwitchPoints() const
Get stored switch points.
void RemoveGaps(ValueType value, bool gapState=false)
Remove gaps with some length.
TRanges()
Default constructor initializing this set to be empty.
void Union(const TRanges< ValueType > &rangesList)
Calculate union of this range list and the other one.
void Intersection(const TRanges< ValueType > &rangesList)
Calculate intersection of this range list and the other one.
void Reset()
Set this set to be empty.
void GetInverted(TRanges< ValueType > &result, const TRange< ValueType > *clipRangePtr) const
Get inverted range.
void GetAsList(const TRange< ValueType > &range, RangeList &result) const
Get this set as list of istd::TRange objects.
QList< TRange< ValueType > > RangeList
TRanges< ValueType > GetIntersection(const TRanges< ValueType > &rangesList) const
Get intersection of two range list.
TRanges< double > CRanges
uint qHash(const CVarIndex &index, uint seed=0)
TRanges< int > CIntRanges