├── .gitignore
├── README.md
└── RadarPPI
├── .gitignore
├── RadarPPI.vcxproj
├── RadarPPI.vcxproj.filters
├── RadarPPI.vcxproj.user
├── Resource.qrc
├── Resource
├── background.png
├── dot.png
└── scan.png
├── VGRadarPPIViewer.cpp
├── VGRadarPPIViewer.h
├── VGRadarPPIViewer.ui
├── icon.ico
├── icon.rc
├── main.cpp
├── qcustomplot.cpp
├── qcustomplot.h
├── vgradarppi.cpp
├── vgradarppi.h
└── 资源
├── 示例.png
├── 示例2.png
├── 示例3.png
├── 背景图源文件-雷达抽象绿色光圈.zip
└── 雷达PPI显示效果3.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RadarPPI
2 | 使用Qt+QCustomPlot实现的动态雷达PPI显示(P显)...
3 |
4 | ## 动态预览效果
5 | 
6 |
7 | ## 预览效果-1
8 | 
9 |
10 | ## 预览效果-2
11 | 
12 |
--------------------------------------------------------------------------------
/RadarPPI/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
--------------------------------------------------------------------------------
/RadarPPI/RadarPPI.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | {A6B22D0B-FFE0-4EFE-9723-A77239DB2785}
43 | QtVS_v302
44 | 8.1
45 | $(MSBuildProjectDirectory)\QtMsBuild
46 |
47 |
48 |
49 | Application
50 | v140
51 | MultiByte
52 |
53 |
54 | Application
55 | v140
56 | MultiByte
57 |
58 |
59 | Application
60 | v140
61 | MultiByte
62 |
63 |
64 | Application
65 | v140
66 | MultiByte
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | $(SolutionDir).temp\$(ProjectName)\Link\$(PlatformTarget)\$(Configuration)\
89 | $(SolutionDir).temp\$(ProjectName)\Compile\$(PlatformTarget)\$(Configuration)\
90 | $(ProjectName)d
91 |
92 |
93 | $(SolutionDir).temp\$(ProjectName)\Link\$(PlatformTarget)\$(Configuration)\
94 | $(SolutionDir).temp\$(ProjectName)\Compile\$(PlatformTarget)\$(Configuration)\
95 |
96 |
97 | $(SolutionDir).temp\$(ProjectName)\Link\$(PlatformTarget)\$(Configuration)\
98 | $(SolutionDir).temp\$(ProjectName)\Compile\$(PlatformTarget)\$(Configuration)\
99 | $(ProjectName)d
100 |
101 |
102 | $(SolutionDir).temp\$(ProjectName)\Link\$(PlatformTarget)\$(Configuration)\
103 | $(SolutionDir).temp\$(ProjectName)\Compile\$(PlatformTarget)\$(Configuration)\
104 |
105 |
106 |
107 |
108 |
109 | Qt5.12.10(VS2017-x64)
110 | core;gui;widgets;sql
111 |
112 |
113 | msvc2017
114 | core;gui;widgets
115 |
116 |
117 | Qt5.12.10(VS2017-x64)
118 | core;gui;widgets;sql;webenginewidgets;axcontainer
119 |
120 |
121 | msvc2017
122 | core;gui;widgets
123 |
124 |
125 |
126 |
127 |
128 |
129 | true
130 | Disabled
131 | ProgramDatabase
132 | MultiThreadedDebugDLL
133 | true
134 | $(SolutionDir)include;$(SolutionDir)include\$(ProjectName);$(SolutionDir)3rdParty\OSG\include;D:\OSG\osg3.6.5\include;D:\QT\5.12.10\msvc2015_64\include\QtSql;.\;%(AdditionalIncludeDirectories)
135 |
136 |
137 | Console
138 | $(TargetPath)
139 | true
140 | D:\QT\5.12.10\msvc2015_64\lib\cmake\Qt5Sql;D:\OSG\osg3.6.5\lib;$(SolutionDir)lib\$(PlatformTarget)\$(Configuration);$(SolutionDir)lib\$(PlatformTarget);$(SolutionDir)3rdParty\OSG\lib\$(PlatformTarget)\$(Configuration);%(AdditionalLibraryDirectories)
141 |
142 |
143 | echo D | xcopy "$(TargetPath)" "$(SolutionDir)bin_$(PlatformTarget)_$(Configuration)\" /y
144 |
145 |
146 |
147 |
148 | true
149 | Disabled
150 | ProgramDatabase
151 | MultiThreadedDebugDLL
152 | true
153 | $(SolutionDir)include;$(SolutionDir)include\$(ProjectName);$(SolutionDir)3rdParty\OSG\include;.\;%(AdditionalIncludeDirectories)
154 |
155 |
156 | Windows
157 | $(TargetPath)
158 | true
159 | $(SolutionDir)lib\$(PlatformTarget)\$(Configuration);$(SolutionDir)lib\$(PlatformTarget);$(SolutionDir)3rdParty\OSG\lib\$(PlatformTarget)\$(Configuration);%(AdditionalLibraryDirectories)
160 |
161 |
162 | echo D | xcopy "$(TargetPath)" "$(SolutionDir)bin_$(PlatformTarget)_$(Configuration)\" /y
163 |
164 |
165 |
166 |
167 | true
168 | ProgramDatabase
169 | MultiThreadedDLL
170 | true
171 | D:\github\src\VGScenarioEditorV2.0\include;$(VG_DEV_LIBS)\OSG\include;$(SolutionDir)include;$(SolutionDir)include\$(ProjectName);$(VG_DEV_LIBS)\grpc\include;$(VG_DEV_LIBS)\OSG\include;$(VG_DEV_LIBS)\GDAL\include;$(VG_DEV_LIBS)\boost\include;$(VG_DEV_LIBS)\python3\include\python3.9;$(SolutionDir)include/util;$(SolutionDir)include/common;$(SolutionDir)include/sim;$(SolutionDir)include/database;$(SolutionDir)include/ai;$(SolutionDir)include/scriptinterface;$(SolutionDir)include;$(SolutionDir)WarfareRPC;.\;%(AdditionalIncludeDirectories)
172 | UNICODE;_UNICODE;WIN32;%(PreprocessorDefinitions)
173 | Disabled
174 |
175 |
176 |
177 |
178 | Console
179 | $(TargetPath)
180 | Debug
181 | D:\github\src\VGScenarioEditorV2.0\lib\x64;$(VG_DEV_LIBS)\OSG\lib\$(PlatformTarget)\$(Configuration);$(SolutionDir)lib\$(PlatformTarget)\$(Configuration);$(SolutionDir)lib\$(PlatformTarget);$(VG_DEV_LIBS)\python3\lib;$(VG_DEV_LIBS)\boost\lib;$(VG_DEV_LIBS)\GDAL\lib\$(PlatformTarget)\;$(VG_DEV_LIBS)\grpc\lib\$(PlatformTarget)\;%(AdditionalLibraryDirectories)
182 | %(AdditionalDependencies)
183 |
184 |
185 | echo D | xcopy "$(TargetPath)" "$(SolutionDir)bin_$(PlatformTarget)_$(Configuration)\" /y
186 |
187 |
188 |
189 |
190 | true
191 |
192 |
193 | MultiThreadedDLL
194 | true
195 | $(SolutionDir)include;$(SolutionDir)include\$(ProjectName);$(SolutionDir)3rdParty\OSG\include;.\;%(AdditionalIncludeDirectories)
196 |
197 |
198 | Windows
199 | $(TargetPath)
200 | false
201 | $(SolutionDir)lib\$(PlatformTarget)\$(Configuration);$(SolutionDir)lib\$(PlatformTarget);$(SolutionDir)3rdParty\OSG\lib\$(PlatformTarget)\$(Configuration);%(AdditionalLibraryDirectories)
202 |
203 |
204 | echo D | xcopy "$(TargetPath)" "$(SolutionDir)bin_$(PlatformTarget)_$(Configuration)\" /y
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
--------------------------------------------------------------------------------
/RadarPPI/RadarPPI.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}
14 | qrc;*
15 | false
16 |
17 |
18 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3}
19 | ui
20 |
21 |
22 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}
23 | qrc;*
24 | false
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Source Files
36 |
37 |
38 | Source Files
39 |
40 |
41 | Source Files
42 |
43 |
44 |
45 |
46 | Resource Files
47 |
48 |
49 |
50 |
51 | Header Files
52 |
53 |
54 | Header Files
55 |
56 |
57 |
--------------------------------------------------------------------------------
/RadarPPI/RadarPPI.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(SolutionDir)bin_$(PlatformTarget)_$(Configuration)\$(TargetFileName)
5 | $(SolutionDir)bin_$(PlatformTarget)_$(Configuration)
6 | WindowsLocalDebugger
7 |
8 |
9 | $(SolutionDir)bin_$(PlatformTarget)_$(Configuration)\$(TargetFileName)
10 | $(SolutionDir)bin_$(PlatformTarget)_$(Configuration)
11 | WindowsLocalDebugger
12 | PATH=%PATH%;D:/OSG/osg3.6.5/bin_x64_Debug;$(QtDllPath) $(LocalDebuggerEnvironment)
13 |
14 |
15 | $(SolutionDir)bin_$(PlatformTarget)_$(Configuration)\$(TargetFileName)
16 | $(SolutionDir)bin_$(PlatformTarget)_$(Configuration)
17 | WindowsLocalDebugger
18 |
19 |
20 | $(SolutionDir)bin_$(PlatformTarget)_$(Configuration)\$(TargetFileName)
21 | $(SolutionDir)bin_$(PlatformTarget)_$(Configuration)
22 | WindowsLocalDebugger
23 | PATH=$(VG_DEV_LIBS)bin_x64_Release%3b%PATH% $(LocalDebuggerEnvironment)
24 |
25 |
26 | 2022-11-21T04:17:32.5770636Z
27 |
28 |
29 | 2022-11-21T02:18:11.9319895Z
30 |
31 |
--------------------------------------------------------------------------------
/RadarPPI/Resource.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | Resource/background.png
4 | Resource/dot.png
5 | Resource/scan.png
6 |
7 |
8 |
--------------------------------------------------------------------------------
/RadarPPI/Resource/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/Resource/background.png
--------------------------------------------------------------------------------
/RadarPPI/Resource/dot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/Resource/dot.png
--------------------------------------------------------------------------------
/RadarPPI/Resource/scan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/Resource/scan.png
--------------------------------------------------------------------------------
/RadarPPI/VGRadarPPIViewer.cpp:
--------------------------------------------------------------------------------
1 | #include "VGRadarPPIViewer.h"
2 | #include "ui_VGRadarPPIViewer.h"
3 |
4 | #include "QTime"
5 | #include "QTimer"
6 | #include "QFileDialog"
7 |
8 | #include "QFile"
9 | #include "QTextStream"
10 |
11 | namespace RadarPPI {
12 |
13 | FrameDataVector loadPPIData(const QString& path)
14 | {
15 | FrameDataVector frames;
16 |
17 | QFile file(path);
18 | if (!file.open(QIODevice::ReadOnly | QFile::Text)) return frames;
19 |
20 | QTextStream s(&file);
21 | while (!s.atEnd())
22 | {
23 | auto values = s.readLine().simplified().trimmed().split(" ", QString::SkipEmptyParts);
24 | if (values.empty()) continue;
25 |
26 | Targets targets;
27 | auto n = values.size() / 2;
28 | for (auto i = 0; i < n; ++i)
29 | {
30 | auto r = values[i * 2].toDouble();
31 | auto t = values[i * 2 + 1].toDouble() * 3.1415926 / 180.0;
32 |
33 | if (r >= 0.0)
34 | {
35 | targets.push_back(Target{ r * cos(t), r * sin(t) });
36 | }
37 | }
38 |
39 | frames.push_back(targets);
40 | }
41 |
42 | file.close();
43 | return frames;
44 | }
45 | };
46 |
47 |
48 | VGRadarPPIViewer::VGRadarPPIViewer(QWidget *parent)
49 | : QWidget(parent)
50 | {
51 | ui = new Ui::VGRadarPPIViewer();
52 | ui->setupUi(this);
53 |
54 | ui->widget->setColor(QColor("#00ffb2"));
55 |
56 | qsrand(QTime::currentTime().msecsSinceStartOfDay());
57 | auto timer = new QTimer(this);
58 | connect(timer, &QTimer::timeout, [&, this]() {
59 | if (_data.empty())
60 | {
61 | static int counter = 0;
62 |
63 | //if (counter++ % 2 == 0)
64 | //{
65 | // static int idx = 0;
66 | static QVector clrs{ QColor("#ff6666") ,QColor("#2aff36"), QColor("#ddff21"),QColor("#ffa621"),QColor("#0061ff"),QColor("#00ffb2") };
67 | // ui->widget->setColor(clrs[idx++ % clrs.size()]); // ²âÊÔÑÕÉ«±ä»¯
68 | //}
69 |
70 | const auto range = ui->doubleSpinBoxRange->value() * 1000.0;
71 |
72 | QVector x, y;
73 | for (int i = 0; i < qrand() % 30; i += 1)
74 | {
75 | x.push_back(((qrand() % 2000 - 1000) / 1000.0) * range * 0.7);
76 | y.push_back(((qrand() % 2000 - 1000) / 1000.0) * range * 0.7);
77 | }
78 | ui->widget->addData(x, y);
79 | }
80 | else
81 | {
82 | _idx++;
83 | _idx %= _data.size();
84 |
85 | auto dd = _data[_idx];
86 |
87 | QVector x, y;
88 | for (auto& d : dd)
89 | {
90 | x.push_back(d.x());
91 | y.push_back(d.y());
92 | }
93 | ui->widget->addData(x, y);
94 | }
95 | });
96 | timer->start(1000);
97 |
98 | connect(ui->pushButton, &QPushButton::clicked, [=]() {
99 | auto path = QFileDialog::getOpenFileName(this, "PPI Data", " ");
100 |
101 | if (path.isEmpty()) return;
102 |
103 | _data = RadarPPI::loadPPIData(path);
104 | _idx = 0u;
105 |
106 | if (!_data.empty())
107 | {
108 | ui->widget->setData({}, {});
109 | }
110 | });
111 |
112 | auto handler = [=]() {
113 | ui->widget->setRange(ui->doubleSpinBoxRange->value() * 1000.0);
114 | ui->widget->setSpeed(360.0 / ui->doubleSpinBoxT->value());
115 | };
116 |
117 | connect(ui->doubleSpinBoxRange, QOverload::of(&QDoubleSpinBox::valueChanged), handler);
118 | connect(ui->doubleSpinBoxT, QOverload::of(&QDoubleSpinBox::valueChanged), handler);
119 |
120 | connect(ui->doubleSpinBoxTheta, QOverload::of(&QDoubleSpinBox::valueChanged), [=]() {
121 | ui->widget->stop();
122 | ui->widget->setData({}, {});
123 | ui->widget->setTheta(-ui->doubleSpinBoxTheta->value() + 90.0);
124 | ui->widget->start();
125 | });
126 |
127 | QTimer::singleShot(1000, handler);
128 | }
129 |
130 | VGRadarPPIViewer::~VGRadarPPIViewer()
131 | {
132 | delete ui;
133 | }
--------------------------------------------------------------------------------
/RadarPPI/VGRadarPPIViewer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | namespace Ui { class VGRadarPPIViewer; };
5 |
6 | #include "QPointF"
7 | #include "QVector"
8 |
9 | using Target = QPointF; // 目标点
10 | using Targets = QVector; // 目标列表
11 | using FrameDataVector = QVector; // 所有时刻数据
12 |
13 | class VGRadarPPIViewer : public QWidget
14 | {
15 | Q_OBJECT
16 | public:
17 | VGRadarPPIViewer(QWidget *parent = Q_NULLPTR);
18 | ~VGRadarPPIViewer();
19 |
20 | private:
21 | Ui::VGRadarPPIViewer *ui;
22 |
23 | FrameDataVector _data;
24 | unsigned _idx{ 0u };
25 | };
--------------------------------------------------------------------------------
/RadarPPI/VGRadarPPIViewer.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | VGRadarPPIViewer
4 |
5 |
6 |
7 | 0
8 | 0
9 | 562
10 | 528
11 |
12 |
13 |
14 | VGRadarPPIViewer
15 |
16 |
17 |
18 | 2
19 |
20 |
21 | 2
22 |
23 |
24 | 2
25 |
26 |
27 | 2
28 |
29 |
30 | 2
31 |
32 | -
33 |
34 |
-
35 |
36 |
37 | 加载数据
38 |
39 |
40 |
41 | -
42 |
43 |
44 | 范围
45 |
46 |
47 |
48 | -
49 |
50 |
51 | 公里
52 |
53 |
54 | 0
55 |
56 |
57 | 1.000000000000000
58 |
59 |
60 | 99999999.000000000000000
61 |
62 |
63 | 100.000000000000000
64 |
65 |
66 |
67 | -
68 |
69 |
70 | 扫描周期
71 |
72 |
73 |
74 | -
75 |
76 |
77 | 秒
78 |
79 |
80 | 0.010000000000000
81 |
82 |
83 | 999999.000000000000000
84 |
85 |
86 | 60.000000000000000
87 |
88 |
89 |
90 | -
91 |
92 |
93 | 初始方位
94 |
95 |
96 |
97 | -
98 |
99 |
100 | 度
101 |
102 |
103 | 0.000000000000000
104 |
105 |
106 | 360.000000000000000
107 |
108 |
109 | 0.000000000000000
110 |
111 |
112 |
113 | -
114 |
115 |
116 | Qt::Horizontal
117 |
118 |
119 |
120 | 40
121 | 20
122 |
123 |
124 |
125 |
126 |
127 |
128 | -
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 | VGRadarPPI
137 | QWidget
138 |
139 | 1
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/RadarPPI/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/icon.ico
--------------------------------------------------------------------------------
/RadarPPI/icon.rc:
--------------------------------------------------------------------------------
1 | IDI_ICON1 ICON DISCARDABLE "icon.ico"
2 |
3 |
--------------------------------------------------------------------------------
/RadarPPI/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "VGRadarPPIViewer.h"
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | QApplication a(argc, argv);
7 |
8 | VGRadarPPIViewer p;
9 | p.setWindowTitle(QString::fromLocal8Bit("雷达PPI显示效果"));
10 | p.show();
11 |
12 | return a.exec();
13 | }
--------------------------------------------------------------------------------
/RadarPPI/vgradarppi.cpp:
--------------------------------------------------------------------------------
1 | #include "vgradarppi.h"
2 | #include "QPainter"
3 | #include "QEvent"
4 |
5 | struct VGRadarPPIPrivate
6 | {
7 | VGRadarPPIPrivate()
8 | {
9 | dot = QPixmap(":/Resource/dot.png").scaledToWidth(12, Qt::SmoothTransformation);
10 | }
11 |
12 | inline QPixmap convertToColor(const QPixmap& background, const QColor& color)
13 | {
14 | auto b = background.toImage();
15 | auto ba = b.alphaChannel();
16 | b.fill(color);
17 | b.setAlphaChannel(ba);
18 | return QPixmap::fromImage(b);
19 | }
20 |
21 | inline void setColor(const QColor& color)
22 | {
23 | background = convertToColor(background, color);
24 | scan = convertToColor(scan, color);
25 | dot = convertToColor(dot, color);
26 | }
27 |
28 | QCPGraph* graph{ nullptr };
29 | qreal speed{ 6.0 }; // 扫描角速度,默认120°/s
30 | qreal range_m{ 10000.0 }; // 范围
31 |
32 | QPixmap background{ ":/Resource/background.png" };
33 | QPixmap scan{ ":/Resource/scan.png" };
34 | QPixmap dot;
35 |
36 | qreal angle{ 90.0 };
37 | QElapsedTimer timer;
38 |
39 | qint32 timerID{ -1 };
40 | };
41 |
42 | VGRadarPPI::VGRadarPPI(QWidget *parent)
43 | : QCustomPlot(parent)
44 | , _(new VGRadarPPIPrivate)
45 | {
46 | resize(600, 600);
47 |
48 | setBackground(_->background); //设置背景为透明色
49 |
50 | setBackgroundScaledMode(Qt::IgnoreAspectRatio);
51 |
52 | setBackground(QColor(0, 0, 0, 255)); //设置默认背景为黑色
53 |
54 | _->graph = addGraph();
55 | _->graph->setLineStyle(QCPGraph::lsNone);
56 |
57 | QCPScatterStyle style(QCPScatterStyle::ssPixmap, 1.0);
58 | style.setPixmap(QPixmap(":/Resource/dot.png").scaledToWidth(8, Qt::SmoothTransformation));
59 | _->graph->setScatterStyle(style);
60 |
61 | xAxis2->setVisible(false); // 顶部坐标轴
62 | xAxis->setVisible(false); // 底部坐标轴
63 | yAxis->setVisible(false); // 左边坐标轴
64 | yAxis2->setVisible(false); // 右边坐标轴
65 |
66 | setRange(10e3); // 10km
67 |
68 | start();
69 | }
70 |
71 | VGRadarPPI::~VGRadarPPI()
72 | {
73 | delete _;
74 | _ = Q_NULLPTR;
75 | }
76 |
77 | void VGRadarPPI::setData(const DataVector& x, const DataVector& y)
78 | {
79 | Q_ASSERT(x.size() == y.size());
80 |
81 | DataVector xx, yy;
82 | for (auto i = 0; i < x.size(); ++i)
83 | {
84 | auto r = sqrt(x[i] * x[i] + y[i] * y[i]);
85 | if (r > _->range_m * 0.8)
86 | continue;
87 |
88 | xx.push_back(x[i]);
89 | yy.push_back(y[i]);
90 | }
91 |
92 | _->graph->setData(xx, yy);
93 | replot(QCustomPlot::rpQueuedReplot);
94 | }
95 |
96 | void VGRadarPPI::addData(const DataVector& x, const DataVector& y)
97 | {
98 | Q_ASSERT(x.size() == y.size());
99 |
100 | DataVector xx, yy;
101 | for (auto i = 0; i < x.size(); ++i)
102 | {
103 | auto r = sqrt(x[i] * x[i] + y[i] * y[i]);
104 | if (r > _->range_m * 0.8)
105 | continue;
106 |
107 | xx.push_back(x[i]);
108 | yy.push_back(y[i]);
109 | }
110 | _->graph->addData(xx, yy);
111 | replot(QCustomPlot::rpQueuedReplot);
112 | }
113 |
114 | void VGRadarPPI::setRange(qreal range_m)
115 | {
116 | _->range_m = range_m;
117 | xAxis->setRange(-range_m, range_m);
118 | yAxis->setRange(-range_m, range_m);
119 | replot(QCustomPlot::rpQueuedReplot);
120 | }
121 |
122 | void VGRadarPPI::setTheta(qreal theta)
123 | {
124 | _->angle = theta;
125 | }
126 |
127 | void VGRadarPPI::setSpeed(qreal speed_deg_s)
128 | {
129 | _->speed = speed_deg_s;
130 | }
131 |
132 | void VGRadarPPI::start()
133 | {
134 | if (_->timerID == -1)
135 | {
136 | _->timerID = startTimer(20);
137 | _->timer.restart();
138 | }
139 | }
140 |
141 | void VGRadarPPI::pause()
142 | {
143 | if (_->timerID == -1)return;
144 |
145 | killTimer(_->timerID);
146 | _->timerID = -1;
147 | }
148 |
149 | void VGRadarPPI::stop()
150 | {
151 | if (_->timerID == -1)return;
152 |
153 | killTimer(_->timerID);
154 | _->timerID = -1;
155 |
156 | _->angle = -90.0;
157 | }
158 |
159 | void VGRadarPPI::setColor(const QColor& color)
160 | {
161 | _->setColor(color);
162 |
163 | setBackground(_->background); //设置背景为透明色
164 |
165 | QCPScatterStyle style(QCPScatterStyle::ssPixmap, 1.0);
166 | style.setPixmap(_->dot);
167 | _->graph->setScatterStyle(style);
168 |
169 | repaint();
170 | replot();
171 | }
172 |
173 | qreal VGRadarPPI::getRange() const
174 | {
175 | return _->range_m;
176 | }
177 |
178 | qreal VGRadarPPI::getSpeed() const
179 | {
180 | return _->speed;
181 | }
182 |
183 | void VGRadarPPI::paintEvent(QPaintEvent *event)
184 | {
185 | QCustomPlot::paintEvent(event);
186 |
187 | QPainter p(this);
188 | p.translate(width() / 2, height() / 2);
189 | p.rotate(_->angle);
190 | p.drawPixmap(-width() / 2, -height() / 2, width(), height(), _->scan);
191 |
192 | _->angle -= _->speed * _->timer.elapsed() / 1000.0;
193 |
194 | _->timer.restart();
195 | }
196 |
197 | void VGRadarPPI::timerEvent(QTimerEvent *event)
198 | {
199 | repaint();
200 | }
--------------------------------------------------------------------------------
/RadarPPI/vgradarppi.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "QCustomPlot.h"
4 |
5 | struct VGRadarPPIPrivate;
6 |
7 | /**
8 | * 雷达PPI显示
9 | */
10 | class VGRadarPPI : public QCustomPlot
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | using DataVector = QVector;
16 |
17 | VGRadarPPI(QWidget *parent = Q_NULLPTR);
18 |
19 | ~VGRadarPPI();
20 |
21 | /**
22 | * 替换更新数据,直角坐标
23 | */
24 | void setData(const DataVector& x, const DataVector& y);
25 |
26 | /**
27 | * 追加更新数据,直角坐标
28 | */
29 | void addData(const DataVector& x, const DataVector& y);
30 |
31 | /**
32 | * 设置颜色
33 | */
34 | void setColor(const QColor& color);
35 |
36 | /**
37 | * 查询P显范围(m)
38 | */
39 | qreal getRange() const;
40 |
41 | /**
42 | * 查询P显扫描角速度(°/s)
43 | */
44 | qreal getSpeed() const;
45 |
46 | public Q_SLOTS:
47 | /**
48 | * 设置P显范围(m)
49 | */
50 | void setRange(qreal range_m);
51 |
52 | /**
53 | * 设置P显当前扫描角度
54 | */
55 | void setTheta(qreal theta);
56 |
57 | /**
58 | * 设置扫描角速度(°/s)
59 | */
60 | void setSpeed(qreal speed_deg_s);
61 |
62 | /**
63 | * 开始扫描
64 | */
65 | void start();
66 |
67 | /**
68 | * 暂停扫描
69 | */
70 | void pause();
71 |
72 | /**
73 | * 停止扫描
74 | */
75 | void stop();
76 |
77 | protected:
78 | void paintEvent(QPaintEvent *event) override;
79 |
80 | void timerEvent(QTimerEvent *event) override;
81 |
82 | private:
83 | VGRadarPPIPrivate *_{ Q_NULLPTR };
84 | };
--------------------------------------------------------------------------------
/RadarPPI/资源/示例.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/资源/示例.png
--------------------------------------------------------------------------------
/RadarPPI/资源/示例2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/资源/示例2.png
--------------------------------------------------------------------------------
/RadarPPI/资源/示例3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/资源/示例3.png
--------------------------------------------------------------------------------
/RadarPPI/资源/背景图源文件-雷达抽象绿色光圈.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/资源/背景图源文件-雷达抽象绿色光圈.zip
--------------------------------------------------------------------------------
/RadarPPI/资源/雷达PPI显示效果3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnibuoz/RadarPPI/ccc5ce4c888aff7d6d705bf8a9abb55a8b8b597f/RadarPPI/资源/雷达PPI显示效果3.gif
--------------------------------------------------------------------------------