qt仿雷达图扫描效果

2 篇文章 0 订阅
1 篇文章 0 订阅
这篇博客展示了如何利用Qt进行仿雷达扫描效果的实现,包括绘制雷达的背景、坐标轴、刻度、转动部分以及目标点。代码中详细定义了CRadar类,包含了绘制事件、大小重置事件和定时器事件的处理。雷达扫描效果通过定时器更新扇形旋转区域来实现动态效果,并能根据目标点信息动态绘制目标点及其航向。
摘要由CSDN通过智能技术生成

话不多说,上代码。

头文件:

#ifndef CRADAR_H
#define CRADAR_H

/*************************************************
描述: 仿雷达扫描效果
**************************************************/

#include <QWidget>
#include "QPainter"
#include <QJsonObject>

class CRadar : public QWidget
{
    Q_OBJECT
public:
    explicit CRadar(QWidget *parent = nullptr);
    QVector<QJsonObject> mb_points;        //目标点
    int home_dir;   //指北偏移角度

protected:
    void paintEvent(QPaintEvent *event);    //绘制事件
    void resizeEvent(QResizeEvent *event);  //大小重置事件
    void timerEvent(QTimerEvent *event);    //定时器事件
private:
    QRect         m_drawArea;      //绘制区域
    int           m_pieRotate;     //扇形旋转区域
    int           m_timerId;       //定时器ID
    int           m_pointTimerId;  //变更点定时器
    int           m_nSpeed;        //速度
    QList<QPoint> m_points;        //绘制点
    QList<int>    m_pointsAlapha;  //绘制点颜色alapha值
    QPoint CustomRotate(QPointF point,qreal from_angle,qreal rotate);
    QList<QPointF> trans(int angle,float len1,float len2);
};

#endif // CRADAR_H

cpp文件:

#include "cradar.h"
#include <QPainter>
#include <QtMath>
#include <QTimerEvent>
#include <QConicalGradient>
#include <qDebug>
#include "math.h"
CRadar::CRadar(QWidget *parent) : QWidget(parent)
{
    //初始化
    m_pieRotate = 0;
    m_timerId = -1;
    m_nSpeed = 50;
    m_pointsAlapha<<100<<100<<100<<100<<100;

    //启动定时器
    m_timerId = startTimer(m_nSpeed);
    //m_pointTimerId = startTimer(1200);
}

void CRadar::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    //抗锯齿
    painter.setRenderHint(QPainter::Antialiasing);

    //背景
    //    painter.fillRect(rect(),QColor(15,45,188));

    //边长
    int len = m_drawArea.width()-30;

    //底盘(x轴、y轴和4个圆)
    painter.setPen(QPen(Qt::green));
    //圆
    painter.drawEllipse(m_drawArea.center(),len*21/40,len*21/40);
    painter.drawEllipse(m_drawArea.center(),len/2,len/2);
    painter.drawEllipse(m_drawArea.center(),len/3,len/3);
    painter.drawEllipse(m_drawArea.center(),len/6,len/6);

    int fontSize = 15;
    int p_crosses = 3;//十字架数量
    //坐标轴
    for(int i=0; i < p_crosses; i++)
    {
        QLineF line1,line2;
        float angle = (static_cast<float>(i) * 90.0) / (static_cast<float>(p_crosses));
        line1.setP1( m_drawArea.center() );
        line1.setLength( len/2);

        QRectF textRect(0, 0, 4 * fontSize, fontSize + 2);

        for(int c = 0; c < 4; c++)
        {
            line1.setAngle(angle + c*90.0 + 90.0);
            painter.drawLine(line1);
            line2 = QLineF(line1);
            line2.setLength(len/2+6.5 );
            textRect.moveCenter(line2.p2());
            if(i > 0){
                painter.drawText( textRect, Qt::AlignCenter, QString("%1").arg((int)(360 - (c*90 ) - angle) , 3 , 10));
            }else
            {
                if(c == 0)
                {
                    painter.drawText( textRect, Qt::AlignCenter,QString("0"));
                }
                else if(c == 1)
                {
                    painter.drawText( textRect, Qt::AlignCenter, QString("270"));
                }
                else if(c == 2)
                {
                    painter.drawText( textRect, Qt::AlignCenter, QString("180"));
                }
                else if(c == 3)
                {
                    painter.drawText( textRect, Qt::AlignCenter, QString("90"));
                }
            }
        }
    }

    //刻度
    int num=1;
    float len1 = len*21/40;
    float len2;
    QList<QPointF> pointArr;
    for(int i=0;i<360;i++){
        num++;
        //10的倍数刻度要略长
        if(num==11){
            len2 = len/2;
            pointArr = trans(i,len1,len2);
            num=1;
        }else{
            len2 = len*41/80;
            pointArr = trans(i,len1,len2);
        }
        //画刻度
        painter.drawLine(pointArr.at(0),pointArr.at(1));
    }
    //转动部分
    //---//线
    qreal x = m_drawArea.center().x() + (qreal)len/2 * cos(-m_pieRotate*3.14159/180);
    qreal y = m_drawArea.center().y() + (qreal)len/2 * sin(-m_pieRotate*3.14159/180);
    QColor linecolor(20,232,147);//设置颜色
    painter.setPen(QPen(Qt::green));
    painter.drawLine(m_drawArea.center(),QPointF(x,y));

    //----//扇形
    QConicalGradient gradient;
    gradient.setCenter(m_drawArea.center());
    gradient.setAngle(m_pieRotate + 180); //渐变与旋转方向恰好相反,以扇形相反的边作为渐变角度。
    gradient.setColorAt(0.4,QColor(32, 255, 77,100)); //从渐变角度开始0.5 - 0.75为扇形区域,由于Int类型计算不精确,将范围扩大到0.4-0.8
    gradient.setColorAt(0.8,QColor(32, 255, 77,0));
    painter.setBrush(QBrush(gradient));
    painter.setPen(Qt::NoPen);
    painter.drawPie(m_drawArea,m_pieRotate*16,90*16);
    QPixmap pixmap_n(":/images/icon-red.png");

    //绘制本舰指北方向
    QPixmap pixmap3(":/images/jiantou.png");
    painter.translate(m_drawArea.center());
    painter.rotate(-home_dir);//旋转角度
    QPoint point = CustomRotate(QPoint(len/2,0),0,-90);// 使图片方向不变
    painter.drawPixmap(point.x()-pixmap3.width(),point.y()-pixmap3.height(),pixmap3);
    painter.resetTransform();

    QPixmap pixmap2(":/images/mubiao.png");

    //绘制目标点
    for(int i = 0; i < mb_points.size(); i++)
    {
        painter.save();
        int x_mb= m_drawArea.center().x()+static_cast<int>(mb_points.at(i).value("x").toDouble());
        int y_mb = m_drawArea.center().y()-static_cast<int>(mb_points.at(i).value("h").toDouble());
        //背景图恢复正常指向
        int dir_mb = (mb_points.at(i).value("dir").toDouble())-180;
        int id_mb = (mb_points.at(i).value("id").toInt());
        //绘制目标点名称
        painter.setPen(QColor(Qt::white));
        painter.drawText(x_mb-20,y_mb+20,QString::number(id_mb));

        //绘制目标航向
        painter.translate(QPointF(x_mb,y_mb));
        painter.rotate(dir_mb);//旋转角度
        painter.drawPixmap(QPoint(-8,-8),pixmap2);
        painter.restore();
    }
}
QPoint CRadar::CustomRotate(QPointF point,qreal from_angle,qreal rotate)
{
    qreal PI=3.141592653589;
    QPointF Tmp;
    qreal arc = (rotate-from_angle)/180*PI;
    qreal Length = qSqrt(point.x()*point.x() +point.y()*point.y());
    Tmp.setX(Length*qCos(arc));
    Tmp.setY(Length*qSin(arc));
    return Tmp.toPoint();
}
//将角度转为两个坐标点
QList<QPointF> CRadar::trans(int angle,float len1,float len2)
{
    QList<QPointF> list;
    QPointF ptResult1(m_drawArea.center());
    QPointF ptResult2(m_drawArea.center());
    //[角度转弧度]
    float rad = qDegreesToRadians(static_cast<float>(angle));

    ptResult1.setX(m_drawArea.center().x() + len1 * qSin(static_cast<qreal>(rad)));
    ptResult1.setY(m_drawArea.center().y() - len1 * qCos(static_cast<qreal>(rad)));
    list.append(ptResult1);
    ptResult2.setX(m_drawArea.center().x() + len2 * qSin(static_cast<qreal>(rad)));
    ptResult2.setY(m_drawArea.center().y() - len2 * qCos(static_cast<qreal>(rad)));
    list.append(ptResult2);
    return list;
}
void CRadar::resizeEvent(QResizeEvent *event)
{
    //以较短的边长作为绘制区域边长
    if(width() > height())
    {
        m_drawArea = QRect((width() - height())/2,0,height(),height());
    }
    else
    {
        m_drawArea = QRect(0,(height() - width())/2,width(),width());
    }

    m_drawArea.adjust(10,10,-10,-10);
}

void CRadar::timerEvent(QTimerEvent *event)
{
    if(m_timerId == event->timerId())
    {
        m_pieRotate -= 10;
        update();
    }
    else if(m_pointTimerId == event->timerId())
    {
        //随机更换装饰的点
        for(int i = 0; i < m_points.count(); ++i)
        {
            int offsetX = rand()%m_drawArea.width();
            int offsetY = rand()%m_drawArea.width();
            int alapha = rand()%255;
            m_points.replace(i,QPoint(offsetX,offsetY) + m_drawArea.topLeft());
            m_pointsAlapha.replace(i,alapha);
        }

        update();
    }
}

组件调用:

在需要显示雷达效果图的页面引入radar组件,然后放入widget中,

CRadar radar = new CRadar(this);
//我是直接放入了一个水平布局中
ui->horizontalLayout_26->addWidget(radar);

当雷达图里的目标点需要更换时,把存储目标点的线性链表先清空再重新赋值:

//清空原有目标信息
radar->mb_points.clear();
//targetList存储的是目标坐标等信息
 if(targetList.length()<=0) return;
float m_PI = 3.1415926;
//home_dir是指北偏移角度
 radar->home_dir = navigate->m_home.m_navigate.m_direction;
 for(int i=0;i<targetList.length();i++){
   //目标行驶方向
   float m_dir=targetList.at(i).direction;
    //目标坐标
   float hig = targetList.at(i).y;//y坐标
   float mb_x =targetList.at(i).x;//x坐标

   QJsonObject jsonobj;
   jsonobj.insert("x",mb_x);
   jsonobj.insert("h",hig);
   jsonobj.insert("dir",m_dir);
   jsonobj.insert("id", targetList.at(i).m_id);//目标id
   radar->mb_points.append(jsonobj);
}

QT雷达波束扫描图是一种用于显示雷达扫描结果的图形化工具。它能够以图表的形式直观地展示出雷达接收到的目标信息。通常,雷达波束扫描图被用于显示雷达探测到的目标的位置、速度和方向等信息。 QT是一个跨平台的应用程序开发框架,它提供了丰富的图形化界面设计工具和库函数。通过使用QT,我们可以方便地创建和绘制雷达波束扫描图。 雷达波束扫描图通常由两个部分组成:雷达位置图和目标信息图。雷达位置图显示了雷达的位置和扫描范围,通常以雷达位置为中心,以圆或扇形的方式表示扫描范围。目标信息图则显示了雷达探测到的目标的位置和其他相关信息。这些目标通常用点或其他形状表示,并配有标签来标识其属性。通过不同的颜色或形状,目标信息图可以提供更多的目标属性信息,例如目标的速度、方向或类型等。 QT雷达波束扫描图能够实时地从雷达接收到的数据中生成,并能够动态地更新图表。该图表常用于航空、海洋等领域中的目标监测和追踪任务。通过观察雷达波束扫描图,操作人员可以更加直观地了解目标的状态和动态变化,从而辅助决策和操作。 总的来说,QT雷达波束扫描图是一种能够以图表形式展示雷达探测结果的工具,具有直观、实时更新等特点,广泛应用于目标监测和追踪任务中。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值