Procházet zdrojové kódy

调整AutoSnapMixin&AreaItemAbstract

melon.yin před 2 roky
rodič
revize
4f8b18fefa

+ 2 - 0
lib/item_create_test.dart

@@ -106,6 +106,8 @@ class TestItems {
     MeasureTerms.CervixW,
     MeasureTerms.CervixH,
     "Tumor Cervix",
+    "AxT",
+    "FTA",
   ];
 
   static final C_DISTANCE_ITEMS = [

+ 12 - 16
lib/process/primitives/area_abstract.dart

@@ -6,6 +6,8 @@ import 'package:fis_measure/process/items/item_feature.dart';
 
 abstract class AreaItemAbstract extends MeasureItem<AreaItemFeatureAbstract> {
   bool _isClosed = true;
+  double _splineTension = 0.0;
+
   AreaItemAbstract(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);
 
   bool get isClosed => _isClosed;
@@ -14,15 +16,6 @@ abstract class AreaItemAbstract extends MeasureItem<AreaItemFeatureAbstract> {
       _isClosed = val;
     }
   }
-}
-
-abstract class AreaItemFeatureAbstract extends MeasureItemFeature {
-  double _splineTension = 0.0;
-  bool _isClosed = true;
-
-  AreaItemFeatureAbstract(AreaItemAbstract refItem) : super(refItem) {
-    isClosed = refItem.isClosed;
-  }
 
   double get splineTension => _splineTension;
   set splineTension(double val) {
@@ -30,17 +23,20 @@ abstract class AreaItemFeatureAbstract extends MeasureItemFeature {
       _splineTension = val;
     }
   }
+}
+
+abstract class AreaItemFeatureAbstract extends MeasureItemFeature {
+  AreaItemFeatureAbstract(AreaItemAbstract refItem) : super(refItem);
+
+  @override
+  AreaItemAbstract get refItem => super.refItem as AreaItemAbstract;
+
+  double get splineTension => refItem.splineTension;
+  bool get isClosed => refItem.isClosed;
 
   DPoint get startPoint => innerPoints.first;
   DPoint get endPoint => innerPoints.last;
 
-  bool get isClosed => _isClosed;
-  set isClosed(bool val) {
-    if (val != _isClosed) {
-      _isClosed = val;
-    }
-  }
-
   /// 接收新坐标
   void adopt(DPoint point) {
     innerPoints.add(point);

+ 1 - 1
lib/process/primitives/polyline.dart

@@ -58,7 +58,7 @@ class Polyline extends AreaItemAbstract with AutoSnapMixin {
       }
       doCalculate();
 
-      checkAutoFinish(args);
+      checkAutoSnap(args);
 
       // if (f.startPoint.almostEquals(f.endPoint)) {
       //   doFeatureFinish();

+ 18 - 14
lib/process/primitives/spline.dart

@@ -24,6 +24,8 @@ class Spline extends AreaItemAbstract with AutoSnapMixin {
   static Spline createAreaPerimeter(ItemMeta meta, [IMeasureItem? parent]) {
     Spline spline = Spline(meta, parent);
     spline.calculator = _AreaPerimeterCalc(spline);
+    spline.isClosed = false;
+    spline.splineTension = 0.5;
     return spline;
   }
 
@@ -33,6 +35,8 @@ class Spline extends AreaItemAbstract with AutoSnapMixin {
   ]) {
     Spline spline = Spline(meta, parent);
     spline.calculator = CurveLengthCal(spline);
+    spline.isClosed = false;
+    spline.splineTension = 0.5;
     return spline;
   }
 
@@ -61,7 +65,7 @@ class Spline extends AreaItemAbstract with AutoSnapMixin {
       }
       doCalculate();
 
-      f.isClosed = checkAutoFinish(args);
+      checkAutoSnap(args);
     }
     return true;
   }
@@ -84,20 +88,18 @@ class Spline extends AreaItemAbstract with AutoSnapMixin {
 }
 
 class SplineFeature extends AreaItemFeatureAbstract {
-  static const double _splineTension = 0.5;
   static const double _splineTolerance = 0.05;
 
-  SplineFeature(AreaItemAbstract refItem, DPoint point) : super(refItem) {
+  SplineFeature(Spline refItem, DPoint point) : super(refItem) {
     innerPoints.add(point.clone());
     innerPoints.add(point.clone());
-    splineTension = _splineTension;
   }
 
   @override
   void paint(Canvas canvas, Size size) {
     if (innerPoints.isEmpty) return;
     final paintPoints = innerPoints;
-    if (isClosed) {
+    if ((refItem as AutoSnapMixin).snapState) {
       paintPoints.removeLast();
     }
     drawId(canvas, size);
@@ -155,15 +157,17 @@ class SplineFeature extends AreaItemFeatureAbstract {
 
   static void addSegment(List<DPoint> polyLineSegment, List<DPoint> points,
       List<int> pointIndex, double tension, double tolerance) {
+    if (points.length < 2) return;
     segment(
-        polyLineSegment,
-        points[pointIndex[0]],
-        points[pointIndex[1]],
-        points[pointIndex[2]],
-        points[pointIndex[3]],
-        tension,
-        tension,
-        tolerance);
+      polyLineSegment,
+      points[pointIndex[0]],
+      points[pointIndex[1]],
+      points[pointIndex[2]],
+      points[pointIndex[3]],
+      tension,
+      tension,
+      tolerance,
+    );
   }
 
   static double segment(List<DPoint> points, DPoint pt0, DPoint pt1, DPoint pt2,
@@ -303,7 +307,7 @@ class _AreaPerimeterCalc extends Calculator<Spline, double> {
             points[i + 1], points[i + 2], tension, tension, tolerance);
       }
     }
-    print("面积计算拟合点数 ${polyLineSegment.length}");
+    // print("面积计算拟合点数 ${polyLineSegment.length}");
     final area = calcArea(polyLineSegment);
     return [perimeter, area];
   }

+ 2 - 4
lib/process/primitives/trace.dart

@@ -15,7 +15,6 @@ import 'area_abstract.dart';
 
 /// 手势轨迹图形
 class Trace extends AreaItemAbstract with AutoSnapMixin {
-  final bool _initialClosed = false;
   PointInfo? _firstPoint;
 
   Trace(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);
@@ -40,7 +39,7 @@ class Trace extends AreaItemAbstract with AutoSnapMixin {
       if (args.pointType == PointInfoType.mouseDown) {
         doFeatureFinish();
       } else {
-        checkAutoFinish(args);
+        checkAutoSnap(args);
       }
     }
     return true;
@@ -56,7 +55,6 @@ class Trace extends AreaItemAbstract with AutoSnapMixin {
     // TODO: 判断是否当前area
     // 转换为Area逻辑位置
     feature = TraceFeature(this);
-    feature!.isClosed = _initialClosed;
     if (args.hostVisualArea != null) {
       feature!.hostVisualArea = args.hostVisualArea;
     }
@@ -95,7 +93,7 @@ class Trace extends AreaItemAbstract with AutoSnapMixin {
       if (args.pointType == PointInfoType.touchMove) {
         feature?.adopt(args);
         doCalculate();
-        checkAutoFinish(args);
+        checkAutoSnap(args);
       }
     }
     return true;

+ 29 - 9
lib/process/primitives/utils/auto_snap.dart

@@ -2,11 +2,13 @@ import 'package:fis_measure/interfaces/date_types/int_size.dart';
 import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
 import 'package:fis_measure/process/items/item.dart';
 import 'package:fis_measure/process/items/item_feature.dart';
-import 'package:flutter/painting.dart';
 import 'package:flutter/services.dart';
 
 mixin AutoSnapMixin<T extends MeasureItemFeature> on MeasureItem<T> {
   bool _isSmartMove = false;
+  bool _isAutoSnap = true;
+  double _snapThreshold = 10.0;
+  bool snapState = false;
 
   /// 是否启动智能定位
   bool get isSmartMove => _isSmartMove;
@@ -16,17 +18,30 @@ mixin AutoSnapMixin<T extends MeasureItemFeature> on MeasureItem<T> {
     }
   }
 
+  bool get isAutoSnap => _isAutoSnap;
+  set isAutoSnap(bool val) {
+    if (val != _isAutoSnap) {
+      _isAutoSnap = val;
+    }
+  }
+
+  /// 自动结束阈值 pixel
+  double get snapThreshold => _snapThreshold;
+  set snapThreshold(double val) {
+    if (val != _snapThreshold) {
+      _snapThreshold = val;
+    }
+  }
+
   /// 自动结束检测
-  bool checkAutoFinish(PointInfo current) {
+  bool checkAutoSnap(PointInfo current) {
     if (feature == null || feature!.innerPoints.length < 3) {
       isSmartMove = false;
-      return false;
+      return _syncState(false);
     }
 
     // final viewport = feature!.hostVisualArea!.viewport!;
 
-    double autoSnapThreshold = 10; //TODO: from config, pixel
-    bool isAutoSnap = true; //TODO: from config
     if (isAutoSnap == false) return false;
     final pixelSize = IntSize.fill(
       application.frameData!.width,
@@ -36,10 +51,10 @@ mixin AutoSnapMixin<T extends MeasureItemFeature> on MeasureItem<T> {
     final p1 = feature!.innerPoints.first.scale2Size(pixelSize);
     final p2 = current.scale2Size(pixelSize);
     final length = (p1 - p2).length;
-    if (length > autoSnapThreshold * 2.0 && !isSmartMove) {
+    if (length > snapThreshold * 2.0 && !isSmartMove) {
       isSmartMove = true;
     }
-    if (length < autoSnapThreshold && isSmartMove) {
+    if (length < snapThreshold && isSmartMove) {
       feature!.innerPoints.last = feature!.innerPoints.first.clone();
 
       /// TODO:[Gavin] 此处的最后一个点,应该保留,方便计算,但是绘制时要剔除
@@ -49,9 +64,14 @@ mixin AutoSnapMixin<T extends MeasureItemFeature> on MeasureItem<T> {
       doCalculate();
       doFeatureFinish();
       isSmartMove = false;
-      return true;
+      return _syncState(true);
     } else {
-      return false;
+      return _syncState(false);
     }
   }
+
+  bool _syncState(bool isSnap) {
+    snapState = isSnap;
+    return snapState;
+  }
 }