使用QT编写粒子显示热力图效果

1.使用QCustomplot第三方库控件;

传入类,以及点位数据大小;

cpp 复制代码
void heat_map::setupParticleEffect(QCustomPlot *customPlot,int x_size,int y_size)
{
    customPlot->clearPlottables();
    customPlot->clearItems();

    // 清空列表
    m_particles.clear();
    m_backgroundGrid.clear();  // 需要添加这个成员变量

    // 设置深色背景
    customPlot->setBackground(QColor("#1E1E1E"));

    // 隐藏所有轴和网格
    customPlot->xAxis->setVisible(false);
    customPlot->yAxis->setVisible(false);
    customPlot->xAxis->grid()->setVisible(false);
    customPlot->yAxis->grid()->setVisible(false);

    double spacing = 1.0;

    // 先创建背景网格(底层)
    double bgParticleSize = 1.2;  // 背景方块大小,和网格完全一致
    for (int y = 0; y < y_size; ++y) {
        for (int x = 0; x < x_size; ++x) {
            // 创建背景网格方块
            QCPItemRect *bgParticle = new QCPItemRect(customPlot);

            double left = x * spacing - bgParticleSize/2;
            double right = x * spacing + bgParticleSize/2;
            double bottom = y * spacing - bgParticleSize/2;
            double top = y * spacing + bgParticleSize/2;

            bgParticle->topLeft->setCoords(left, top);
            bgParticle->bottomRight->setCoords(right, bottom);

            // 设置背景网格样式(深灰色,带透明度)
            bgParticle->setBrush(QBrush(QColor(30, 30, 30, 80)));  // 深色半透明背景
            bgParticle->setPen(QPen(QColor(60, 60, 60, 50)));      // 网格线(可选)
            bgParticle->setPen(Qt::NoPen);  // 无边框,更柔和
            m_backgroundGrid.append(bgParticle);
        }
    }

    // 再创建彩色粒子层(上层)
    double particleSize = 0.5;  // 保持原来的大小
    for (int y = 0; y < y_size; ++y) {
        for (int x = 0; x < x_size; ++x) {
            double value = 6;
            if (value <= 0) continue;

            double normalized = qBound(0.0, value / 1, 1.0);
            int gray = 50 + normalized * 205;

            // 创建彩色粒子
            QCPItemRect *particle = new QCPItemRect(customPlot);

            double left = x * spacing - particleSize/2;
            double right = x * spacing + particleSize/2;
            double bottom = y * spacing - particleSize/2;
            double top = y * spacing + particleSize/2;

            particle->topLeft->setCoords(left, top);
            particle->bottomRight->setCoords(right, bottom);

            // 设置粒子样式(带透明度)
            particle->setBrush(QBrush(QColor(gray, gray, gray, 100)));
            particle->setPen(Qt::NoPen);  // 无边框,更柔和
            m_particles.append(particle);
        }
    }

    // 设置坐标轴范围
    customPlot->xAxis->setRange(-0.5, x_size * spacing - 0.5);
    customPlot->yAxis->setRange(-0.5, y_size * spacing - 0.5);

    customPlot->replot();
}

2.传入数据

cpp 复制代码
void heat_map::updateParticles(QCustomPlot *customPlot,const double *data)
{
    if (m_particles.size() != current_x_num * current_y_num) return;

    // 创建颜色渐变(只需创建一次,可以移到构造函数中)
    QCPColorGradient gradient;
    gradient.clearColorStops();
    // gradient.setColorStopAt(0.0, QColor("#1E1E1E"));
    gradient.setColorStopAt(0.001, QColor(0, 0, 180));     // 深蓝
    gradient.setColorStopAt(0.2, QColor(2, 6, 255));     // 纯蓝
    gradient.setColorStopAt(0.3, QColor(4, 49, 255));    // 深蓝
    gradient.setColorStopAt(0.4, QColor(1, 100, 253));   // 蓝绿
    gradient.setColorStopAt(0.5, QColor(4, 155, 252));   // 绿
    gradient.setColorStopAt(0.6, QColor(4, 203, 255));   // 黄绿
    gradient.setColorStopAt(0.65, QColor(3, 255, 2));    // 黄色
    gradient.setColorStopAt(0.7, QColor(254, 255, 2));   // 橙色
    gradient.setColorStopAt(0.8, QColor(254, 151, 4));   // 深橙
    gradient.setColorStopAt(0.9, QColor(255, 100, 2));   // 更深的橙色
    gradient.setColorStopAt(1.0, QColor(255, 0, 0));     // 纯红
    // 更新颜色
    // QVector<double>datafenerate= generateGaussianKernel(data);
    for (int i = 0; i < m_backgroundGrid.size(); ++i) {
        double value = data[i];
        if(value<=0.001)
        {
            m_backgroundGrid[i]->setBrush(QBrush(QColor(30, 30, 30, 100)));
            m_particles[i]->setBrush(QBrush(QColor(255, 255, 255, 100)));
        }
        else{
            double normalized = (value - mincolorsvalue) / maxcolorevalue;

            normalized = qBound(0.0, normalized, 1.0);
            // 从渐变获取颜色
            QColor color = gradient.color(normalized, QCPRange(0, 1));
            // color.setAlpha(200);  // 透明度 200/255

            m_backgroundGrid[i]->setBrush(QBrush(color));
            m_particles[i]->setBrush(QBrush(QColor(30, 30, 30,100)));
        }

    }

    customPlot->setPlottingHint(QCP::phFastPolylines);
    customPlot->replot(QCustomPlot::rpQueuedReplot);

    // 或用QGraphicsBlurEffect(适合整图模糊)
    // QGraphicsBlurEffect *blurEffect = new QGraphicsBlurEffect;
    // blurEffect->setBlurRadius(2); // 模糊半径
    // customPlot->setGraphicsEffect(blurEffect);

}

运行效果

相关推荐
2301_816651221 小时前
C++中的策略模式高级应用
开发语言·c++·算法
大树学长1 小时前
【QT开发】Redis通信相关(一)
redis·qt
liuyao_xianhui1 小时前
优选算法_模拟_替换所有的‘?‘_C++
开发语言·javascript·数据结构·c++·算法·链表·动态规划
笨笨马甲1 小时前
Qt 人脸识别
开发语言·qt
Riemann~~2 小时前
ros2写一个可以修改参数的node
开发语言·python·ros2·机器人系统
无巧不成书02182 小时前
Java核心技术全景解析:从白皮书到实战踩坑
java·开发语言
Roy_Sashulin2 小时前
基于AI的Java编程平台
java·开发语言·人工智能·sashulin·deepseek
周万宁.FoBJ2 小时前
vue源码讲解之 reactive解析(仅proxy部分)
开发语言·javascript·ecmascript
阿贵---2 小时前
单元测试在C++项目中的实践
开发语言·c++·算法