Skip to content

Commit

Permalink
feat: add Interval contains and intersects support for different types
Browse files Browse the repository at this point in the history
  • Loading branch information
phc1990 committed Aug 13, 2024
1 parent c7c0f29 commit 67aa56b
Show file tree
Hide file tree
Showing 3 changed files with 770 additions and 553 deletions.
4 changes: 4 additions & 0 deletions include/OpenSpaceToolkit/Mathematics/Object/Interval.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,10 @@ class Interval : public IntervalBase
static types::String StringFromType(const Interval::Type& anIntervalType);

private:
bool contains(const T& aValue, const bool& isOpen) const;
bool checkAgainstLowerBound(const T& aValue, const bool& isOpen, const bool& isUpperBound) const;
bool checkAgainstUpperBound(const T& aValue, const bool& isOpen, const bool& isLowerBound) const;

Interval::Type type_;

T lowerBound_;
Expand Down
193 changes: 168 additions & 25 deletions src/OpenSpaceToolkit/Mathematics/Object/Interval.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,33 @@ bool Interval<T>::intersects(const Interval& anInterval) const
throw ostk::core::error::runtime::Undefined("Interval");
}

return this->contains(anInterval.lowerBound_) || this->contains(anInterval.upperBound_) ||
anInterval.contains(lowerBound_) || anInterval.contains(upperBound_) || (*this) == anInterval;
if (!anInterval.isDefined())
{
throw ostk::core::error::runtime::Undefined("Interval");
}

return (
(this->checkAgainstLowerBound(
anInterval.lowerBound_,
anInterval.type_ == Interval<T>::Type::Open || anInterval.type_ == Interval<T>::Type::HalfOpenLeft,
false
) ||
this->checkAgainstLowerBound(
anInterval.upperBound_,
anInterval.type_ == Interval<T>::Type::Open || anInterval.type_ == Interval<T>::Type::HalfOpenRight,
true
)) &&
(this->checkAgainstUpperBound(
anInterval.lowerBound_,
anInterval.type_ == Interval<T>::Type::Open || anInterval.type_ == Interval<T>::Type::HalfOpenLeft,
true
) ||
this->checkAgainstUpperBound(
anInterval.upperBound_,
anInterval.type_ == Interval<T>::Type::Open || anInterval.type_ == Interval<T>::Type::HalfOpenRight,
false
))
);
}

template <class T>
Expand All @@ -98,42 +123,32 @@ bool Interval<T>::contains(const T& aValue) const
throw ostk::core::error::runtime::Undefined("Interval");
}

switch (type_)
{
case Interval<T>::Type::Closed:
return (lowerBound_ <= aValue) && (aValue <= upperBound_);

case Interval<T>::Type::Open:
return (lowerBound_ < aValue) && (aValue < upperBound_);

case Interval<T>::Type::HalfOpenLeft:
return (lowerBound_ < aValue) && (aValue <= upperBound_);

case Interval<T>::Type::HalfOpenRight:
return (lowerBound_ <= aValue) && (aValue < upperBound_);

default:
throw ostk::core::error::runtime::Wrong("Type");
break;
}

return false;
return this->contains(aValue, false);
}

template <class T>
bool Interval<T>::contains(const Interval& anInterval) const
{
if (!anInterval.isDefined())
if (!this->isDefined())
{
throw ostk::core::error::runtime::Undefined("Interval");
}

if (!this->isDefined())
if (!anInterval.isDefined())
{
throw ostk::core::error::runtime::Undefined("Interval");
}

return this->contains(anInterval.lowerBound_) && this->contains(anInterval.upperBound_);
return this->checkAgainstLowerBound(
anInterval.lowerBound_,
anInterval.type_ == Interval<T>::Type::Open || anInterval.type_ == Interval<T>::Type::HalfOpenLeft,
false
) &&
this->checkAgainstUpperBound(
anInterval.upperBound_,
anInterval.type_ == Interval<T>::Type::Open || anInterval.type_ == Interval<T>::Type::HalfOpenRight,
false
);
}

template <class T>
Expand Down Expand Up @@ -500,6 +515,134 @@ types::String Interval<T>::StringFromType(const Interval::Type& anIntervalType)
return types::String::Empty();
}

template <class T>
bool Interval<T>::contains(const T& aValue, const bool& isOpen) const
{
return this->checkAgainstLowerBound(aValue, isOpen, false) && this->checkAgainstUpperBound(aValue, isOpen, false);
}

template <class T>
bool Interval<T>::checkAgainstLowerBound(const T& aValue, const bool& isOpen, const bool& isUpperBound) const
{
switch (type_)
{
case Interval<T>::Type::Closed:
case Interval<T>::Type::HalfOpenRight:
if (isOpen && isUpperBound)
{
return lowerBound_ < aValue;
}

return lowerBound_ <= aValue;

case Interval<T>::Type::HalfOpenLeft:
case Interval<T>::Type::Open:
if (isOpen && !isUpperBound)
{
return lowerBound_ <= aValue;
}

return lowerBound_ < aValue;

default:
throw ostk::core::error::runtime::Wrong("Type");
break;
}
}

template <class T>
bool Interval<T>::checkAgainstUpperBound(const T& aValue, const bool& isOpen, const bool& isLowerBound) const
{
switch (type_)
{
case Interval<T>::Type::Closed:
case Interval<T>::Type::HalfOpenLeft:
if (isOpen && isLowerBound)
{
return upperBound_ > aValue;
}

return upperBound_ >= aValue;

case Interval<T>::Type::HalfOpenRight:
case Interval<T>::Type::Open:
if (isOpen && !isLowerBound)
{
return upperBound_ >= aValue;
}

return upperBound_ > aValue;

default:
throw ostk::core::error::runtime::Wrong("Type");
break;
}
}

// template <class T>
// bool Interval<T>::containsLowerBound(const Interval& anInterval) const
// {
// switch (type_)
// {
// case Interval<T>::Type::Closed:
// case Interval<T>::Type::HalfOpenRight:
// return lowerBound_ <= anInterval.lowerBound_;

// case Interval<T>::Type::HalfOpenLeft:
// case Interval<T>::Type::Open:
// switch (type_)
// {
// case Interval<T>::Type::Closed:
// case Interval<T>::Type::HalfOpenRight:
// return lowerBound_ < anInterval.lowerBound_;

// case Interval<T>::Type::HalfOpenLeft:
// case Interval<T>::Type::Open:
// return lowerBound_ <= anInterval.lowerBound_;

// default:
// throw ostk::core::error::runtime::Wrong("Type");
// break;
// }

// default:
// throw ostk::core::error::runtime::Wrong("Type");
// break;
// }
// }

// template <class T>
// bool Interval<T>::containsUpperBound(const Interval& anInterval) const
// {
// switch (type_)
// {
// case Interval<T>::Type::Closed:
// case Interval<T>::Type::HalfOpenLeft:
// return upperBound_ >= anInterval.upperBound_;

// case Interval<T>::Type::HalfOpenRight:
// case Interval<T>::Type::Open:
// switch (type_)
// {
// case Interval<T>::Type::Closed:
// case Interval<T>::Type::HalfOpenLeft:
// return upperBound_ > anInterval.upperBound_;

// case Interval<T>::Type::HalfOpenRight:
// case Interval<T>::Type::Open:
// return upperBound_ >= anInterval.upperBound_;

// default:
// throw ostk::core::error::runtime::Wrong("Type");
// break;
// }

// default:
// throw ostk::core::error::runtime::Wrong("Type");
// break;
// }
// }

} // namespace object
} // namespace mathematics
} // namespace ostk
Loading

0 comments on commit 67aa56b

Please sign in to comment.