import 'package:fis_measure/interfaces/date_types/point.dart'; import 'package:fis_measure/interfaces/process/items/terms.dart'; import 'package:fis_measure/process/primitives/area_abstract.dart'; import 'package:fis_measure/process/primitives/ellipse.dart'; import 'package:fis_measure/process/primitives/trace.dart'; import 'calculator.dart'; class AreaPerimeterEllipseCal extends Calculator { AreaPerimeterEllipseCal(Ellipse ref) : super(ref); @override void calculate() { if (ref.feature == null) return; final feature = ref.feature! as EllipseFeature; final viewport = feature.hostVisualArea!.viewport!; for (var output in ref.meta.outputs) { if (output.name == MeasureTerms.Perimeter) { var value = feature.getCircumference(viewport.convertBoundary); feature.updateFloatValue(output, value, output.unit); } else if (output.name == MeasureTerms.Area) { var value = feature.getArea(viewport.convertBoundary); feature.updateFloatValue(output, value, output.unit); } } } } class AreaPerimeterCal extends Calculator { AreaPerimeterCal(AreaItemAbstract ref) : super(ref); @override void calculate() { if (ref.feature == null) return; final feature = ref.feature!; final viewport = feature.hostVisualArea!.viewport!; final points = feature.innerPoints.map((e) => viewport.convert(e)).toList(); double area; double perimeter; if ((feature.splineTension - 0).abs() > 0) { // TODO: CreateSpline - Polyline.cs 850 perimeter = 0; area = 0; } else { double threshold = 0.0; // TODO: // if (ref.Threshold.HasValue) // { // threshold = ref.Threshold.Value; // } area = calcArea(points); perimeter = calcPerimeter(points, feature.isClosed, threshold); } for (var output in ref.meta.outputs) { if (output.name == MeasureTerms.Perimeter) { var value = roundDouble(perimeter, output.fractionalDigits); feature.updateFloatValue(output, value, output.unit); } else if (output.name == MeasureTerms.Area) { var value = roundDouble(area, output.fractionalDigits); feature.updateFloatValue(output, value, output.unit); } } // double value = clacArea(points); // updateFloatValue(value); } static double calcArea(List points) { if (points.isEmpty) { return 0; } double sum = 0; var ax = points[0].x; var ay = points[0].y; for (var i = 1; i < points.length - 1; i++) { var bx = points[i].x; var by = points[i].y; var cx = points[i + 1].x; var cy = points[i + 1].y; sum += ax * by - ay * bx + ay * cx - ax * cy + bx * cy - cx * by; } return (-sum / 2).abs(); } static double calcPerimeter( List points, bool isClosed, double threshold, ) { if (points.length < 2) { return 0; } double sum = 0; for (int i = 1, j = 0; j < points.length && i < points.length; i++) { var length = (points[i] - points[j]).length; if (length.abs() > threshold) { sum += length; j = i; } } if (isClosed) { sum += (points[points.length - 1] - points[0]).length; } return sum; } } class CurveLengthCal extends Calculator { CurveLengthCal(AreaItemAbstract ref) : super(ref); @override void calculate() { if (ref.feature == null) return; final feature = ref.feature!; final viewport = feature.hostVisualArea!.viewport!; final points = feature.innerPoints.map((e) => viewport.convert(e)).toList(); double threshold = 0; // if (ref.Threshold.HasValue) // { // threshold = ref.Threshold.Value; // } double perimeter = AreaPerimeterCal.calcPerimeter( points, ref.feature!.isClosed, threshold); updateFloatValue(perimeter, useRound: true); } }