ray.dart 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import 'dart:ui';
  2. import 'dart:math' as math;
  3. import 'package:fis_measure/interfaces/date_types/point.dart';
  4. import 'package:fis_measure/interfaces/date_types/rect_region.dart';
  5. import 'package:fis_measure/interfaces/enums/items.dart';
  6. import 'package:fis_measure/interfaces/process/items/item.dart';
  7. import 'package:fis_measure/interfaces/process/items/item_metas.dart';
  8. import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
  9. import 'package:fis_measure/process/calcuators/ray.dart';
  10. import 'package:fis_measure/process/items/item.dart';
  11. import 'package:fis_measure/process/items/item_feature.dart';
  12. import 'package:fis_measure/utils/canvas.dart';
  13. class Ray extends MeasureItem<RayFeature> {
  14. double _initializeAngle = 0;
  15. double _initializeAngleVal = 0;
  16. bool _switchInitialAngle = false;
  17. Ray(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);
  18. double get initializeAngle => _initializeAngle;
  19. set initializeAngle(double value) {
  20. if (value != _initializeAngle) {
  21. _initializeAngleVal = value;
  22. _updateInitializeAngle();
  23. }
  24. }
  25. bool get switchInitialAngle => _switchInitialAngle;
  26. set switchInitialAngle(bool value) {
  27. if (value != _switchInitialAngle) {
  28. _switchInitialAngle = value;
  29. _updateInitializeAngle();
  30. }
  31. }
  32. @override
  33. bool onExecuteMouse(PointInfo args) {
  34. if (state == ItemStates.finished || state == ItemStates.waiting) {
  35. if (args.pointType == PointInfoType.mouseMove) {
  36. feature = RayFeature(this, args);
  37. feature!.hostVisualArea = args.hostVisualArea;
  38. final viewport = args.hostVisualArea!.viewport!;
  39. feature!.isReverse =
  40. viewport.isFlipHorizontal ^ viewport.isFlipVertical;
  41. state = ItemStates.running;
  42. }
  43. }
  44. if (state == ItemStates.running) {
  45. if (args.pointType == PointInfoType.mouseUp) return false;
  46. feature?.point = args;
  47. doCalculate();
  48. if (args.pointType == PointInfoType.mouseDown) {
  49. doFeatureFinish();
  50. }
  51. }
  52. return true;
  53. }
  54. @override
  55. bool onExecuteTouch(PointInfo args) {
  56. // TODO: implement onExecuteTouch
  57. throw UnimplementedError();
  58. }
  59. static Ray createRay(ItemMeta meta, [IMeasureItem? parent]) {
  60. final ray = Ray(meta, parent);
  61. ray.calculator = RayDepthCal(ray);
  62. return ray;
  63. }
  64. void _updateInitializeAngle() {
  65. int switchNumber = switchInitialAngle ? -1 : 1;
  66. _initializeAngle = _initializeAngleVal * switchNumber;
  67. }
  68. }
  69. class RayFeature extends MeasureItemFeature {
  70. double _angle = 0;
  71. bool _isReverse = false;
  72. RayFeature(Ray refItem, DPoint point) : super(refItem) {
  73. innerPoints.add(point.clone());
  74. angle = refItem.initializeAngle;
  75. }
  76. DPoint get point => innerPoints[0];
  77. set point(DPoint value) {
  78. innerPoints[0] = value;
  79. }
  80. double get angle => _angle;
  81. set angle(double value) {
  82. if (value != _angle) {
  83. _angle = value;
  84. }
  85. }
  86. bool get isReverse => _isReverse;
  87. set isReverse(bool value) {
  88. if (value != _isReverse) {
  89. _isReverse = value;
  90. }
  91. }
  92. RectRegion get viewRegion => hostVisualArea!.viewport!.area.layoutRegion!;
  93. @override
  94. void paint(Canvas canvas, Size size) {
  95. if (innerPoints.isEmpty) return;
  96. final curItemName = refItem.displayName;
  97. final offset = convert2ViewPoint(size, point).toOffset();
  98. final rect = Rect.fromLTWH(
  99. viewRegion.left * size.width,
  100. viewRegion.top * size.height,
  101. viewRegion.width * size.width,
  102. viewRegion.height * size.height);
  103. List<Offset> twoPoint = [const Offset(0, 0), const Offset(0, 0)];
  104. final idText = '$id.${refItem.displayName}';
  105. switch (curItemName) {
  106. case "Baseline":
  107. twoPoint = calcLinePoint(rect, offset, 0);
  108. drawCustomId(canvas, size, twoPoint[1], idText);
  109. break;
  110. case "Line α":
  111. twoPoint = calcLinePoint(rect, offset, angle);
  112. drawCustomId(canvas, size, twoPoint[1], idText);
  113. break;
  114. case "Line β":
  115. twoPoint = calcLinePoint(rect, offset, 180 - angle);
  116. drawCustomId(canvas, size, twoPoint[0], idText);
  117. break;
  118. default:
  119. break;
  120. }
  121. canvas.drawDashLine(twoPoint[0], twoPoint[1], 1, 10, paintLinePan);
  122. }
  123. List<Offset> calcLinePoint(Rect rect, Offset innerPoint, double angle) {
  124. List<Offset> twoPoint = [const Offset(0, 0), const Offset(0, 0)];
  125. if (!rect.contains(innerPoint)) return twoPoint;
  126. final tan = math.tan(angle * math.pi / 180);
  127. final x = innerPoint.dx;
  128. final y = innerPoint.dy;
  129. final d1 = x - y / tan;
  130. twoPoint[0] = Offset(d1, 0);
  131. final d2 = (rect.height - y) / tan + x;
  132. twoPoint[1] = Offset(d2, rect.height);
  133. if (angle <= 90) {
  134. if (d1 < rect.left) {
  135. twoPoint[0] = Offset(rect.left, y - tan * (x - rect.left));
  136. }
  137. if (d2 > rect.right) {
  138. twoPoint[1] = Offset(rect.right, y + tan * (rect.right - x));
  139. }
  140. } else {
  141. if (d1 > rect.right) {
  142. twoPoint[0] = Offset(rect.right, y - tan * (x - rect.right));
  143. }
  144. if (d2 < rect.left) {
  145. twoPoint[1] = Offset(rect.left, y + tan * (rect.left - x));
  146. }
  147. }
  148. return twoPoint;
  149. }
  150. }