|
@@ -10,7 +10,6 @@ import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
|
|
|
import 'package:fis_measure/process/calcuators/calculator.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 TwolineAngle extends MeasureItem<TwolineAngleFeature> {
|
|
@@ -55,10 +54,73 @@ class TwolineAngle extends MeasureItem<TwolineAngleFeature> {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ DPoint lastStartPoint = DPoint(0, 0); // 上一个起点
|
|
|
+ bool isFirstPointNeedOffset = false; // 第一个点是否需要施加偏移
|
|
|
+ DPoint splineTouchStartPoint = DPoint(0, 0); // 轨迹触摸起始点
|
|
|
+ bool isOtherPointNeedOffset = false; // 其他点是否需要施加偏移
|
|
|
@override
|
|
|
bool onExecuteTouch(PointInfo args) {
|
|
|
- // TODO: implement onExecuteTouch
|
|
|
- throw UnimplementedError();
|
|
|
+ if (state == ItemStates.finished) {
|
|
|
+ if (args.pointType == PointInfoType.touchDown) {
|
|
|
+ state = ItemStates.waiting;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state == ItemStates.waiting) {
|
|
|
+ if (isFirstPointNeedOffset) args.addOffset(0, -0.2);
|
|
|
+ switch (args.pointType) {
|
|
|
+ case PointInfoType.touchDown:
|
|
|
+ handleTouchDownWhileWaiting(args);
|
|
|
+ isFirstPointNeedOffset = false;
|
|
|
+ break;
|
|
|
+ case PointInfoType.touchUp:
|
|
|
+ lastStartPoint = args; // 设置线段起点
|
|
|
+ state = ItemStates.running;
|
|
|
+ feature?.innerPoints.first = args;
|
|
|
+ break; // 按下立即抬起无事发生
|
|
|
+ case PointInfoType.touchMove:
|
|
|
+ isFirstPointNeedOffset = true;
|
|
|
+ feature?.innerPoints.first = args;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else if (state == ItemStates.running) {
|
|
|
+ final f = feature!;
|
|
|
+ if (isOtherPointNeedOffset && f.innerPoints.length == 3) {
|
|
|
+ args.addOffset(0, -0.2);
|
|
|
+ }
|
|
|
+ if (feature == null) return false;
|
|
|
+ DPoint newPoint =
|
|
|
+ lastStartPoint.clone().addVector(args - splineTouchStartPoint);
|
|
|
+ if (args.pointType == PointInfoType.touchUp) {
|
|
|
+ if (!isOtherPointNeedOffset) {
|
|
|
+ f.innerPoints.last = args;
|
|
|
+ lastStartPoint = args;
|
|
|
+ doCalculate();
|
|
|
+ } else {
|
|
|
+ lastStartPoint = newPoint;
|
|
|
+ }
|
|
|
+ if (f.innerPoints.length == 4) {
|
|
|
+ doFeatureFinish();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (args.pointType == PointInfoType.touchDown) {
|
|
|
+ isOtherPointNeedOffset = false;
|
|
|
+ splineTouchStartPoint = args;
|
|
|
+ f.innerPoints.add(lastStartPoint);
|
|
|
+ if (f.innerPoints.length == 3) {
|
|
|
+ lastStartPoint = args;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (args.pointType == PointInfoType.touchMove) {
|
|
|
+ isOtherPointNeedOffset = true;
|
|
|
+ f.innerPoints.last = newPoint;
|
|
|
+ }
|
|
|
+ doCalculate();
|
|
|
+ }
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
void handleMouseDownWhileWaiting(PointInfo args) {
|
|
@@ -71,6 +133,16 @@ class TwolineAngle extends MeasureItem<TwolineAngleFeature> {
|
|
|
}
|
|
|
state = ItemStates.running;
|
|
|
}
|
|
|
+
|
|
|
+ void handleTouchDownWhileWaiting(PointInfo args) {
|
|
|
+ // TODO: 判断是否当前area
|
|
|
+ // 转换为Area逻辑位置
|
|
|
+ final point = args.toAreaLogicPoint();
|
|
|
+ feature = TwolineAngleFeature.withOneStartPoint(this, point);
|
|
|
+ if (args.hostVisualArea != null) {
|
|
|
+ feature!.hostVisualArea = args.hostVisualArea;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
class TwolineAngleFeature extends MeasureItemFeature {
|
|
@@ -78,6 +150,10 @@ class TwolineAngleFeature extends MeasureItemFeature {
|
|
|
innerPoints.add(point.clone());
|
|
|
innerPoints.add(point.clone());
|
|
|
}
|
|
|
+ TwolineAngleFeature.withOneStartPoint(IMeasureItem refItem, DPoint point)
|
|
|
+ : super(refItem) {
|
|
|
+ innerPoints.add(point.clone());
|
|
|
+ }
|
|
|
@override
|
|
|
void paint(Canvas canvas, Size size) {
|
|
|
if (innerPoints.isEmpty) return;
|
|
@@ -85,11 +161,19 @@ class TwolineAngleFeature extends MeasureItemFeature {
|
|
|
final innerOffsets =
|
|
|
innerPoints.map((e) => convert2ViewPoint(size, e).toOffset()).toList();
|
|
|
final len = innerOffsets.length;
|
|
|
- if (len == 2 || len == 3) {
|
|
|
+
|
|
|
+ if (len == 1) {
|
|
|
+ drawVertex(canvas, innerOffsets[0]);
|
|
|
+ } else if (len == 2) {
|
|
|
final a = innerOffsets[0];
|
|
|
final b = innerOffsets[1];
|
|
|
canvas.drawLine(a, b, paintLinePan);
|
|
|
- } else if (len >= 4) {
|
|
|
+ } else if (len == 3) {
|
|
|
+ final a = innerOffsets[0];
|
|
|
+ final b = innerOffsets[1];
|
|
|
+ canvas.drawLine(a, b, paintLinePan);
|
|
|
+ drawVertex(canvas, innerOffsets[2]);
|
|
|
+ } else if (len == 4) {
|
|
|
final a = innerOffsets[0];
|
|
|
final b = innerOffsets[1];
|
|
|
final c = innerOffsets[2];
|
|
@@ -104,24 +188,30 @@ class TwolineAngleFeature extends MeasureItemFeature {
|
|
|
//计算射线cd的角度
|
|
|
final vecBAngle = vecB.angleToSigned(Vector2(1, 0));
|
|
|
// 计算射线ab与射线cd的交点
|
|
|
- final p = _getIntersection(a, b, c, d);
|
|
|
- // 绘制角度
|
|
|
- canvas.drawArc(Rect.fromCircle(center: p, radius: 30), -vecBAngle, -angle,
|
|
|
- false, paintLinePan);
|
|
|
- //如果交点在线段外,线段要延长至交点
|
|
|
- Offset p1 = _getIntersection(a, b, p, Offset(0, p.dy));
|
|
|
- final vecA1 = Vector2(p1.dx - a.dx, p1.dy - a.dy).normalized() * 50;
|
|
|
- p1 += Offset(vecA1.x, vecA1.y);
|
|
|
- Offset p2 = _getIntersection(c, d, p, Offset(0, p.dy));
|
|
|
- final vecB1 = Vector2(p2.dx - c.dx, p2.dy - c.dy).normalized() * 50;
|
|
|
- p2 += Offset(vecB1.x, vecB1.y);
|
|
|
- canvas.drawLine(a, p1, paintLinePan);
|
|
|
- canvas.drawLine(c, p2, paintLinePan);
|
|
|
+ final Offset? p = _getIntersection(a, b, c, d);
|
|
|
+ if (p != null) {
|
|
|
+ // 绘制角度
|
|
|
+ canvas.drawArc(Rect.fromCircle(center: p, radius: 30), -vecBAngle,
|
|
|
+ -angle, false, paintLinePan);
|
|
|
+ //如果交点在线段外,线段要延长至交点
|
|
|
+ Offset? p1 = _getIntersection(a, b, p, Offset(0, p.dy));
|
|
|
+ if (p1 != null) {
|
|
|
+ final vecA1 = Vector2(p1.dx - a.dx, p1.dy - a.dy).normalized() * 50;
|
|
|
+ p1 += Offset(vecA1.x, vecA1.y);
|
|
|
+ canvas.drawLine(a, p1, paintLinePan);
|
|
|
+ }
|
|
|
+ Offset? p2 = _getIntersection(c, d, p, Offset(0, p.dy));
|
|
|
+ if (p2 != null) {
|
|
|
+ final vecB1 = Vector2(p2.dx - c.dx, p2.dy - c.dy).normalized() * 50;
|
|
|
+ p2 += Offset(vecB1.x, vecB1.y);
|
|
|
+ canvas.drawLine(c, p2, paintLinePan);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// 计算射线ab与射线cd的交点
|
|
|
- Offset _getIntersection(Offset a, Offset b, Offset c, Offset d) {
|
|
|
+ Offset? _getIntersection(Offset a, Offset b, Offset c, Offset d) {
|
|
|
final x1 = a.dx;
|
|
|
final y1 = a.dy;
|
|
|
final x2 = b.dx;
|
|
@@ -130,12 +220,21 @@ class TwolineAngleFeature extends MeasureItemFeature {
|
|
|
final y3 = c.dy;
|
|
|
final x4 = d.dx;
|
|
|
final y4 = d.dy;
|
|
|
+
|
|
|
+ final denominator = ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
|
|
|
+
|
|
|
+ // 检查分母是否为零,即两条射线是否平行
|
|
|
+ if (denominator == 0) {
|
|
|
+ return null; // 无交点
|
|
|
+ }
|
|
|
+
|
|
|
final x =
|
|
|
((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) /
|
|
|
- ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
|
|
|
+ denominator;
|
|
|
final y =
|
|
|
((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) /
|
|
|
- ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
|
|
|
+ denominator;
|
|
|
+
|
|
|
return Offset(x, y);
|
|
|
}
|
|
|
}
|