import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: SignalCoverage(),
));
}
class SignalCoverage extends StatefulWidget {
@override
_SignalCoverageState createState() => _SignalCoverageState();
}
class _SignalCoverageState extends State<SignalCoverage> {
List<List<double>> signalStrength = [
[0.8, 0.6, 0.4],
[0.7, 0.5, 0.3],
[0.6, 0.4, 0.2],
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('信号覆盖图')),
body: CustomPaint(
painter: SignalCoveragePainter(signalStrength),
size: Size.infinite,
),
);
}
}
class SignalCoveragePainter extends CustomPainter {
final List<List<double>> signalStrength;
SignalCoveragePainter(this.signalStrength);
@override
void paint(Canvas canvas, Size size) {
double cellWidth = size.width / signalStrength[0].length;
double cellHeight = size.height / signalStrength.length;
for (int row = 0; row < signalStrength.length; row++) {
for (int col = 0; col < signalStrength[row].length; col++) {
double strength = signalStrength[row][col];
Color color;
if (strength > 0.6) {
color = Colors.red;
} else if (strength > 0.3) {
color = Colors.yellow;
} else {
color = Colors.blue;
}
Paint paint = Paint()..color = color;
Rect rect = Rect.fromLTWH(
col * cellWidth,
row * cellHeight,
cellWidth,
cellHeight,
);
canvas.drawRect(rect, paint);
}
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
————
import 'package:flutter/material.dart';
import 'dart:math' as math;
class SignalVisualizationPage extends StatefulWidget {
const SignalVisualizationPage({Key? key}) : super(key: key);
@override
State<SignalVisualizationPage> createState() => _SignalVisualizationPageState();
}
class _SignalVisualizationPageState extends State<SignalVisualizationPage> {
// AP 的位置,以画布中心为示例
final Offset apPosition = Offset(200, 200);
// 假设的画布大小
final Size canvasSize = Size(400, 400);
// 网格的数量,用于细分画布
final int gridCount = 20;
// 计算某点的信号强度,简单根据距离计算,距离越远强度越低
double _calculateSignalStrength(Offset point) {
double distance = math.sqrt(math.pow(point.dx - apPosition.dx, 2) +
math.pow(point.dy - apPosition.dy, 2));
// 最大距离,这里取画布对角线长度
double maxDistance = math.sqrt(math.pow(canvasSize.width, 2) +
math.pow(canvasSize.height, 2));
// 将距离映射到 0 - 1 的信号强度范围
return 1 - (distance / maxDistance);
}
// 根据信号强度获取对应的颜色
Color _getColorFromStrength(double strength) {
// 简单的线性插值,将 0 - 1 的强度映射到红 - 黄 - 绿
int red = (255 * (1 - strength)).toInt();
int green = (255 * strength).toInt();
return Color.fromRGBO(red, green, 0, 1);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('吸顶 AP 信号可视化'),
),
body: Center(
child: CustomPaint(
size: canvasSize,
painter: _SignalVisualizationPainter(
apPosition: apPosition,
gridCount: gridCount,
calculateSignalStrength: _calculateSignalStrength,
getColorFromStrength: _getColorFromStrength,
),
),
),
);
}
}
class _SignalVisualizationPainter extends CustomPainter {
final Offset apPosition;
final int gridCount;
final double Function(Offset point) calculateSignalStrength;
final Color Function(double strength) getColorFromStrength;
_SignalVisualizationPainter({
required this.apPosition,
required this.gridCount,
required this.calculateSignalStrength,
required this.getColorFromStrength,
});
@override
void paint(Canvas canvas, Size size) {
// 每个网格的宽度和高度
double cellWidth = size.width / gridCount;
double cellHeight = size.height / gridCount;
for (int i = 0; i < gridCount; i++) {
for (int j = 0; j < gridCount; j++) {
// 计算当前网格的左上角坐标
double x = i * cellWidth;
double y = j * cellHeight;
Rect cellRect = Rect.fromLTWH(x, y, cellWidth, cellHeight);
// 计算当前网格中心的信号强度
Offset center = Offset(x + cellWidth / 2, y + cellHeight / 2);
double strength = calculateSignalStrength(center);
Color color = getColorFromStrength(strength);
// 绘制当前网格
Paint paint = Paint()..color = color;
canvas.drawRect(cellRect, paint);
}
}
// 绘制 AP 的图标,这里简单用一个白色圆形表示
Paint apPaint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
canvas.drawCircle(apPosition, 10, apPaint);
// 绘制代表墙体的线条,这里简单绘制几条示例线条
Paint wallPaint = Paint()
..color = Colors.black
..strokeWidth = 3;
canvas.drawLine(Offset(50, 50), Offset(350, 50), wallPaint);
canvas.drawLine(Offset(350, 50), Offset(350, 350), wallPaint);
canvas.drawLine(Offset(350, 350), Offset(50, 350), wallPaint);
canvas.drawLine(Offset(50, 350), Offset(50, 50), wallPaint);
// 绘制 AP 的文字标注
TextPainter textPainter = TextPainter(
text: TextSpan(
text: '吸顶AP',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
textDirection: TextDirection.ltr,
);
textPainter.layout();
textPainter.paint(canvas, Offset(apPosition.dx - 15, apPosition.dy - 5));
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
import 'package:flutter/material.dart';
import 'dart:math' as math;
class WirelessSignalVisualization extends StatefulWidget {
const WirelessSignalVisualization({Key? key}) : super(key: key);
@override
State<WirelessSignalVisualization> createState() => _WirelessSignalVisualizationState();
}
class _WirelessSignalVisualizationState extends State<WirelessSignalVisualization> {
// 吸顶AP的位置,这里以画布中心为例
Offset apPosition = const Offset(150, 150);
// 画布大小
Size canvasSize = const Size(300, 300);
// 模拟墙体的线条列表,每个元素是一个包含两个Offset的列表,表示线段的两个端点
List<List<Offset>> walls = [
[const Offset(50, 50), const Offset(250, 50)],
[const Offset(250, 50), const Offset(250, 250)],
[const Offset(250, 250), const Offset(50, 250)],
[const Offset(50, 250), const Offset(50, 50)],
];
// 计算某点的信号强度,简化为距离越远强度越低
double _calculateSignalStrength(Offset point) {
double distance = math.sqrt(math.pow(point.dx - apPosition.dx, 2) + math.pow(point.dy - apPosition.dy, 2));
// 最大距离取画布对角线长度
double maxDistance = math.sqrt(math.pow(canvasSize.width, 2) + math.pow(canvasSize.height, 2));
// 将距离映射到0 - 1的信号强度范围
return 1 - (distance / maxDistance);
}
// 根据信号强度获取对应的颜色,从绿色到红色渐变
Color _getColorFromStrength(double strength) {
int red = (255 * (1 - strength)).toInt();
int green = (255 * strength).toInt();
return Color.fromRGBO(red, green, 0, 1);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('室内无线信号覆盖仿真'),
),
body: Center(
child: CustomPaint(
size: canvasSize,
painter: _SignalVisualizationPainter(
apPosition: apPosition,
walls: walls,
calculateSignalStrength: _calculateSignalStrength,
getColorFromStrength: _getColorFromStrength,
),
),
),
);
}
}
class _SignalVisualizationPainter extends CustomPainter {
final Offset apPosition;
final List<List<Offset>> walls;
final double Function(Offset point) calculateSignalStrength;
final Color Function(double strength) getColorFromStrength;
_SignalVisualizationPainter({
required this.apPosition,
required this.walls,
required this.calculateSignalStrength,
required this.getColorFromStrength,
});
@override
void paint(Canvas canvas, Size size) {
// 绘制代表信号强度的区域,将画布划分为小网格来近似模拟
int gridCount = 50;
double cellWidth = size.width / gridCount;
double cellHeight = size.height / gridCount;
for (int i = 0; i < gridCount; i++) {
for (int j = 0; j < gridCount; j++) {
double x = i * cellWidth;
double y = j * cellHeight;
Offset center = Offset(x + cellWidth / 2, y + cellHeight / 2);
double strength = calculateSignalStrength(center);
Color color = getColorFromStrength(strength);
Paint paint = Paint()..color = color;
canvas.drawRect(
Rect.fromLTWH(x, y, cellWidth, cellHeight),
paint,
);
}
}
// 绘制吸顶AP
Paint apPaint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
canvas.drawCircle(apPosition, 10, apPaint);
// 绘制墙体
Paint wallPaint = Paint()
..color = Colors.black
..strokeWidth = 3;
for (var wall in walls) {
canvas.drawLine(wall[0], wall[1], wallPaint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}