QT雷达扫描仪表

实现雷达扫描图,主要难点在于扫面目标这块。
当前提供两种方法:1、弧度法;2、等比三角。
1、弧度法:会使用到atan、atan2、qAtan、qAtan2。其中atan和atan2、QAtan和QAtan2它们区别在于atan、qAtan它弧度的范围是[-PI/2,PI/2],atan2、qAtan2它的弧度范围是[-PI,PI];我们得到弧度后将它转换为角度,然后通过角度来进行比较。弧度转角度,只需要”*180/PI“就可以实现转换。

2、等比三角:就是两个三角形,A三角形它的边长为abc;B三角形它的边长为efg。且a/e = b/f = c/g,我们进行扫描时,目标位置会与扫描线构成一对等比三角形,所以凡是符合这个公式的就能判断目标位置在扫描线上。

qFloor 向下取整
qCeil 向上取整
qRound 四舍五入

代码示例:完整代码

void Widget::paintEvent(QPaintEvent *event)
{
#if 1
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    QString pixpath = QApplication::applicationDirPath()+"/世界地图.jfif";
    painter.drawPixmap(0,0,width(),height(),QPixmap(pixpath));
    painter.setPen(Qt::white);
    painter.drawLine(QPoint(width()/2,0),QPoint(width()/2,height()));
    painter.drawLine(QPoint(0,height()/2),QPoint(width(),height()/2));
    painter.translate(width()/2,height()/2);

    painter.setPen(Qt::white);
    painter.drawEllipse(QPoint(0,0),width()/2,height()/2);

    painter.drawEllipse(QPoint(0,0),width()/4,height()/4);

    painter.drawEllipse(QPoint(0,0),width()/8,height()/8);

    painter.drawEllipse(QPoint(0,0),width()/16,height()/16);

    painter.drawEllipse(QPoint(0,0),width()/32,height()/32);

    //余晖扫描
    //   int len = m_drawArea.width();
    double x = width()/2 * cos(m_pieRotate*PI/180);
    double y = height()/2 * sin(m_pieRotate*PI/180);
    painter.setPen(QPen(Qt::green));
    painter.drawLine(QPoint( 0, 0 ),QPointF(x,y));

    //扇形
    QConicalGradient gradient;
    gradient.setCenter(QPoint( 0, 0 ));
    gradient.setAngle(-m_pieRotate + 180); //渐变与旋转方向恰好相反,以扇形相反的边作为渐变角度。
    gradient.setColorAt(0.4,QColor(169,253,51,100)); //从渐变角度开始0.5 - 0.75为扇形区域,由于Int类型计算不精确,将范围扩大到0.4-0.8
    gradient.setColorAt(0.8,QColor(169,253,51,0));
    painter.setBrush(QBrush(gradient));
    painter.setPen(Qt::NoPen);
    painter.drawPie(-width()/2,-height()/2,width(),height(),-m_pieRotate*16,90*16);


    //目标圆位置
    QPointF p1(0,0);  //扫描线起点坐标
    QPointF p2(x,y);  //扫描线终点坐标
    for (int i = 0; i < m_desPoints.size(); ++i) {
        QPointF Q = m_desPoints[i];
#if 1
        scanRegion1(painter,Q,p1,p2,i);
#else
        scanRegion2(painter,Q,p1,p2,i);
#endif
    }
#endif

}

void Widget::scanRegion1(QPainter &painter,QPointF Q,QPointF p1,QPointF p2,int index)
{
    double s1 = atan2(Q.y(),Q.x())*180/PI;
    double s2 = atan2(p2.y(),p2.x())*180/PI;
    painter.save();
    painter.translate(Q);
    painter.rotate(2*m_pieRotate);

    //按照弧度来计算,此处求弧度的方法atan、atan2、qAtan、qAtan2。
    //atan弧度范围[-PI/2,PI/2]、atan2弧度范围[-PI,PI]
    if (s1 <= s2 && s1 >= s2 - ShowRange)    //判断一个返回内出现的目标。
        //        if (s2 >= qFloor(s1) && s2 <= qCeil(s1)) //判断扫描线上出现的目标
    {
        painter.setPen(Qt::green);
        painter.setBrush(QBrush(QColor(255,255,255,50)));
        QPointF P = QPointF(0,0);  //移到坐标原点,配合rotate实现自转。
        painter.drawEllipse(P,maxSize,maxSize);
        painter.drawRect(P.x()-(maxSize+4)/2,P.y()-(maxSize+4)/2,maxSize+4,maxSize+4);
        painter.drawText(P.x()-(maxSize+4)/2,P.y()-(maxSize+4)/2,maxSize+4,maxSize+4,Qt::AlignCenter,QString::number(index));
    }
    else
    {
        painter.setPen(Qt::red);
        painter.setBrush(QBrush(QColor(255,255,255,50)));
        QPointF P = QPointF(0,0); //移到坐标原点,配合rotate实现自转。
        painter.drawEllipse(P,NoalmalSize,NoalmalSize);
        painter.drawRect(P.x()-(NoalmalSize+4)/2,P.y()-(NoalmalSize+4)/2,NoalmalSize+4,NoalmalSize+4);
    }
    painter.restore();

}

void Widget::scanRegion2(QPainter &painter,QPointF Q,QPointF p1,QPointF p2,int index)
{
    painter.save();
    painter.translate(Q);
    painter.rotate(2*m_pieRotate);
    // 叉积公式:(Q - P1) * (P2 - P1)= 0   判断Q点是否在点P1到P2的线段上
    // (Q.x - P1.x) * (P2.y - P1.y) == (P2.x - P1.x) * (Q.y - P1.y)
    //        int val = (Q.x() - p1.x())*(p2.y() - p1.y()) - (p2.x() - p1.x())*(Q.y() - p1.y());

    //等比 三角形A(边abc)和三角形B(边efg)是等比三角形,所以a/e = b/f = c/g.扫描线和出现在扫描线上的坐标点构成等比三角形。
    double val = (Q.x() - p1.x())/(p2.x() - p1.x()) - (Q.y() - p1.y())/(p2.y() - p1.y());
    //        qDebug()<<val;
    if ( val<= 0.1 && val >= -0.1
         && qMin(p1.x() , p2.x()) <= Q.x() && Q.x() <= qMax(p1.x() , p2.x())
         && qMin(p1.y() , p2.y()) <= Q.y() && Q.y() <= qMax(p1.y() , p2.y()))
    {
        painter.setPen(Qt::green);
        painter.setBrush(QBrush(QColor(255,255,255,50)));
        QPointF P = QPointF(0,0);  //移到坐标原点,配合rotate实现自转。
        painter.drawEllipse(P,maxSize,maxSize);
        painter.drawRect(P.x()-(maxSize+4)/2,P.y()-(maxSize+4)/2,maxSize+4,maxSize+4);
        painter.drawText(P.x()-(maxSize+4)/2,P.y()-(maxSize+4)/2,maxSize+4,maxSize+4,Qt::AlignCenter,QString::number(index));
    }
    else
    {
        painter.setPen(Qt::red);
        painter.setBrush(QBrush(QColor(255,255,255,50)));
        QPointF P = QPointF(0,0); //移到坐标原点,配合rotate实现自转。
        painter.drawEllipse(P,NoalmalSize,NoalmalSize);
        painter.drawRect(P.x()-(NoalmalSize+4)/2,P.y()-(NoalmalSize+4)/2,NoalmalSize+4,NoalmalSize+4);
    }
    painter.restore();
}

请添加图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方忘忧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值