Browse Source

[wip] Math: support inverted ranges.

Could be useful in combination with inverted scissor that's present on
new NV HW.

TODO: finish tests for all functions
TODO: implement all functions
TODO: doc better, mention that not all APIs could be happy with this
inverted-ranges
Vladimír Vondruš 8 years ago
parent
commit
c37da6715a
  1. 18
      src/Magnum/Math/Range.h
  2. 12
      src/Magnum/Math/Test/RangeTest.cpp

18
src/Magnum/Math/Range.h

@ -50,6 +50,13 @@ namespace Implementation {
Axis-aligned line (in 1D), rectangle (in 2D) or cube (in 3D). Minimal
coordinate is inclusive, maximal exclusive. See @ref Range1D, @ref Range2D and
@ref Range3D specializations for given dimension count.
@section Math-Range-inverted Inverted ranges
It is valid to create ranges where a maximal coordinate is less than the
matching minimal coordinate in some dimension. The range is then interpreted as
inverted in given dimension, affecting result of @ref contains(), @ref intersect(),
@ref intersects() and @ref join().
*/
template<UnsignedInt dimensions, class T> class Range {
template<UnsignedInt, class> friend class Range;
@ -234,7 +241,6 @@ template<UnsignedInt dimensions, class T> class Range {
* @f]
*
* The range minimum is interpreted as inclusive, maximum as exclusive.
* Results are undefined if the range has negative size.
* @see @ref intersects(), @ref contains(const Range<dimensions, T>&) const,
* @ref min(), @ref max()
*/
@ -252,7 +258,6 @@ template<UnsignedInt dimensions, class T> class Range {
* (\operatorname{max}(B)_i \le \operatorname{max}(A)_i)
* @f]
*
* Results are undefined if the range has negative size.
* @see @ref intersects(), @ref contains(const VectorType&) const,
* @ref min(), @ref max()
*/
@ -646,8 +651,7 @@ template<UnsignedInt dimensions, class T> inline Range<dimensions, T> join(const
Returns a range that covers the intersection of both ranges. If the
intersection is empty, a default-constructed range is returned. The range
minimum is interpreted as inclusive, maximum as exclusive. Results are
undefined if any range has a negative size.
minimum is interpreted as inclusive, maximum as exclusive.
@see @ref intersects()
*/
template<UnsignedInt dimensions, class T> inline Range<dimensions, T> intersect(const Range<dimensions, T>& a, const Range<dimensions, T>& b) {
@ -664,13 +668,13 @@ Returns @cpp true @ce if the following holds for all dimensions @f$ i @f$,
(\operatorname{max}(A)_i > \operatorname{min}(B)_i) \land
(\operatorname{min}(A)_i < \operatorname{max}(B)_i)
@f]
The range minimum is interpreted as inclusive, maximum as exclusive. Results
are undefined if any range has a negative size.
The range minimum is interpreted as inclusive, maximum as exclusive.
@see @ref Range::contains(), @ref intersect(), @ref join(), @ref Range::min(),
@ref Range::max()
*/
template<UnsignedInt dimensions, class T> inline bool intersects(const Range<dimensions, T>& a, const Range<dimensions, T>& b) {
return (a.max() > b.min()).all() && (a.min() < b.max()).all();
return ((a.min() > b.min()) & (a.min() < b.max())).all() ||
((b.min() > a.min()) & (b.min() < a.max())).all();
}
/** @debugoperator{Range} */

12
src/Magnum/Math/Test/RangeTest.cpp

@ -119,6 +119,7 @@ struct RangeTest: Corrade::TestSuite::Tester {
void containsVector();
void containsRange();
void containsRangeInverted();
void intersectIntersects();
void join();
@ -161,6 +162,7 @@ RangeTest::RangeTest() {
&RangeTest::containsVector,
&RangeTest::containsRange,
&RangeTest::containsRangeInverted,
&RangeTest::intersectIntersects,
&RangeTest::join,
@ -581,6 +583,16 @@ void RangeTest::containsRange() {
CORRADE_VERIFY(!a.contains(j));
}
void RangeTest::containsRangeInverted() {
/* Inverse range contains things that are only outside */
Range2Di b({40, 50}, {10, 30});
CORRADE_VERIFY( b.contains({{45, 55}, { 5, 25}}));
CORRADE_VERIFY(!b.contains({{35, 45}, {15, 35}})); /* B contains A */
CORRADE_VERIFY(!b.contains({{15, 35}, {35, 45}})); /* Fully inside */
CORRADE_VERIFY(!b.contains({{45, 55}, {15, 25}})); /* "Leaks" on max X */
CORRADE_VERIFY(!b.contains({{45, 45}, { 5, 25}})); /* "Leaks" on min Y */
}
void RangeTest::intersectIntersects() {
Range2Di a({34, 23}, {47, 30});

Loading…
Cancel
Save