import 'dart:ui'; import 'dart:math' as math; import 'package:fis_measure/interfaces/date_types/point.dart'; import 'package:fis_measure/interfaces/date_types/rect_region.dart'; import 'package:fis_measure/interfaces/enums/items.dart'; import 'package:fis_measure/interfaces/process/items/item.dart'; import 'package:fis_measure/interfaces/process/items/item_metas.dart'; import 'package:fis_measure/interfaces/process/workspace/application.dart'; import 'package:fis_measure/interfaces/process/workspace/point_info.dart'; import 'package:fis_measure/process/visual/tissue_area.dart'; import 'package:fis_measure/utils/canvas.dart'; import 'package:get/get.dart'; import '../calcuators/depth.dart'; import '../items/item.dart'; import '../items/item_feature.dart'; import '../physical_coordinates/convex_tissue.dart'; class Location extends MeasureItem { Location(ItemMeta meta, IMeasureItem? parent) : super(meta, parent); @override bool onExecuteMouse(PointInfo args) { if (state == ItemStates.finished || state == ItemStates.waiting) { if (args.pointType == PointInfoType.mouseMove) { handleMouseMoveWhileFinish(args); } } if (state == ItemStates.running) { if (args.pointType == PointInfoType.mouseUp) return false; feature?.point = args; doCalculate(); if (args.pointType == PointInfoType.mouseDown) { doFeatureFinish(); } } return true; } @override bool onExecuteTouch(PointInfo args) { // TODO: implement onExecuteTouch throw UnimplementedError(); } void handleMouseMoveWhileFinish(PointInfo args) { // TODO: 判断是否当前area // 转换为Area逻辑位置 final point = args.toAreaLogicPoint(); final isProbeConvex = (args.hostVisualArea! as TissueArea).isConvex; if (isProbeConvex) { feature = TissueConvexLocationFeature(this, point); } else { feature = LocationFeature(this, point); } if (args.hostVisualArea != null) { feature!.hostVisualArea = args.hostVisualArea; } state = ItemStates.running; } static Location createTissueConvexDepth( ItemMeta meta, [ IMeasureItem? parent, ]) { Location location = Location(meta, parent); location.calculator = TissueConvexDepthCal(location); return location; } static Location createTissueDepth( ItemMeta meta, [ IMeasureItem? parent, ]) { final area = Get.find().currentVisualArea; final isProbeConvex = (area as TissueArea).isConvex; final fn = isProbeConvex ? createTissueConvexDepth : createTissueNormalDepth; return fn(meta, parent); } static Location createTissueNormalDepth( ItemMeta meta, [ IMeasureItem? parent, ]) { Location location = Location(meta, parent); location.calculator = TissueDepthCal(location); return location; } } class TissueConvexLocationFeature extends LocationFeature { TissueConvexLocationFeature(IMeasureItem refItem, DPoint point) : super(refItem, point); @override void paint(Canvas canvas, Size size) { super.paint(canvas, size); final point = this.point.clone(); final layout = hostVisualArea!.displayRegion; point.addOffset(-layout.left, -layout.top); // TODO : fix bug final viewport = hostVisualArea!.viewport!; final physical = (viewport.physical! as ConvexTissuePhysicalCoordinate); final region = viewport.region; final physicalZeroPoint = DPoint(region.width / 2, physical.zeroY); // 真实尺寸圆心 final physicalPoint = viewport.convert(point); final physicalStartPoint = _findCrossPointOnInnerDiameter( physicalZeroPoint, physicalPoint, physical.zeroRadius, viewport.region, ); // 在内圈内,不处理 if (physicalStartPoint == null) return; final logicStartPoint = viewport.convertBack(physicalStartPoint); logicStartPoint.addOffset(layout.left, layout.top); point.addOffset(layout.left, layout.top); Offset viewStartPoint = convert2ViewPoint(size, logicStartPoint).toOffset(); Offset viewPoint = convert2ViewPoint(size, point).toOffset(); if (viewStartPoint.dy < 0) { // TODO: 处理起点在画布区间外的情况,区间外不绘制 return; } canvas.drawDashLine(viewStartPoint, viewPoint, 1, 10, paintPan); } /// 找到直线(圆心到当前点)和扇形内圈的交叉点 DPoint? _findCrossPointOnInnerDiameter( DPoint zero, DPoint point, double zeroRadius, RectRegion region, ) { final centerOfX = region.width / 2; final pointWidthOnX = centerOfX - point.x; final pointHeightOnY = point.y - zero.y; final pointRadius = math.sqrt(math.pow(pointWidthOnX, 2) + math.pow(pointHeightOnY, 2)); final ratio = zeroRadius / pointRadius; if (ratio > 1) return null; double width = pointWidthOnX * ratio; double height = pointHeightOnY * ratio; double x = centerOfX - width; double y = height + zero.y; return DPoint(x, y); } } class LocationFeature extends MeasureItemFeature { LocationFeature(IMeasureItem refItem, DPoint point) : super(refItem) { innerPoints.add(point); } DPoint get point => innerPoints[0]; set point(DPoint value) => innerPoints[0] = value; @override void paint(Canvas canvas, Size size) { drawId(canvas, size); final viewPoint = convert2ViewPoint(size, point).toOffset(); drawVertex(canvas, viewPoint, isActive); } }