从 QPolygonF 获取最后 n 个元素

Get last n elements from QPolygonF

本文关键字:元素 最后 QPolygonF 获取      更新时间:2023-10-16

我有一个包含三个QStrings(sensorId)的std::map< QString, QPolygonF>,每个传感器都有一些数据作为QVector< QPointF>,这些数据是连续生成的,并写入cv::Mat

在下面的代码块中,我从每个传感器的cv::Mat中获取数据并将其保存在std::map< QString, double> m_Value;中,并将值推入std::map< QString, QPolygonF> m_Points。我只收集每个传感器的数据 5 次。之后,我将我的积分发送到其他班级,以便用QwtPlot可视化它们。

std::map<QString, QPolygonF> m_Points
std::map<QString, double>  m_Value;
std::map<QString, int> m_Index;
for(int i= 0; i< 5 ++i)
{
m_Value[sensorId]= dataMat.at<double>(i);
m_Points[sensorId].push_back(QPointF((double)m_Index[sensorId], 
m_Value[sensorId]));
m_Index[sensorId]++;
}
qDebug()<<" POINTS: " << toolId << m_Points[toolId];
emit updateDataSignal(m_Points); 

有了std::map< QString, int> m_Index;,我继续/增加发送点的数量。

仅一个循环的 for 循环输出如下所示:

POINTS: 
sensor1 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue)
sensor2 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue)
sensor3 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue)

对于第二个循环:

sensor1 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue) QPolygonF(5, newPointValue) QPolygonF(6, newPointValue) QPolygonF(7, newPointValue) QPolygonF(8, newPointValue) QPolygonF(9, newPointValue)
sensor2 ...
sensor3 ...

一段时间后,我有数千个点,我的Qwtplot通过实时绘制/更新而变慢。因此,我只想发送例如地图上的最后 5 个点。

传感器1 的输出应如下所示:

第一个循环:

sensor1 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue)

第二循环:

sensor1 QPolygonF(5, newPointValue) QPolygonF(6, newPointValue) QPolygonF(7, newPointValue) QPolygonF(8, newPointValue) QPolygonF(9, newPointValue)

第三循环:

sensor1 QPolygonF(10, newPointValue) QPolygonF(11, newPointValue) QPolygonF(12, newPointValue) QPolygonF(13, newPointValue) QPolygonF(14, newPointValue)
...

谢谢

我认为您的示例代码不正确,因为您没有将 map 用于其预期目的——即使用 O(1) 查找时间存储键值对。

如前所述,您应该改用std::vector,然后您可以访问使用std::vector::end迭代器添加的最后五个元素 (cplusplus doc link)。根据您的需要,您可能需要将其切片为新向量,方法是使用end获得所需元素的const_iterator并构建新向量:

vector<T>::const_iterator last = myVec.end() - 1;
vector<T>::const_iterator first = last - 5;
vector<T> newVec(first, last);

此方法取自此处的另一个堆栈溢出问题:从向量中提取子向量的最佳方法?

答案很简单:不要存储超过 5 分。或者,更确切地说, 始终在m_Points中存储 5 个最新点。将所有数据放在一个结构中可能也会有助于参考位置。因此:

class Class : public QObject {
Q_OBJECT
std::map<QString, SensorData> m_data;
public:
struct SensorData {
QPolygonF points{5};
qreal value;
int index;
};
void method(const QString &sensorId, const cv::Mat<double> &matrix);
Q_SIGNAL void updateDataSignal(const QPolygonF &);
};    
void Class::method(const QString &sensorId, const cv::Mat<double> &matrix) {
auto &data = m_data[sensorId]; // cache the lookup
for(int i=0; i<data.points.size(); ++i) {
data.value = matrix.at<double>(i);
data.points[i] = {(qreal)data.index, data.value};
data.index++;
}
emit updateDataSignal(data.points);
}