|
@@ -1,11 +1,13 @@
|
|
|
import 'dart:ui';
|
|
|
|
|
|
import 'package:fis_measure/interfaces/date_types/point.dart';
|
|
|
+import 'package:fis_measure/interfaces/date_types/vector.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/items/types.dart';
|
|
|
import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
|
|
|
+import 'package:fis_measure/process/calcuators/curve.dart';
|
|
|
import 'package:fis_measure/process/calcuators/formulas/general.dart';
|
|
|
import 'package:fis_measure/process/items/item.dart';
|
|
|
import 'package:fis_measure/process/items/item_feature.dart';
|
|
@@ -14,8 +16,11 @@ import 'package:fis_measure/process/primitives/area_abstract.dart';
|
|
|
import 'package:fis_measure/process/primitives/utils/auto_snap.dart';
|
|
|
import 'package:fis_measure/utils/canvas.dart';
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
+import 'package:flutter/rendering.dart';
|
|
|
import 'package:path_drawing/path_drawing.dart';
|
|
|
|
|
|
+import 'spline.dart';
|
|
|
+
|
|
|
enum LvSimpsonStep {
|
|
|
none,
|
|
|
splineBeginEdit,
|
|
@@ -153,23 +158,34 @@ class SimpsonPath extends AreaItemAbstract with AutoSnapMixin {
|
|
|
}
|
|
|
|
|
|
class SimpsonPathFeature extends AreaItemFeatureAbstract {
|
|
|
- Map<int, double> horizontalSplitterLegths = {};
|
|
|
+ static const autoGetApexPoint = false; // TODO
|
|
|
+
|
|
|
+ late Map<int, double> horizontalSplitterLegths;
|
|
|
+ late DPoint moveBasedPoint;
|
|
|
+
|
|
|
IPathGeometry? _pathGeometry;
|
|
|
List<DPoint>? _splinePoints;
|
|
|
IPathGeometry? _spline;
|
|
|
late DPoint _centerLineFixedPoint;
|
|
|
late DPoint _centerLineMovablePoint;
|
|
|
+
|
|
|
+ late MovablePointsInfo _movablePtsInfo;
|
|
|
late DPoint _leftPoint;
|
|
|
late DPoint _rightPoint;
|
|
|
late DPoint _apexPoint;
|
|
|
|
|
|
SimpsonPathFeature(AreaItemAbstract refItem) : super(refItem) {
|
|
|
- // _splinePoints = [];
|
|
|
+ _splinePoints = [];
|
|
|
_centerLineFixedPoint = DPointExt.empty;
|
|
|
_centerLineMovablePoint = DPointExt.empty;
|
|
|
+
|
|
|
+ _movablePtsInfo = MovablePointsInfo.empty();
|
|
|
_leftPoint = DPointExt.empty;
|
|
|
_rightPoint = DPointExt.empty;
|
|
|
_apexPoint = DPointExt.empty;
|
|
|
+
|
|
|
+ moveBasedPoint = DPointExt.empty;
|
|
|
+ horizontalSplitterLegths = {};
|
|
|
}
|
|
|
|
|
|
@override
|
|
@@ -181,10 +197,61 @@ class SimpsonPathFeature extends AreaItemFeatureAbstract {
|
|
|
_centerLineMovablePoint = val;
|
|
|
|
|
|
updateSplitters();
|
|
|
- // OnVertexPointChanged();
|
|
|
+ _onVertexPointChanged();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ DPoint get centerLineFixedPoint => _centerLineFixedPoint;
|
|
|
+
|
|
|
+ MovablePointsInfo get movablePtsInfo => _movablePtsInfo;
|
|
|
+ set movablePtsInfo(MovablePointsInfo val) {
|
|
|
+ if (val != _movablePtsInfo) {
|
|
|
+ _movablePtsInfo = val;
|
|
|
+ _onSplineMovablePointsInfoChanged();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DPoint get leftPoint => _leftPoint;
|
|
|
+ set leftPoint(DPoint val) {
|
|
|
+ if (val != _leftPoint) {
|
|
|
+ _leftPoint = val;
|
|
|
+ _onVertexPointChanged();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DPoint get rightPoint => _rightPoint;
|
|
|
+ set rightPoint(DPoint val) {
|
|
|
+ if (val != _rightPoint) {
|
|
|
+ _rightPoint = val;
|
|
|
+ _onVertexPointChanged();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DPoint get apexPoint => _apexPoint;
|
|
|
+ set apexPoint(DPoint val) {
|
|
|
+ if (val != _apexPoint) {
|
|
|
+ _apexPoint = val;
|
|
|
+ _onVertexPointChanged();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double get centerLineLength {
|
|
|
+ final viewport = hostVisualArea!.viewport!;
|
|
|
+ final p1 = viewport.convert(_centerLineFixedPoint);
|
|
|
+ final p2 = viewport.convert(_centerLineMovablePoint);
|
|
|
+ final value = (p2 - p1).length.abs();
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ double get area {
|
|
|
+ final viewport = hostVisualArea!.viewport!;
|
|
|
+ final points = innerPoints.map((e) => viewport.convert(e)).toList();
|
|
|
+ final value = AreaPerimeterCal.calcArea(points);
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool isClosed = false; // TODO
|
|
|
+
|
|
|
@override
|
|
|
void paint(Canvas canvas, Size size) {
|
|
|
if (innerPoints.isEmpty) return;
|
|
@@ -222,73 +289,70 @@ class SimpsonPathFeature extends AreaItemFeatureAbstract {
|
|
|
|
|
|
void updateActivePoint(DPoint point) {
|
|
|
if (activeIndex > 0 && activeIndex <= innerPoints.length) {
|
|
|
- // ActivePoint = point;
|
|
|
+ activePoint = point;
|
|
|
recreateSpline(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ DPoint get activePoint {
|
|
|
+ if (activeIndex < 0 || activeIndex >= innerPoints.length) {
|
|
|
+ throw IndexError.withLength(activeIndex, innerPoints.length);
|
|
|
+ }
|
|
|
+ return innerPoints[activeIndex];
|
|
|
+ }
|
|
|
+
|
|
|
+ set activePoint(DPoint val) {
|
|
|
+ if (activeIndex < 0 || activeIndex >= innerPoints.length) {
|
|
|
+ throw IndexError.withLength(activeIndex, innerPoints.length);
|
|
|
+ }
|
|
|
+ innerPoints[activeIndex] = val;
|
|
|
+ }
|
|
|
+
|
|
|
void fixedSpline() {
|
|
|
- return;
|
|
|
if (innerPoints.isEmpty) {
|
|
|
return;
|
|
|
}
|
|
|
- // _centerLineFixedPoint =
|
|
|
- DPoint((innerPoints.last.x + innerPoints.first.x) * 0.5,
|
|
|
- (innerPoints.last.y + innerPoints.first.y) * 0.5);
|
|
|
+ _centerLineFixedPoint = DPoint(
|
|
|
+ (innerPoints.last.x + innerPoints.first.x) * 0.5,
|
|
|
+ (innerPoints.last.y + innerPoints.first.y) * 0.5,
|
|
|
+ );
|
|
|
|
|
|
var movablePoint = DPoint(0, double.infinity);
|
|
|
|
|
|
- // if (BaseType == MeasureTypes.SimpsonAutoTrace)
|
|
|
- // {
|
|
|
- // movablePoint = InnerPoints[InnerPoints.Count >> 1];
|
|
|
- // }
|
|
|
- // else
|
|
|
- // {
|
|
|
- // var isFindMin = innerPoints[innerPoints.length >> 1].y - innerPoints[0].y < 0;
|
|
|
- // if (AutoGetApexPoint)
|
|
|
- // {
|
|
|
- // movablePoint = isFindMin ? movablePoint : DPoint(0, double.negativeInfinity);
|
|
|
- // }
|
|
|
+ var isFindMin =
|
|
|
+ innerPoints[innerPoints.length >> 1].y - innerPoints[0].y < 0;
|
|
|
+ if (autoGetApexPoint) {
|
|
|
+ movablePoint =
|
|
|
+ isFindMin ? movablePoint : DPoint(0, double.negativeInfinity);
|
|
|
+ }
|
|
|
|
|
|
- // foreach (DPoint point in InnerPoints)
|
|
|
- // {
|
|
|
- // if (AutoGetApexPoint && innerPoints.Count > 0)
|
|
|
- // {
|
|
|
- // if (isFindMin)
|
|
|
- // {
|
|
|
- // if (point.Y < movablePoint.Y)
|
|
|
- // {
|
|
|
- // movablePoint = point;
|
|
|
- // }
|
|
|
- // }
|
|
|
- // else
|
|
|
- // {
|
|
|
- // if (point.Y > movablePoint.Y)
|
|
|
- // {
|
|
|
- // movablePoint = point;
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- // else
|
|
|
- // {
|
|
|
- // if (point.Y < movablePoint.Y)
|
|
|
- // {
|
|
|
- // movablePoint = point;
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
+ for (DPoint point in innerPoints) {
|
|
|
+ if (autoGetApexPoint && innerPoints.isNotEmpty) {
|
|
|
+ if (isFindMin) {
|
|
|
+ if (point.y < movablePoint.y) {
|
|
|
+ movablePoint = point;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (point.y > movablePoint.y) {
|
|
|
+ movablePoint = point;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (point.y < movablePoint.y) {
|
|
|
+ movablePoint = point;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // if (_centerLineMovablePoint != movablePoint)
|
|
|
- // {
|
|
|
- // _centerLineMovablePoint = movablePoint;
|
|
|
- // if (!DPointExtension.IsEmpty(_centerLineMovablePoint) && (BaseType != MeasureTypes.SimpsonAutoTrace))
|
|
|
- // {
|
|
|
- // _centerLineMovablePoint.SynchToMainMonitorScreen(HostArea);
|
|
|
- // }
|
|
|
- // }
|
|
|
- // UpdateSplitters();
|
|
|
- // OnVertexPointChanged();
|
|
|
+ if (_centerLineMovablePoint != movablePoint) {
|
|
|
+ _centerLineMovablePoint = movablePoint;
|
|
|
+ if (!_centerLineMovablePoint.isEmpty) {
|
|
|
+ // TODO 重设光标位置,暂不支持
|
|
|
+ // _centerLineMovablePoint.SynchToMainMonitorScreen(HostArea);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ updateSplitters();
|
|
|
+ _onVertexPointChanged();
|
|
|
}
|
|
|
|
|
|
void adjustEndPoint(DPoint point) {
|
|
@@ -360,6 +424,9 @@ class SimpsonPathFeature extends AreaItemFeatureAbstract {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ void _onVertexPointChanged() {}
|
|
|
+ void _onSplineMovablePointsInfoChanged() {}
|
|
|
}
|
|
|
|
|
|
class SimpsonGeometryGenerator {
|
|
@@ -372,7 +439,49 @@ class SimpsonGeometryGenerator {
|
|
|
DPoint centerLineMovablePoint,
|
|
|
Map<int, double> horizontalSplitterLegths,
|
|
|
) {
|
|
|
+ if (centerLineFixedPoint.isEmpty || centerLineMovablePoint.isEmpty) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// TODO: 辛普森绘制核心
|
|
|
+
|
|
|
+ // Center line
|
|
|
+ DVector centerLine = centerLineMovablePoint - centerLineFixedPoint;
|
|
|
+ var horizontalStart = DPoint(-50, centerLineFixedPoint.y);
|
|
|
+ // horizonta line
|
|
|
+ DVector horizontalLine = horizontalStart - centerLineFixedPoint;
|
|
|
+ // Get angle between horizontal and center line
|
|
|
+ double angle = DVector.angleBetween(horizontalLine, centerLine);
|
|
|
+ double angleToVertical = 90.0 - angle;
|
|
|
+
|
|
|
+ double cellHeight = centerLine.length / splitterCount;
|
|
|
+
|
|
|
+ //Create a 20 splitters path geometry
|
|
|
+ PathGeometryContainer temSplittersGeometry = PathGeometryContainer(Path());
|
|
|
+ for (int i = 1; i <= splitterCount; i++) {
|
|
|
+ double midPointY =
|
|
|
+ centerLineFixedPoint.y - cellHeight * (i - 1) - cellHeight / 2;
|
|
|
+ //horizontal splitter line
|
|
|
+ final tempLinePath = Path();
|
|
|
+ tempLinePath.moveTo(-50, midPointY);
|
|
|
+ tempLinePath.lineTo(50, midPointY);
|
|
|
+
|
|
|
+ var matrix = Matrix4.identity();
|
|
|
+ matrix.rotateZ(angleToVertical * 0.0174533); // Convert degrees to radians
|
|
|
+ // matrix.translate(centerLineFixedPoint.dx, centerLineFixedPoint.dy);
|
|
|
+ matrix.scale(1, 1, 1); // Adjust scale if needed
|
|
|
+ matrix.translate(
|
|
|
+ -50, -midPointY); // Adjust translation to center the line
|
|
|
+ // tempLinePath.transform(matrix)
|
|
|
+ // LineGeometry templineGeometry =
|
|
|
+ // new LineGeometry(Point(-50, midPointY), Point(50, midPointY));
|
|
|
+ // templineGeometry.Transform = new RotateTransform(
|
|
|
+ // -angleToVertical, centerLineFixedPoint.x, centerLineFixedPoint.y);
|
|
|
+ // temSplittersGeometry.addGeometry(templineGeometry);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<DPoint> leftPoints = [];
|
|
|
+ List<DPoint> rightPoints = [];
|
|
|
}
|
|
|
|
|
|
IPathGeometry? createSpline(
|
|
@@ -390,7 +499,7 @@ class SimpsonGeometryGenerator {
|
|
|
return null;
|
|
|
}
|
|
|
List<DPoint> samplePoints = [];
|
|
|
- // var points = Spline.Create(sourcePoints, tension, tensions, isClosed, tolerance, true, out length, samplePoints,true);
|
|
|
+ // var points = Spline.create(sourcePoints, tension, tensions, isClosed, tolerance, true, out length, samplePoints,true);
|
|
|
var points = <DPoint>[];
|
|
|
// var myPoints = GeomTools.ToWindowPoints(points.ToArray());
|
|
|
// var polyLineSegment = new PolyLineSegment { Points = new PointCollection(myPoints) };
|
|
@@ -410,6 +519,7 @@ class SimpsonGeometryGenerator {
|
|
|
|
|
|
class PathGeometryContainer implements IPathGeometry {
|
|
|
final pathList = <Path>[];
|
|
|
+ final geometries = <IPathGeometry>[];
|
|
|
late final Path control;
|
|
|
|
|
|
PathGeometryContainer(Path geometry) {
|
|
@@ -418,8 +528,7 @@ class PathGeometryContainer implements IPathGeometry {
|
|
|
|
|
|
@override
|
|
|
void addGeometry(IPathGeometry geometry) {
|
|
|
- // TODO:
|
|
|
- // pathList.addAll(geometry.pathList);
|
|
|
+ geometries.add(geometry);
|
|
|
}
|
|
|
|
|
|
void addPath(Path path) {
|
|
@@ -455,3 +564,15 @@ extension DPointExt on DPoint {
|
|
|
return this == empty;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+class MovablePointsInfo {
|
|
|
+ int index;
|
|
|
+ int start;
|
|
|
+ int end;
|
|
|
+
|
|
|
+ MovablePointsInfo(this.index, this.start, this.end);
|
|
|
+
|
|
|
+ factory MovablePointsInfo.empty() {
|
|
|
+ return MovablePointsInfo(-1, -1, -1);
|
|
|
+ }
|
|
|
+}
|