123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- 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/point_info.dart';
- import 'package:fis_measure/process/calcuators/ray.dart';
- import 'package:fis_measure/process/items/item.dart';
- import 'package:fis_measure/process/items/item_feature.dart';
- import 'package:fis_measure/utils/canvas.dart';
- class Ray extends MeasureItem<RayFeature> {
- double _initializeAngle = 0;
- double _initializeAngleVal = 0;
- bool _switchInitialAngle = false;
- Ray(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);
- double get initializeAngle => _initializeAngle;
- set initializeAngle(double value) {
- if (value != _initializeAngle) {
- _initializeAngleVal = value;
- _updateInitializeAngle();
- }
- }
- bool get switchInitialAngle => _switchInitialAngle;
- set switchInitialAngle(bool value) {
- if (value != _switchInitialAngle) {
- _switchInitialAngle = value;
- _updateInitializeAngle();
- }
- }
- @override
- bool onExecuteMouse(PointInfo args) {
- if (state == ItemStates.finished || state == ItemStates.waiting) {
- if (args.pointType == PointInfoType.mouseMove) {
- feature = RayFeature(this, args);
- feature!.hostVisualArea = args.hostVisualArea;
- final viewport = args.hostVisualArea!.viewport!;
- feature!.isReverse =
- viewport.isFlipHorizontal ^ viewport.isFlipVertical;
- state = ItemStates.running;
- }
- }
- if (state == ItemStates.running) {
- if (args.pointType == PointInfoType.mouseUp) return false;
- feature?.point = args;
- doCalculate();
- if (args.pointType == PointInfoType.mouseDown) {
- doFeatureFinish();
- }
- }
- return true;
- }
- // 是否需要结束当前的测量过程,用于移动端的交互
- bool isNeedFinish = true;
- bool isFirstTouch = true;
- DPoint touchStartPoint = DPoint(0, 0);
- DPoint lastLinePosition = DPoint(0, 0);
- @override
- bool onExecuteTouch(PointInfo args) {
- if (state == ItemStates.waiting || state == ItemStates.finished) {
- if (args.pointType == PointInfoType.touchMove) {
- if (measuredFeatures.isEmpty) {
- feature = RayFeature(this, args);
- feature!.hostVisualArea = args.hostVisualArea;
- final viewport = args.hostVisualArea!.viewport!;
- feature!.isReverse =
- viewport.isFlipHorizontal ^ viewport.isFlipVertical;
- } else {
- feature = measuredFeatures.first;
- }
- state = ItemStates.running;
- }
- }
- if (state == ItemStates.running) {
- if (args.pointType == PointInfoType.touchDown) {
- touchStartPoint = args;
- lastLinePosition = feature?.point ?? args;
- isNeedFinish = true;
- isFirstTouch = feature?.point == null;
- }
- if (args.pointType == PointInfoType.touchMove) {
- isNeedFinish = false;
- if (isFirstTouch) {
- if (isMoveTargetOutOfRange(args)) return true;
- feature?.point = args;
- } else {
- PointInfo newPoint = PointInfo.fromOffset(
- lastLinePosition
- .clone()
- .addVector(args - touchStartPoint)
- .toOffset(),
- args.pointType);
- newPoint.hostVisualArea = args.hostVisualArea;
- if (isMoveTargetOutOfRange(newPoint)) return true;
- feature?.point = newPoint;
- }
- doCalculate();
- }
- if (args.pointType == PointInfoType.touchUp && isNeedFinish) {
- doFeatureFinish();
- }
- }
- return true;
- }
- static Ray createRay(ItemMeta meta, [IMeasureItem? parent]) {
- final ray = Ray(meta, parent);
- ray.calculator = RayDepthCal(ray);
- return ray;
- }
- void _updateInitializeAngle() {
- int switchNumber = switchInitialAngle ? -1 : 1;
- _initializeAngle = _initializeAngleVal * switchNumber;
- }
- }
- class RayFeature extends MeasureItemFeature {
- double _angle = 0;
- bool _isReverse = false;
- RayFeature(Ray refItem, DPoint point) : super(refItem) {
- innerPoints.add(point.clone());
- angle = refItem.initializeAngle;
- }
- DPoint get point => innerPoints[0];
- set point(DPoint value) {
- innerPoints[0] = value;
- }
- double get angle => _angle;
- set angle(double value) {
- if (value != _angle) {
- _angle = value;
- }
- }
- bool get isReverse => _isReverse;
- set isReverse(bool value) {
- if (value != _isReverse) {
- _isReverse = value;
- }
- }
- RectRegion get viewRegion => hostVisualArea!.viewport!.area.layoutRegion!;
- @override
- void paint(Canvas canvas, Size size) {
- if (innerPoints.isEmpty) return;
- final curItemName = refItem.displayName;
- final offset = convert2ViewPoint(size, point).toOffset();
- final rect = Rect.fromLTWH(
- viewRegion.left * size.width,
- viewRegion.top * size.height,
- viewRegion.width * size.width,
- viewRegion.height * size.height);
- List<Offset> twoPoint = [const Offset(0, 0), const Offset(0, 0)];
- final idText = '$id.${refItem.displayName}';
- switch (curItemName) {
- case "Baseline":
- twoPoint = calcLinePoint(rect, offset, 0);
- drawCustomId(canvas, size, twoPoint[1], idText);
- break;
- case "Line α":
- twoPoint = calcLinePoint(rect, offset, angle);
- drawCustomId(canvas, size, twoPoint[1], idText);
- break;
- case "Line β":
- twoPoint = calcLinePoint(rect, offset, 180 - angle);
- drawCustomId(canvas, size, twoPoint[0], idText);
- break;
- default:
- break;
- }
- canvas.drawDashLine(twoPoint[0], twoPoint[1], 1, 10, paintLinePan);
- }
- List<Offset> calcLinePoint(Rect rect, Offset innerPoint, double angle) {
- List<Offset> twoPoint = [const Offset(0, 0), const Offset(0, 0)];
- if (!rect.contains(innerPoint)) return twoPoint;
- final tan = math.tan(angle * math.pi / 180);
- final x = innerPoint.dx;
- final y = innerPoint.dy;
- final d1 = x - y / tan;
- twoPoint[0] = Offset(d1, 0);
- final d2 = (rect.height - y) / tan + x;
- twoPoint[1] = Offset(d2, rect.height);
- if (angle <= 90) {
- if (d1 < rect.left) {
- twoPoint[0] = Offset(rect.left, y - tan * (x - rect.left));
- }
- if (d2 > rect.right) {
- twoPoint[1] = Offset(rect.right, y + tan * (rect.right - x));
- }
- } else {
- if (d1 > rect.right) {
- twoPoint[0] = Offset(rect.right, y - tan * (x - rect.right));
- }
- if (d2 < rect.left) {
- twoPoint[1] = Offset(rect.left, y + tan * (rect.left - x));
- }
- }
- return twoPoint;
- }
- }
|