location.dart 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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/application.dart';
  9. import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
  10. import 'package:fis_measure/process/calcuators/velocity.dart';
  11. import 'package:fis_measure/process/visual/tissue_area.dart';
  12. import 'package:fis_measure/utils/canvas.dart';
  13. import 'package:get/get.dart';
  14. import 'package:vid/us/vid_us_mode.dart';
  15. import '../calcuators/depth.dart';
  16. import '../items/item.dart';
  17. import '../items/item_feature.dart';
  18. import '../physical_coordinates/convex_tissue.dart';
  19. class Location extends MeasureItem<LocationFeature> {
  20. Location(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);
  21. @override
  22. bool get finishAfterUnactive => false;
  23. @override
  24. bool onExecuteMouse(PointInfo args) {
  25. if (state == ItemStates.finished || state == ItemStates.waiting) {
  26. if (args.pointType == PointInfoType.mouseMove) {
  27. handleMouseMoveWhileFinish(args);
  28. }
  29. }
  30. if (state == ItemStates.running) {
  31. if (args.pointType == PointInfoType.mouseUp) return false;
  32. feature?.point = args;
  33. doCalculate();
  34. if (args.pointType == PointInfoType.mouseDown) {
  35. doFeatureFinish();
  36. }
  37. }
  38. return true;
  39. }
  40. @override
  41. bool onExecuteTouch(PointInfo args) {
  42. if (state == ItemStates.finished || state == ItemStates.waiting) {
  43. if (args.pointType == PointInfoType.touchDown) {
  44. handleMouseMoveWhileFinish(args);
  45. }
  46. }
  47. if (state == ItemStates.running) {
  48. if (args.pointType == PointInfoType.touchDown) {
  49. feature?.point = args;
  50. doCalculate();
  51. }
  52. if (args.pointType == PointInfoType.touchMove) {
  53. args.addOffset(0, -0.2);
  54. if (isMoveTargetOutOfRange(args)) return true;
  55. feature?.point = args;
  56. doCalculate();
  57. }
  58. if (args.pointType == PointInfoType.touchUp) {
  59. doFeatureFinish();
  60. }
  61. }
  62. return true;
  63. }
  64. void handleMouseMoveWhileFinish(PointInfo args) {
  65. // TODO: 判断是否当前 area
  66. // 转换为 Area 逻辑位置
  67. final point = args.toAreaLogicPoint();
  68. handleTissue(args, point);
  69. handleTissueTM(args.hostVisualArea!.mode.modeType, point);
  70. if (args.hostVisualArea != null) {
  71. feature!.hostVisualArea = args.hostVisualArea;
  72. }
  73. state = ItemStates.running;
  74. }
  75. void handleTissueTM(VidUsModeType mode, DPoint point) {
  76. if (mode == VidUsModeType.TissueTM || mode == VidUsModeType.Doppler) {
  77. feature = LocationFeature(this, point);
  78. }
  79. }
  80. void handleTissue(PointInfo args, DPoint point) {
  81. final mode = args.hostVisualArea!.mode.modeType;
  82. if (mode == VidUsModeType.Tissue || mode == VidUsModeType.Flow) {
  83. final isProbeConvex = (args.hostVisualArea! as TissueArea).isConvex;
  84. if (isProbeConvex) {
  85. feature = TissueConvexLocationFeature(this, point);
  86. } else {
  87. feature = LocationFeature(this, point);
  88. }
  89. }
  90. }
  91. static Location createTissueConvexDepth(
  92. ItemMeta meta, [
  93. IMeasureItem? parent,
  94. ]) {
  95. Location location = Location(meta, parent);
  96. location.calculator = TissueConvexDepthCal(location);
  97. return location;
  98. }
  99. static Location createTissueDepth(
  100. ItemMeta meta, [
  101. IMeasureItem? parent,
  102. ]) {
  103. final area = Get.find<IApplication>().currentVisualArea;
  104. final isProbeConvex = (area as TissueArea).isConvex;
  105. final fn =
  106. isProbeConvex ? createTissueConvexDepth : createTissueNormalDepth;
  107. return fn(meta, parent);
  108. }
  109. static Location createTissueNormalDepth(
  110. ItemMeta meta, [
  111. IMeasureItem? parent,
  112. ]) {
  113. Location location = Location(meta, parent);
  114. location.calculator = TissueDepthCal(location);
  115. return location;
  116. }
  117. static Location createTissueTMDepth(
  118. ItemMeta meta, [
  119. IMeasureItem? parent,
  120. ]) {
  121. Location location = Location(meta, parent);
  122. location.calculator = MDepthCal(location);
  123. return location;
  124. }
  125. static Location createVelocity(
  126. ItemMeta meta, [
  127. IMeasureItem? parent,
  128. ]) {
  129. Location location = Location(meta, parent);
  130. location.calculator = VelocityCal(location);
  131. return location;
  132. }
  133. }
  134. class TissueConvexLocationFeature extends LocationFeature {
  135. TissueConvexLocationFeature(IMeasureItem refItem, DPoint point)
  136. : super(refItem, point);
  137. @override
  138. void paint(Canvas canvas, Size size) {
  139. super.paint(canvas, size);
  140. if (!measureData.measureSystemSetting.showDepthGuideline) return;
  141. final point = this.point.clone();
  142. final layout = hostVisualArea!.displayRegion;
  143. point.addOffset(-layout.left, -layout.top);
  144. // TODO : fix bug
  145. final viewport = hostVisualArea!.viewport!;
  146. final physical = (viewport.physical! as ConvexTissuePhysicalCoordinate);
  147. final region = viewport.region;
  148. final physicalZeroPoint =
  149. DPoint(region.width / 2, physical.zeroY); // 真实尺寸圆心
  150. final physicalPoint = viewport.convert(point);
  151. final physicalStartPoint = _findCrossPointOnInnerDiameter(
  152. physicalZeroPoint,
  153. physicalPoint,
  154. physical.zeroRadius,
  155. viewport.region,
  156. );
  157. // 在内圈内,不处理
  158. if (physicalStartPoint == null) return;
  159. final logicStartPoint = viewport.convertBack(physicalStartPoint);
  160. logicStartPoint.addOffset(layout.left, layout.top);
  161. point.addOffset(layout.left, layout.top);
  162. Offset viewStartPoint = convert2ViewPoint(size, logicStartPoint).toOffset();
  163. Offset viewPoint = convert2ViewPoint(size, point).toOffset();
  164. if (viewStartPoint.dy < 0) {
  165. // TODO: 处理起点在画布区间外的情况,区间外不绘制
  166. return;
  167. }
  168. canvas.drawDashLine(viewStartPoint, viewPoint, 1, 10, paintLinePan);
  169. }
  170. /// 找到直线(圆心到当前点)和扇形内圈的交叉点
  171. DPoint? _findCrossPointOnInnerDiameter(
  172. DPoint zero,
  173. DPoint point,
  174. double zeroRadius,
  175. RectRegion region,
  176. ) {
  177. final centerOfX = region.width / 2;
  178. final pointWidthOnX = centerOfX - point.x;
  179. final pointHeightOnY = point.y - zero.y;
  180. final pointRadius =
  181. math.sqrt(math.pow(pointWidthOnX, 2) + math.pow(pointHeightOnY, 2));
  182. final ratio = zeroRadius / pointRadius;
  183. if (ratio > 1) return null;
  184. double width = pointWidthOnX * ratio;
  185. double height = pointHeightOnY * ratio;
  186. double x = centerOfX - width;
  187. double y = height + zero.y;
  188. return DPoint(x, y);
  189. }
  190. }
  191. class LocationFeature extends MeasureItemFeature {
  192. LocationFeature(IMeasureItem refItem, DPoint point) : super(refItem) {
  193. innerPoints.add(point);
  194. }
  195. DPoint get point => innerPoints[0];
  196. set point(DPoint value) => innerPoints[0] = value;
  197. @override
  198. void paint(Canvas canvas, Size size) {
  199. drawId(canvas, size);
  200. final viewPoint = convert2ViewPoint(size, point).toOffset();
  201. drawVertex(canvas, viewPoint, isActive);
  202. }
  203. }