使用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);

}

运行效果

相关推荐
西飘客23 分钟前
vs 怎么根据dll 生成lib文件
c++·qt
bkspiderx1 小时前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
程序员老陆1 小时前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
沐晓时光1 小时前
C语言入门,深入理解指针(3)
c语言·开发语言
码云数智-园园2 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
禾小西3 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨3 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言
徐小黑ACG3 小时前
Golang 基础05 结构体struct
开发语言·算法·golang
优橙教育4 小时前
零基础学AI应用开发要多久?3个月能到什么水平
服务器·开发语言·网络·php
半杯咖啡半行码4 小时前
Qt开发实战:数据库、MV 模式、QProcess与串口通信全攻略
数据库·qt