一、前言
雷达模拟仿真工具,整体结构采用的QGraphicsView框架,背景布局采用的分层绘制,这样可以控制该需要重新绘制的重新绘制,不需要重新的绘制的就没必要再多余的浪费,这里定义了一个GraphicsBackGroundItem类继承自QGraphicsItem用于背景图的绘制。
二、雷达模拟仿真工具介绍
雷达模拟仿真工具,主要通过模拟点模拟相关物体,方位、航向角、距离、速度,并且显示相关详情信息可建立跟踪线建立与模拟点联系。可自定义更换模拟点背景达到更加逼真效果,如歼击机,航母发射导弹效果,指挥所被打击爆炸效果。在距离上可自由控制距离缩放,也可建立危险等级制度的区域范围显示,也可激光雷达航向距离控制发射。这过程中会运用到很多数学计算,也有对模拟点组合效果。
三、功能特点
- 设计点由背景,功能按钮,雷达区域,频谱区域,缩放模块,信息点采集模块组成;
- 背景采用分层绘制达到绘制性能的最优化;
- 功能按钮增设了相关雷达功能点;
- 雷达区域为核心模块,包含模拟点各种功能效果,危险等级区域绘制,激光雷达等功能;
- 频谱区域主要显示音频频谱效果;
- 缩放模块控制雷达区域缩放效果;
- 信息采集区域采集雷达区域相关数据信息点数据展示;
- 可支持换肤;
- 可支持音频频谱显示;
- 可支持任意随机添加模拟点;
- 可支持自定义背景添加模拟点;
- 可支持方位,航向角,距离,速度,目标体真实图自定制;
- 可支持危险区域并且可等级划分,方位,角度,距离,危险提示信息等显示;
- 可支持激光发射模拟;
- 支持雷达图放大缩小显示;
- 可支持模拟点编辑设置;
- 可支持模拟点跟踪线设置;
- 可支持模拟点详细数据查看;
- 可支持增加添加目标体预览功能;
- 可支持增加航母目标体;
- 可支持增加歼击机目标体;
- 可支持增加指挥所目标体;
- 可支持增加航母炮弹攻击指挥使效果;
- 可支持增加航母导弹攻击指挥使效果;
- 可支持增加歼击机炮弹攻击指挥使效果;
- 可支持增加歼击机导弹攻击指挥使效果;
- 可支持增加指挥使被炸前,中, 后三种状态效果;
四、核心代码
- 背景表格
int rowgridCount = 6;
int columngridCount = 6;
painter.save();
QPen pen;
QColor tmpColor = AppInstance::getInstance()->foreGroundColor;
tmpColor.setAlpha(150);
pen.setColor(tmpColor);
pen.setCapStyle(Qt::RoundCap);
pen.setWidthF(0.5);
painter.setPen(pen);
QRectF girdRect = rect.adjusted(6, 6, -6, -6);
qreal girdHeight = girdRect.height() * 1.0 / columngridCount;
qreal girdWidth = girdRect.width() * 1.0 / rowgridCount;
for (int row = 0; row <= rowgridCount; row++) {
painter.drawLine(girdRect.x(), girdRect.y() + girdHeight * row, girdRect.x() + girdRect.width(), girdRect.y() + girdHeight * row);
}
for (int column = 0; column <= columngridCount; column++) {
painter.drawLine(girdRect.x() + girdWidth * column, girdRect.y(), girdRect.x() + girdWidth * column, girdRect.y() + girdRect.height());
}
painter.restore();
- 绘制圆弧
painter.save();
painter.setBrush(AppInstance::getInstance()->foreGroundColor);
QPainterPath ellipsePath;
painter.translate(-radius, -radius);
ellipsePath.addEllipse(0, 0, 2 * radius, 2 * radius);
QPainterPath subPath;
int arcWidth = 6;
subPath.addEllipse(arcWidth, arcWidth, 2 * (radius - arcWidth), 2 * (radius - arcWidth));
ellipsePath -= subPath;
painter.drawPath(ellipsePath);
painter.restore();
- 绘制刻度盘
painter.save();
painter.setPen(AppInstance::getInstance()->foreGroundColor);
QFont font = painter.font();
font.setPointSize(12);
font.setWeight(60);
painter.setFont(font);
int scaleMajor = 36;
radius -= 26;
qreal q = 0;
for (int i = 0; i < scaleMajor; i++) {
int value = 1.0 * i * (360 / scaleMajor);
QString strValue = QString("%1").arg(value, 3, 10, QLatin1Char('0'));
painter.save();
painter.rotate(q);
qreal l = painter.fontMetrics().width(strValue) / 2.0;
painter.drawText(QPointF(-l, -radius), strValue);
painter.restore();
q = q + 10;
}
painter.restore();
- 绘制圆弧背景蒙层
int aphpaRadius = radius - 6;
QColor tmpcolor = AppInstance::getInstance()->foreGroundColor;
tmpcolor.setAlpha(10);
painter.save();
painter.setPen(Qt::NoPen);
painter.setBrush(tmpcolor);
painter.translate(-aphpaRadius, -aphpaRadius);
painter.drawEllipse(0, 0, 2 * aphpaRadius, 2 * aphpaRadius);
painter.restore();
- 绘制刻度
int scaleMajor = 36;
radius -= 6;
painter.save();
painter.rotate(0);
int subScaleMajor = 10;
int midScaleMajor = subScaleMajor / 2;
int steps = (scaleMajor * subScaleMajor);
double angleStep = 360.0 / steps;
QPen pen;
pen.setColor(AppInstance::getInstance()->foreGroundColor);
pen.setCapStyle(Qt::RoundCap);
for (int i = 0; i <= steps; i++) {
if (i % subScaleMajor == 0) {
pen.setWidthF(1.5);
painter.setPen(pen);
painter.drawLine(0, radius - 15, 0, radius);
if (i % (subScaleMajor * 9) == 0) {
pen.setWidthF(2.0);
QColor linecolor = AppInstance::getInstance()->foreGroundColor;
linecolor.setAlpha(100);
pen.setColor(linecolor);
painter.setPen(pen);
painter.drawLine(0, radius - lineWidth, 0, radius);
}
}
else if (i % midScaleMajor == 0) {
pen.setWidthF(1.0);
painter.setPen(pen);
painter.drawLine(0, radius - 10, 0, radius);
}
else {
pen.setWidthF(0.5);
painter.setPen(pen);
painter.drawLine(0, radius - 5, 0, radius);
}
painter.rotate(angleStep);
}
painter.restore();