From 3b689f4ea0bb44902cdb70059621081efaecc87e Mon Sep 17 00:00:00 2001 From: Allan Bazinet Date: Fri, 6 Dec 2024 06:07:03 -0800 Subject: [PATCH] Add ColorMapper functor --- plotter.cpp | 41 ++++++++++++++++------------------------- plotter.h | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/plotter.cpp b/plotter.cpp index e7899be2..4dbf17bc 100644 --- a/plotter.cpp +++ b/plotter.cpp @@ -1,5 +1,4 @@ #include "plotter.h" -#include #include #include #include @@ -222,11 +221,11 @@ CPlotter::drawData(WF::SWide swide, // Display the processed data in the waterfall, drawing only the range // that's displayed. - auto const gain = gainFactor(); + auto const color = colorMapper(); for (auto x = 0; x < m_w; ++x) { - p.setPen(m_colors[std::clamp(m_plotZero + static_cast(swide[x] * gain), 0, 254)]); + p.setPen(color(swide[x])); p.drawPoint(x, 0); } @@ -639,15 +638,6 @@ CPlotter::replot() m_WaterfallPixmap.fill(Qt::black); - // Given a value, return color a to use for a point, based on the - // zero, gain, and color palette settings. - - auto const color = [this, - gain = gainFactor()](auto const value) - { - return m_colors[std::clamp(m_plotZero + static_cast(gain * value), 0, 254)]; - }; - // We need to consider that entries have been added to the replot // buffer at a rate proportional to the display pixel ratio, i.e., // it deals in device pixels, not logical pixels, so we must deal @@ -688,20 +678,16 @@ CPlotter::replot() // Standard waterfall data display; run through the vector of data // and color each corresponding point in the pixmap appropriately. - [width = m_WaterfallPixmap.size().width(), - &color = std::as_const(color), - &y = std::as_const(y), + [width = m_WaterfallPixmap.size().width(), + color = colorMapper(), + &y = std::as_const(y), &p ](WF::SWide const & swide) { - auto x = 0; - auto it = swide.begin(); - auto const end = it + width; - for (; it != end; ++it) + for (auto x = 0; x < width; ++x) { - p.setPen(color(*it)); + p.setPen(color(swide[x])); p.drawPoint(x, y); - x++; } } }; @@ -816,11 +802,16 @@ CPlotter::freqFromX(int const x) const return m_startFreq + x * m_freqPerPixel; } -float -CPlotter::gainFactor() const +CPlotter::ColorMapper +CPlotter::colorMapper() const { - return 10.f * std::sqrt(m_binsPerPixel * m_waterfallAvg / 15.0f) - * std::pow(10.0f, 0.015f * m_plotGain); + auto const gain = 10.f + * std::sqrt(m_binsPerPixel * m_waterfallAvg / 15.0f) + * std::pow(10.0f, 0.015f * m_plotGain); + + return ColorMapper(m_colors, + m_plotZero, + gain); } void diff --git a/plotter.h b/plotter.h index 81456d50..0b72c8b0 100644 --- a/plotter.h +++ b/plotter.h @@ -8,6 +8,7 @@ #ifndef PLOTTER_H #define PLOTTER_H +#include #include #include #include @@ -102,6 +103,32 @@ protected: private: + // Class to reduce the six things that the color of a pixel in the + // waterfall plot depends on to just one one thing. + + class ColorMapper + { + Colors const & m_colors; + int m_zero; + float m_gain; + + public: + + ColorMapper(Colors const & colors, + int const zero, + float const gain) + : m_colors(colors) + , m_zero (zero) + , m_gain (gain) + {} + + auto + operator()(float const value) const + { + return m_colors[std::clamp(m_zero + static_cast(m_gain * value), 0, 254)]; + } + }; + // Replot data storage; alternatives of nothing at all, a // string denoting the label of a transmit period interval // start, and waterfall display data, flattened. Important @@ -115,11 +142,11 @@ private: // Accessors - bool shouldDrawSpectrum(WF::State) const; - bool in30MBand() const; - int xFromFreq(float f) const; - float freqFromX(int x) const; - float gainFactor() const; + bool shouldDrawSpectrum(WF::State) const; + bool in30MBand() const; + int xFromFreq(float f) const; + float freqFromX(int x) const; + ColorMapper colorMapper() const; // Manipulators