From 1fbf2c4e688374079208273a866597c3e005f0fb Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Tue, 31 Mar 2020 10:51:23 +0200
Subject: [PATCH] Add reversed()

---
 SimoxUtility/color/ColorMap.cpp       | 24 +++++++++++++++++++++++
 SimoxUtility/color/ColorMap.h         | 18 +++++++++++++----
 SimoxUtility/tests/color/ColorMap.cpp | 28 +++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/SimoxUtility/color/ColorMap.cpp b/SimoxUtility/color/ColorMap.cpp
index d32ffd188..3c24ff552 100644
--- a/SimoxUtility/color/ColorMap.cpp
+++ b/SimoxUtility/color/ColorMap.cpp
@@ -95,6 +95,30 @@ namespace simox::color
     }
 
 
+    ColorMap ColorMap::reversed() const
+    {
+        ColorMap rev;
+        if (!empty())
+        {
+            auto fit = keys.begin();
+            auto bit = keys.end();
+            --bit;
+            while (fit != keys.end())
+            {
+                rev.keys[fit->first] = bit->second;
+
+                ++fit;
+                --bit;
+            }
+        }
+        rev._vmin = _vmin;
+        rev._vmax = _vmax;
+        rev._name = _name + "_r";
+
+        return rev;
+    }
+
+
     float ColorMap::original_vmin() const
     {
         if (empty())
diff --git a/SimoxUtility/color/ColorMap.h b/SimoxUtility/color/ColorMap.h
index 4c66557ec..a9ba1fdaf 100644
--- a/SimoxUtility/color/ColorMap.h
+++ b/SimoxUtility/color/ColorMap.h
@@ -58,20 +58,24 @@ namespace simox::color
 
         /// Apply this colormap to a vector.
         template <typename V>
-        std::vector<Color> operator()(const std::vector<V>& vector) const { return simox::apply(vector, *this); }
-        /// Apply this colormap to a map.
+        std::vector<Color> operator()(const std::vector<V>& vector) const { return simox::alg::apply(*this, vector); }
+        /// Apply this colormap to a map's values.
         template <typename K, typename V>
-        std::map<K, Color> operator()(const std::map<K, V>& map) const { return simox::apply(map, *this); }
+        std::map<K, Color> operator()(const std::map<K, V>& map) const { return simox::alg::apply(*this, map); }
+
 
         std::string name() const { return _name; }
         void setName(const std::string& name) { this->_name = name; }
 
 
+        /// The value corresponding to the bottom color.
         float vmin() const { return _vmin ? *_vmin : original_vmin(); }
-        float vmax() const { return _vmax ? *_vmax : original_vmax(); }
         void set_vmin(float vmin) { this->_vmin = vmin; }
+        /// The value corresponding to the top color.
+        float vmax() const { return _vmax ? *_vmax : original_vmax(); }
         void set_vmax(float vmax) { this->_vmax = vmax; }
 
+        /// Sets the value limits, i.e. scales the color map to the range [vmin, vmax].
         void set_vlimits(float vmin, float vmax)
         {
             set_vmin(vmin);
@@ -79,6 +83,10 @@ namespace simox::color
         }
 
 
+        /// Get this colormap reversed (but defined in the same value range as this).
+        ColorMap reversed() const;
+
+
     private:
 
         /// Return the lowest key value in `keys` (0 if empty).
@@ -96,7 +104,9 @@ namespace simox::color
         std::string _name = "";
 
 
+        /// The "virtual" minimal value.
         std::optional<float> _vmin = std::nullopt;
+        /// The "virtual" maximal value.
         std::optional<float> _vmax = std::nullopt;
 
     };
diff --git a/SimoxUtility/tests/color/ColorMap.cpp b/SimoxUtility/tests/color/ColorMap.cpp
index 6f1b65d44..ee4fd56f6 100644
--- a/SimoxUtility/tests/color/ColorMap.cpp
+++ b/SimoxUtility/tests/color/ColorMap.cpp
@@ -246,4 +246,32 @@ BOOST_AUTO_TEST_CASE(test_apply_map)
 }
 
 
+BOOST_AUTO_TEST_CASE(test_reversed)
+{
+    const simox::Color colorA(1.0, 0.5, 0.0);
+    const simox::Color colorB(0.5, 0.5, 0.5);
+    const simox::Color colorC(0.0, 0.5, 1.0);
+
+    const simox::color::ColorMap cmap {
+        { -1, colorC }, { 0, colorB }, { 2, colorA }
+    };
+
+    const simox::color::ColorMap rev = cmap.reversed();
+
+    BOOST_CHECK_EQUAL(rev.at(-2), colorA);
+    BOOST_CHECK_EQUAL(rev.at(-1), colorA);
+    BOOST_CHECK_EQUAL(rev.at( 0), colorB);
+    BOOST_CHECK_EQUAL(rev.at( 2), colorC);
+    BOOST_CHECK_EQUAL(rev.at( 3), colorC);
+
+    BOOST_CHECK_EQUAL(rev.at(-0.75), simox::Color(0.875, 0.5, 0.125));
+    BOOST_CHECK_EQUAL(rev.at(-0.50), simox::Color(0.750, 0.5, 0.250));
+    BOOST_CHECK_EQUAL(rev.at(-0.25), simox::Color(0.625, 0.5, 0.375));
+
+    BOOST_CHECK_EQUAL(rev.at(0.5), simox::Color(0.375, 0.5, 0.625));
+    BOOST_CHECK_EQUAL(rev.at(1.0), simox::Color(0.250, 0.5, 0.750));
+    BOOST_CHECK_EQUAL(rev.at(1.5), simox::Color(0.125, 0.5, 0.875));
+}
+
+
 BOOST_AUTO_TEST_SUITE_END()
-- 
GitLab