Browse Source

Math: add Range::scaled() and scaledFromCenter() taking a scalar.

Having to form a vector when scaling by the same value in all dimensions
is wasteful.
pull/168/head
Vladimír Vondruš 3 years ago
parent
commit
72b36347c3
  1. 2
      doc/changelog.dox
  2. 34
      src/Magnum/Math/Range.h
  3. 13
      src/Magnum/Math/Test/RangeTest.cpp

2
doc/changelog.dox

@ -648,6 +648,8 @@ See also:
return a reference to a fixed-size array instead of a pointer (i.e.,
@cpp T(&)[size] @ce instead of @cpp T* @ce) for more convenient usage in
APIs that take sized views.
- Added @ref Math::Range::scaled() and @ref Math::Range::scaledFromCenter()
overloads taking a scalar
@subsubsection changelog-latest-changes-meshtools MeshTools library

34
src/Magnum/Math/Range.h

@ -287,23 +287,47 @@ template<UnsignedInt dimensions, class T> class Range {
* Multiplies the minimal and maximal coordinates by given amount.
* Center *doesn't* remain the same, use @ref scaledFromCenter() for
* that operation.
* @see @ref padded()
* @see @ref padded(), @ref scaled(T) const
*/
Range<dimensions, T> scaled(const VectorType& scaling) const {
return {_min*scaling, _max*scaling};
}
/**
* @overload
* @m_since_latest
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt d = dimensions, class = typename std::enable_if<d != 1>::type>
#endif
Range<dimensions, T> scaled(T scaling) const {
return {_min*scaling, _max*scaling};
}
/**
* @brief Range scaled from the center
*
* Scales the size, while center remains the same.
* @see @ref scaled(), @ref padded(), @ref fromCenter()
* @see @ref scaled(), @ref padded(), @ref fromCenter(),
* @ref scaledFromCenter(T) const
*/
Range<dimensions, T> scaledFromCenter(const VectorType& scaling) const {
/* Can't use *T(0.5) because that won't work for integers */
return fromCenter(center(), size()*scaling/T(2));
}
/**
* @overload
* @m_since_latest
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt d = dimensions, class = typename std::enable_if<d != 1>::type>
#endif
Range<dimensions, T> scaledFromCenter(T scaling) const {
/* Can't use *T(0.5) because that won't work for integers */
return fromCenter(center(), size()*scaling/T(2));
}
/**
* @brief Whether given point is contained inside the range
*
@ -375,8 +399,14 @@ template<UnsignedInt dimensions, class T> class Range {
Type<T> scaled(const VectorType<T>& scaling) const { \
return Range<dimensions, T>::scaled(scaling); \
} \
Type<T> scaled(T scaling) const { \
return Range<dimensions, T>::scaled(scaling); \
} \
Type<T> scaledFromCenter(const VectorType<T>& scaling) const { \
return Range<dimensions, T>::scaledFromCenter(scaling); \
} \
Type<T> scaledFromCenter(T scaling) const { \
return Range<dimensions, T>::scaledFromCenter(scaling); \
}
#endif

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

@ -666,9 +666,12 @@ void RangeTest::padded1D() {
void RangeTest::scaled() {
Range2Di a({34, 23}, {47, 30});
Range2Di b({68, -69}, {94, -90});
Range2Di c({68, 46}, {94, 60});
CORRADE_COMPARE(a.scaled({2, -3}), b);
CORRADE_COMPARE(a.scaled(2), c);
CORRADE_COMPARE((a.size()*Vector2i{2, -3}), b.size());
CORRADE_COMPARE(a.size()*2, c.size());
}
void RangeTest::scaled1D() {
@ -682,10 +685,14 @@ void RangeTest::scaled1D() {
void RangeTest::scaledFromCenter() {
Range2Di a{{34, 22}, {48, 30}};
Range2Di b{{27, 38}, {55, 14}};
Range2Di c{{27, 18}, {55, 34}};
CORRADE_COMPARE(a.scaledFromCenter({2, -3}), b);
CORRADE_COMPARE(a.scaledFromCenter(2), c);
CORRADE_COMPARE(a.center(), b.center());
CORRADE_COMPARE(a.center(), c.center());
CORRADE_COMPARE((a.size()*Vector2i{2, -3}), b.size());
CORRADE_COMPARE(a.size()*2, c.size());
}
void RangeTest::scaledFromCenter1D() {
@ -943,7 +950,9 @@ void RangeTest::subclassTypes() {
CORRADE_VERIFY(std::is_same<decltype(r.translated(a)), Recti>::value);
CORRADE_VERIFY(std::is_same<decltype(r.padded(a)), Recti>::value);
CORRADE_VERIFY(std::is_same<decltype(r.scaled(a)), Recti>::value);
CORRADE_VERIFY(std::is_same<decltype(r.scaled(2)), Recti>::value);
CORRADE_VERIFY(std::is_same<decltype(r.scaledFromCenter(a)), Recti>::value);
CORRADE_VERIFY(std::is_same<decltype(r.scaledFromCenter(2)), Recti>::value);
}
void RangeTest::subclass() {
@ -960,8 +969,12 @@ void RangeTest::subclass() {
Recti(Vector2i{31, 28}, Vector2i{50, 25}));
CORRADE_COMPARE(Recti(Vector2i{34, 23}, Vector2i{47, 30}).scaled({2, -3}),
Recti(Vector2i{68, -69}, Vector2i{94, -90}));
CORRADE_COMPARE(Recti(Vector2i{34, 23}, Vector2i{47, 30}).scaled(2),
Recti(Vector2i{68, 46}, Vector2i{94, 60}));
CORRADE_COMPARE(Recti(Vector2i{34, 22}, Vector2i{48, 30}).scaledFromCenter({2, -3}),
Recti(Vector2i{27, 38}, Vector2i{55, 14}));
CORRADE_COMPARE(Recti(Vector2i{34, 22}, Vector2i{48, 30}).scaledFromCenter(2),
Recti(Vector2i{27, 18}, Vector2i{55, 34}));
}
void RangeTest::debug() {

Loading…
Cancel
Save