import 'dart:developer' as dev; // import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:scence_map/controllers/controller.dart'; import 'package:scence_map/controllers/plum_controller.dart'; import 'view.dart'; ScenceMapController mapController = Get.find(); class DrawDirection extends CustomPainter { PlumDataController controller; Offset pos; bool isDarkMode; bool isInit; DrawDirection(this.controller, this.pos, this.isDarkMode, this.isInit); @override void paint(Canvas canvas, Size size) { controller.canvasSize = size; final paint = Paint(); Path path = Path(); paint ..strokeWidth = 2 ..style = PaintingStyle.stroke ..color = isDarkMode ? Colors.white : Colors.black; if (controller.linePointOffset.value == Offset.zero || controller.centerXY.value == Offset.zero || controller.checkValue.value == "checkPile") { return; } Offset linePointOffset = mapController.xy2Screen( controller.linePointXY.value.dx, controller.linePointXY.value.dy); Offset centerOffset = controller.centerOffset.value; Offset centerXY = controller.centerXY.value; if (isInit) { linePointOffset = linePointOffset + pos; centerOffset = controller.centerOffset.value + pos; } dev.log("-----矩阵中心$centerOffset,$centerXY"); path.moveTo(centerOffset.dx, centerOffset.dy); path.lineTo(linePointOffset.dx, linePointOffset.dy); canvas.drawPath(path, paint); paint.style = PaintingStyle.fill; // double deLength = 100; // double angle = atan2((linePointOffset.dy - centerOffset.dy), // (linePointOffset.dx - centerOffset.dx)); // // dev.log("-----角度$angle,${controller.angle.value}"); // canvas.drawCircle(linePointOffset, 10, paint); // var dx1 = (deLength * cos(angle + pi / 2)) + centerOffset.dx; // var dy1 = (deLength) * sin(angle + pi / 2) + centerOffset.dy; // canvas.drawCircle(Offset(dx1, dy1), 10, paint); // dx1 = (deLength * cos(angle + pi)) + centerOffset.dx; // dy1 = (deLength) * sin(angle + pi) + centerOffset.dy; // canvas.drawCircle(Offset(dx1, dy1), 10, paint); // dx1 = (deLength * cos(angle + pi / 2 * 3)) + centerOffset.dx; // dy1 = (deLength) * sin(angle + pi / 2 * 3) + centerOffset.dy; // canvas.drawCircle(Offset(dx1, dy1), 10, paint); paint // ..color = Colors.grey.withOpacity(.4) .style = PaintingStyle.stroke; if (controller.isUp.value && controller.angle.value != 0) { List rect = getRect(controller.distancesOffset); List outRect = getOutRect(rect, centerOffset, linePointOffset); double unit = controller.space / mapController.pixel2MeterRatio; paint.color = Colors.grey; canvas.drawLine(rect[0], rect[1], paint); // 绘制上边 canvas.drawLine(rect[1], rect[2], paint); // 绘制右边 canvas.drawLine(rect[2], rect[3], paint); // 绘制下边 canvas.drawLine(rect[3], rect[0], paint); // 绘制左边 // 沿着路径绘制圆圈 double distance = (outRect[2] - outRect[0]).distance; int horizonalCircles = (distance / unit).ceil(); taskcontroller.currentask.value.list.length = 0; List circlePoints = []; paint.color = Colors.yellow; // double minY = rect[0].dy; double maxY = rect[2].dy; double minX = rect[0].dx; double maxX = rect[2].dx; bool centerEven = false; for (int j = -1; j <= horizonalCircles; j++) { double t = j * unit / distance; Offset point = Offset.lerp(centerOffset, linePointOffset, t)!; circlePoints.add(point); if (j > 1) { Offset point1 = Offset.lerp(centerOffset, linePointOffset, -t)!; if (point1.dx >= (minX - unit) && point1.dx <= (maxX + unit) && point1.dy >= (minY - unit) && point1.dy <= (maxY + unit)) { circlePoints.add(point1); if (point1 - centerOffset < Offset(unit, unit)) { centerEven = circlePoints.length % 2 == 0; } } // } } circlePoints.sort((a, b) => a.dx.compareTo(b.dx)); Offset direction = (linePointOffset - centerOffset).scale(1 / distance, 1 / distance); Offset perpendicular = Offset(-direction.dy, direction.dx); controller.plumList.length = 0; // 绘制上下方的圆圈,形成正方形矩阵 for (int p = 0; p <= circlePoints.length - 1; p++) { Offset point = circlePoints[p]; for (int j = 0; j <= horizonalCircles; j++) { Offset upPoint = point + perpendicular * (j * unit); Offset downPoint = point - perpendicular * (j * unit); bool isUpPointInRect = upPoint.dx >= minX && upPoint.dx <= maxX && upPoint.dy >= minY && upPoint.dy <= maxY; bool isDownPointInRect = downPoint.dx >= minX && downPoint.dx <= maxX && downPoint.dy >= minY && downPoint.dy <= maxY; if (controller.isPlum.value) { if ((j % 2 == p % 2) == centerEven) { paint.style = PaintingStyle.fill; } else { paint.style = PaintingStyle.stroke; } if (isDownPointInRect && j > 0) { canvas.drawCircle( downPoint, .3 / mapController.pixel2MeterRatio, paint); if ((j % 2 == p % 2) == centerEven) { Offset xy1 = mapController.screen2xy0(downPoint); controller.plumList.add(xy1); } } if (isUpPointInRect) { canvas.drawCircle( upPoint, .3 / mapController.pixel2MeterRatio, paint); if ((j % 2 == p % 2) != centerEven) { Offset xy = mapController.screen2xy0(upPoint); controller.plumList.add(xy); } } continue; } if (isUpPointInRect) { // TextPainter textPainter = TextPainter( // text: TextSpan( // text: '$p,$j', // style: TextStyle(color: Colors.blue, fontSize: 16)), // textDirection: TextDirection.ltr, // ); // textPainter.layout(); // textPainter.paint(canvas, upPoint); canvas.drawCircle( upPoint, .3 / mapController.pixel2MeterRatio, paint); Offset xy = mapController.screen2xy0(upPoint); controller.plumList.add(xy); } if (isDownPointInRect && j > 0) { // TextPainter textPainter = TextPainter( // text: TextSpan( // text: '$p,$j', // style: TextStyle(color: Colors.blue, fontSize: 16)), // textDirection: TextDirection.ltr, // ); // textPainter.layout(); // textPainter.paint(canvas, downPoint); canvas.drawCircle( downPoint, .3 / mapController.pixel2MeterRatio, paint); Offset xy1 = mapController.screen2xy0(downPoint); controller.plumList.add(xy1); } } } dev.log("controller.plumList:${controller.plumList.length}"); } } getRect(List list) { if (list.isEmpty) { return [Offset.zero, Offset.zero, Offset.zero, Offset.zero]; } List rect = []; double minx = double.infinity; double maxx = double.negativeInfinity; double miny = double.infinity; double maxy = double.negativeInfinity; for (var point in list) { minx = point.dx < minx ? point.dx : minx; maxx = point.dx > maxx ? point.dx : maxx; miny = point.dy < miny ? point.dy : miny; maxy = point.dy > maxy ? point.dy : maxy; } minx += controller.transOff.dx; maxx += controller.transOff.dx; miny += controller.transOff.dy; maxy += controller.transOff.dy; // 根据最小最大坐标生成矩形的四个顶点 rect.add(Offset(minx, miny)); // 左下角 rect.add(Offset(maxx, miny)); // 右下角 rect.add(Offset(maxx, maxy)); // 右上角 rect.add(Offset(minx, maxy)); // 左上角 return rect; } getOutRect(List rect, Offset centerOffset, Offset linePointOffset) { // double height = rect[2].dy - rect[0].dy; // double width = rect[1].dx - rect[0].dx; double newHeight = (centerOffset.dy - linePointOffset.dy) * 2; double newWidth = (centerOffset.dx - linePointOffset.dx) * 2; // if (newHeight < height) { // newHeight = height; // } // if (newWidth < width) { // newWidth = width; // } Offset topLeft = Offset(centerOffset.dx - newWidth / 2, centerOffset.dy - newHeight / 2); Offset topRight = Offset(centerOffset.dx + newWidth / 2, centerOffset.dy - newHeight / 2); Offset bottomLeft = Offset(centerOffset.dx - newWidth / 2, centerOffset.dy + newHeight / 2); Offset bottomRight = Offset(centerOffset.dx + newWidth / 2, centerOffset.dy + newHeight / 2); return [ bottomLeft, bottomRight, topRight, topLeft, ]; } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => true; }