Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Interval contains and intersects support for different types #141

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
129 changes: 104 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,70 @@ 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;
}
}

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