##// END OF EJS Templates
Mesh generation for QColorMap (2)...
Mesh generation for QColorMap (2) Creates method to generate mesh and starts implementation (preconditions)

File last commit:

r1034:3411e62bc9af
r1034:3411e62bc9af
Show More
DataSeriesUtils.cpp
116 lines | 4.5 KiB | text/x-c | CppLexer
/ core / src / Data / DataSeriesUtils.cpp
#include "Data/DataSeriesUtils.h"
#include <cmath>
Q_LOGGING_CATEGORY(LOG_DataSeriesUtils, "DataSeriesUtils")
void DataSeriesUtils::fillDataHoles(std::vector<double> &xAxisData, std::vector<double> &valuesData,
double resolution, double fillValue, double minBound,
double maxBound)
{
if (resolution == 0. || std::isnan(resolution)) {
qCWarning(LOG_DataSeriesUtils())
<< "Can't fill data holes with a null resolution, no changes will be made";
return;
}
if (xAxisData.empty()) {
qCWarning(LOG_DataSeriesUtils())
<< "Can't fill data holes for empty data, no changes will be made";
return;
}
// Gets the number of values per x-axis data
auto nbComponents = valuesData.size() / xAxisData.size();
// Generates fill values that will be used to complete values data
std::vector<double> fillValues(nbComponents, fillValue);
// Checks if there are data holes on the beginning of the data and generates the hole at the
// extremity if it's the case
auto minXAxisData = xAxisData.front();
if (!std::isnan(minBound) && minBound < minXAxisData) {
auto holeSize = static_cast<int>((minXAxisData - minBound) / resolution);
if (holeSize > 0) {
xAxisData.insert(xAxisData.begin(), minXAxisData - holeSize * resolution);
valuesData.insert(valuesData.begin(), fillValues.begin(), fillValues.end());
}
}
// Same for the end of the data
auto maxXAxisData = xAxisData.back();
if (!std::isnan(maxBound) && maxBound > maxXAxisData) {
auto holeSize = static_cast<int>((maxBound - maxXAxisData) / resolution);
if (holeSize > 0) {
xAxisData.insert(xAxisData.end(), maxXAxisData + holeSize * resolution);
valuesData.insert(valuesData.end(), fillValues.begin(), fillValues.end());
}
}
// Generates other data holes
auto xAxisIt = xAxisData.begin();
while (xAxisIt != xAxisData.end()) {
// Stops at first value which has a gap greater than resolution with the value next to it
xAxisIt = std::adjacent_find(
xAxisIt, xAxisData.end(),
[resolution](const auto &a, const auto &b) { return (b - a) > resolution; });
if (xAxisIt != xAxisData.end()) {
auto nextXAxisIt = xAxisIt + 1;
// Gets the values that has a gap greater than resolution between them
auto lowValue = *xAxisIt;
auto highValue = *nextXAxisIt;
// Completes holes between the two values by creating new values (according to the
// resolution)
for (auto i = lowValue + resolution; i < highValue; i += resolution) {
// Gets the iterator of values data from which to insert fill values
auto nextValuesIt = valuesData.begin()
+ std::distance(xAxisData.begin(), nextXAxisIt) * nbComponents;
// New value is inserted before nextXAxisIt
nextXAxisIt = xAxisData.insert(nextXAxisIt, i) + 1;
// New values are inserted before nextValuesIt
valuesData.insert(nextValuesIt, fillValues.begin(), fillValues.end());
}
// Moves to the next value to continue loop on the x-axis data
xAxisIt = nextXAxisIt;
}
}
}
DataSeriesUtils::Mesh DataSeriesUtils::regularMesh(DataSeriesIterator begin, DataSeriesIterator end,
Resolution xResolution, Resolution yResolution)
{
// Checks preconditions
if (xResolution.m_Val == 0. || std::isnan(xResolution.m_Val) || yResolution.m_Val == 0.
|| std::isnan(yResolution.m_Val)) {
qCWarning(LOG_DataSeriesUtils()) << "Can't generate mesh with a null resolution";
return Mesh{};
}
if (xResolution.m_Logarithmic) {
qCWarning(LOG_DataSeriesUtils())
<< "Can't generate mesh with a logarithmic x-axis resolution";
return Mesh{};
}
if (std::distance(begin, end) == 0) {
qCWarning(LOG_DataSeriesUtils()) << "Can't generate mesh for empty data";
return Mesh{};
}
auto yData = begin->y();
if (yData.empty()) {
qCWarning(LOG_DataSeriesUtils()) << "Can't generate mesh for data with no y-axis";
return Mesh{};
}
// Converts y-axis and its resolution to logarithmic values
if (yResolution.m_Logarithmic) {
std::for_each(yData.begin(), yData.end(), [](auto &val) { val = std::log10(val); });
}
}