123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- import 'dart:ui';
- import 'package:fis_measure/interfaces/date_types/point.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/formulas/general.dart';
- import 'package:fis_measure/process/items/item.dart';
- import 'package:fis_measure/process/items/item_feature.dart';
- import 'package:fis_measure/process/primitives/polyline.dart';
- 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:path_drawing/path_drawing.dart';
- enum LvSimpsonStep {
- none,
- splineBeginEdit,
- splineEditing,
- splineEndEdit,
- splineCompleted,
- done,
- }
- class SimpsonPath extends AreaItemAbstract with AutoSnapMixin {
- static const int SplitterCount = 20;
- static const double MaxPointsCount = 10000;
- SimpsonPath(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);
- PointInfo? firstPoint;
- @protected
- LvSimpsonStep lvSimpsonStep = LvSimpsonStep.none;
- @override
- SimpsonPathFeature? get feature => super.feature as SimpsonPathFeature;
- @override
- bool onExecuteMouse(PointInfo args) {
- if (state == ItemStates.finished) {
- if (args.pointType == PointInfoType.mouseDown) {
- state = ItemStates.waiting;
- lvSimpsonStep = LvSimpsonStep.none;
- }
- }
- if (state == ItemStates.waiting) {
- if (args.pointType == PointInfoType.mouseDown) {
- handleMouseDownWhileWaiting(args);
- }
- } else if (state == ItemStates.running) {
- switch (args.pointType) {
- case PointInfoType.mouseUp:
- return false;
- case PointInfoType.mouseDown:
- if (lvSimpsonStep == LvSimpsonStep.splineCompleted) {
- feature!.adjustEndPoint(args.toAreaLogicPoint());
- lvSimpsonStep = LvSimpsonStep.done;
- // CaliperExtension.ShowCaliper();
- } else {
- final lineLen = (args - firstPoint!).length;
- if ((feature!.innerPoints.length > 3 &&
- GeneralFormulas.doubleAlmostEquals(lineLen, 0)) ||
- feature!.innerPoints.length >= MaxPointsCount) {
- lvSimpsonStep = LvSimpsonStep.splineCompleted;
- feature!.fixedSpline();
- } else {
- feature!.adopt(args.toAreaLogicPoint());
- }
- }
- break;
- case PointInfoType.mouseMove:
- if (lvSimpsonStep == LvSimpsonStep.splineCompleted) {
- feature!.adjustEndPoint(args.toAreaLogicPoint());
- } else {
- if (!snapState) {
- checkAutoSnap(args, false);
- }
- if (!snapState) {
- feature!.updateActivePoint(args.toAreaLogicPoint());
- }
- }
- break;
- default:
- break;
- }
- }
- doCalculate();
- if (args.pointType == PointInfoType.mouseDown) {
- // doFeatureFinish();
- if (state == ItemStates.waiting || state == ItemStates.finished) {
- state = ItemStates.running;
- }
- if (state == ItemStates.running) {
- updateStatus();
- }
- }
- if (args.pointType == PointInfoType.mouseMove) {
- updateStatus();
- }
- return true;
- }
- @override
- bool onExecuteTouch(PointInfo args) {
- // TODO: implement onExecuteTouch
- throw UnimplementedError();
- }
- void handleMouseDownWhileWaiting(PointInfo args) {
- // TODO: 判断是否当前area
- // 转换为Area逻辑位置
- feature = SimpsonPathFeature(this);
- if (args.hostVisualArea != null) {
- feature!.hostVisualArea = args.hostVisualArea;
- }
- final point = args.toAreaLogicPoint();
- feature!.adopt(point);
- feature!.adopt(point);
- state = ItemStates.running;
- firstPoint = args;
- }
- void updateStatus() {
- switch (lvSimpsonStep) {
- case LvSimpsonStep.splineCompleted:
- firstPoint = null;
- if (feature != null) {
- feature!.activeIndex = feature!.innerPoints.length;
- }
- break;
- case LvSimpsonStep.done:
- state = ItemStates.finished;
- if (feature != null) {
- feature!.activeIndex = -1;
- }
- break;
- default:
- break;
- }
- }
- static SimpsonPath create(ItemMeta meta, [IMeasureItem? parent]) {
- final path = SimpsonPath(meta, parent);
- return path;
- }
- }
- class SimpsonPathFeature extends AreaItemFeatureAbstract {
- Map<int, double> horizontalSplitterLegths = {};
- IPathGeometry? _pathGeometry;
- List<DPoint>? _splinePoints;
- IPathGeometry? _spline;
- late DPoint _centerLineFixedPoint;
- late DPoint _centerLineMovablePoint;
- late DPoint _leftPoint;
- late DPoint _rightPoint;
- late DPoint _apexPoint;
- SimpsonPathFeature(AreaItemAbstract refItem) : super(refItem) {
- // _splinePoints = [];
- _centerLineFixedPoint = DPointExt.empty;
- _centerLineMovablePoint = DPointExt.empty;
- _leftPoint = DPointExt.empty;
- _rightPoint = DPointExt.empty;
- _apexPoint = DPointExt.empty;
- }
- @override
- SimpsonPath get refItem => super.refItem as SimpsonPath;
- DPoint get centerLineMovablePoint => _centerLineMovablePoint;
- set centerLineMovablePoint(DPoint val) {
- if (val != _centerLineMovablePoint) {
- _centerLineMovablePoint = val;
- updateSplitters();
- // OnVertexPointChanged();
- }
- }
- @override
- void paint(Canvas canvas, Size size) {
- if (innerPoints.isEmpty) return;
- drawId(canvas, size);
- final points = innerPoints.map((e) => convert2ViewPoint(size, e)).toList();
- final startPoint = points.first;
- drawVertex(canvas, startPoint.toOffset(), points.length == 1);
- // if (points.length > 1) {
- // final Path path = Path();
- // path.moveTo(startPoint.x, startPoint.y);
- // for (var i = 1; i < points.length; i++) {
- // final point = points[i];
- // path.lineTo(point.x, point.y);
- // }
- // if (isClosed) {
- // path.lineTo(startPoint.x, startPoint.y);
- // }
- // canvas.drawPath(
- // path,
- // paintLinePan,
- // );
- // }
- drawVertex(canvas, points.last.toOffset(), isActive);
- }
- @override
- void adopt(DPoint point) {
- super.adopt(point);
- recreateSpline(false);
- }
- void updateActivePoint(DPoint point) {
- if (activeIndex > 0 && activeIndex <= innerPoints.length) {
- // ActivePoint = point;
- recreateSpline(false);
- }
- }
- 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);
- 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);
- // }
- // 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;
- // }
- // }
- // }
- // }
- // if (_centerLineMovablePoint != movablePoint)
- // {
- // _centerLineMovablePoint = movablePoint;
- // if (!DPointExtension.IsEmpty(_centerLineMovablePoint) && (BaseType != MeasureTypes.SimpsonAutoTrace))
- // {
- // _centerLineMovablePoint.SynchToMainMonitorScreen(HostArea);
- // }
- // }
- // UpdateSplitters();
- // OnVertexPointChanged();
- }
- void adjustEndPoint(DPoint point) {
- if (innerPoints.isEmpty) {
- return;
- }
- var endPoint = point;
- double minDistance = double.infinity;
- if (_splinePoints != null) {
- for (DPoint splinePoint in _splinePoints!) {
- double distance = (point - splinePoint).length;
- if (distance < minDistance) {
- minDistance = distance;
- endPoint = splinePoint;
- }
- }
- }
- centerLineMovablePoint = endPoint;
- }
- void recreateSpline(bool isClosed) {
- // if (_breaker.Paused) {
- // return;
- // }
- final generator = SimpsonGeometryGenerator();
- _pathGeometry ??= generator.createPathGeometry();
- double tempCircumference = 0;
- _spline = generator.createSpline(
- innerPoints,
- 0.5,
- null,
- isClosed,
- false,
- 0.005,
- tempCircumference,
- _splinePoints,
- );
- if (_spline != null && _splinePoints != null) {
- _pathGeometry!.addGeometry(_spline!);
- }
- }
- void updateSplitters() {
- recreateSpline(true);
- if (_spline != null && !_centerLineMovablePoint.isEmpty) {
- var generator = SimpsonGeometryGenerator();
- _pathGeometry!.clear();
- if (innerPoints.isNotEmpty) {
- _pathGeometry!.addGeometry(_spline!);
- horizontalSplitterLegths = {};
- generator.createSplitters(
- _pathGeometry!,
- _spline!,
- _centerLineFixedPoint,
- _centerLineMovablePoint,
- horizontalSplitterLegths,
- );
- _pathGeometry!.addLineGeometry(
- _centerLineFixedPoint,
- _centerLineMovablePoint,
- );
- }
- }
- }
- }
- class SimpsonGeometryGenerator {
- static const int splitterCount = 20;
- void createSplitters(
- IPathGeometry pathGeometry,
- IPathGeometry spline,
- DPoint centerLineFixedPoint,
- DPoint centerLineMovablePoint,
- Map<int, double> horizontalSplitterLegths,
- ) {
- // TODO: 辛普森绘制核心
- }
- IPathGeometry? createSpline(
- List<DPoint> sourcePoints,
- double tension,
- List<double>? tensions,
- bool isClosed,
- bool isFilled,
- double tolerance,
- double length,
- List<DPoint>? splinePoints,
- ) {
- length = 0;
- if (sourcePoints.isEmpty) {
- return null;
- }
- List<DPoint> samplePoints = [];
- // 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) };
- // var pathFigure = new PathFigure { IsClosed = isClosed, IsFilled = true, StartPoint = sourcePoints[0].ToWindowPoint() };
- // pathFigure.Segments.Add(polyLineSegment);
- var pathGeometry = Path();
- // pathGeometry.Figures.Add(pathFigure);
- splinePoints = points;
- return PathGeometryContainer(pathGeometry);
- }
- IPathGeometry createPathGeometry() {
- return PathGeometryContainer(Path());
- }
- }
- class PathGeometryContainer implements IPathGeometry {
- final pathList = <Path>[];
- late final Path control;
- PathGeometryContainer(Path geometry) {
- control = geometry;
- }
- @override
- void addGeometry(IPathGeometry geometry) {
- // TODO:
- // pathList.addAll(geometry.pathList);
- }
- void addPath(Path path) {
- pathList.add(path);
- }
- @override
- void clear() {
- pathList.clear();
- }
- @override
- void addLineGeometry(
- DPoint centerLineFixedPoint, DPoint centerLineMovablePoint) {
- final linePath = Path()
- ..moveTo(centerLineFixedPoint.x, centerLineFixedPoint.y)
- ..lineTo(centerLineMovablePoint.x, centerLineMovablePoint.y);
- addPath(linePath);
- }
- }
- abstract class IPathGeometry {
- void clear();
- void addGeometry(IPathGeometry spline);
- void addLineGeometry(
- DPoint centerLineFixedPoint, DPoint centerLineMovablePoint);
- }
- extension DPointExt on DPoint {
- static final empty = DPoint(double.minPositive, double.minPositive);
- bool get isEmpty {
- return this == empty;
- }
- }
|