/*------------------------------------------------------------------------------ * Copyright (c) 2023 by Bai Bing (seread@163.com) * See COPYING file for copying and redistribution conditions. * * Alians IT Studio. *----------------------------------------------------------------------------*/ #pragma once #include #include #include #include #include #include "_Define.h" #include "ASPoint.h" #include "ASMatrix.h" #include "core/Error.h" namespace ais { /// Enum To describe an axis enum class Axis3DType : int { X = 0, Y, Z }; //================================================================ // /// get point list for specified axis /// @param pointList vector list for ais::Point or ais::PointXYZ /// @param axis for target axis, must be Axis3DType::X, Axis3DType::Y, Axis3DType::Z /// template AIS_EXPORT std::vector getAxisValues(const std::vector &pointList, Axis3DType axis) { std::vector axisValues; for (auto &p : pointList) { if (axis == Axis3DType::Z) { if constexpr (ais::all_same_v) { axisValues.push_back(p.z); } else THROW_INVALID_ARGUMENT("PointList not contains z axis values."); } else axisValues.push_back(axis == Axis3DType::Y ? p.y : p.x); } return axisValues; } //================================================================ // /// get min and max values from point list /// @param points list of points /// template AIS_EXPORT std::pair getMinMax(const std::vector
&points) { const auto [minp, maxp] = std::minmax_element(std::execution::par_unseq, points.begin(), points.end()); return std::pair(*minp, *maxp); } //================================================================ // /// get min and max values from point matrix /// @param matrix matrix of point values /// template AIS_EXPORT std::pair getMinMax(const ais::Matrix
&matrix) { const auto [minp, maxp] = std::minmax_element(std::execution::par_unseq, matrix.begin(), matrix.end()); return std::pair(*minp, *maxp); } //================================================================ // /// get average values from list /// @param matrix matrix of point values /// template AIS_EXPORT double getAverage(const DC &list) { double ret = INFINITY; double sum = 0.0; size_t count = 0; for (auto &value : list) { if (!std::isnan(value) && !std::isinf(value)) { count++; sum += value; } } ret = count == 0 ? INFINITY : sum / count; return ret; } //================================================================ // /// get inverse distance weighting average values from list /// @param matrix matrix of point values /// template AIS_EXPORT double get_idw(const DC &list) { double ret = INFINITY; double sum = 0.0; double denominator = 0.0; std::pair nearestWeight{1e+10, 0}; for (auto &dv_pair : list) { if (nearestWeight.first > dv_pair.first) nearestWeight = dv_pair; } for (auto &dv_pair : list) { auto [distance, value] = dv_pair; if (std::abs(distance) < 1e-6) return value; double weight = 1 / (distance * distance); sum += weight * value; denominator += weight; } ret = std::abs(denominator) < 1e-6 ? INFINITY : sum / denominator; return ret; } //================================================================ // /// get mean values from list /// @param matrix matrix of point values /// template AIS_EXPORT double get_mean(const DC &list, size_t top = 0) { double ret = INFINITY; double sum = 0.0; double denominator = 0.0; std::pair nearestWeight{1e+10, 0}; for (auto &dv_pair : list) { if (nearestWeight.first > dv_pair.first) nearestWeight = dv_pair; } size_t count = 0; for (auto &dv_pair : list) { if (top > 0 && count > top) break; auto [distance, value] = dv_pair; if (std::abs(distance) < 1e-6) return value; if (std::isnan(value) || std::isinf(value)) continue; sum += value; denominator += 1; count++; } ret = std::abs(denominator) < 1e-6 ? INFINITY : sum / denominator; return ret; } //================================================================ // /// get mean values from list /// @param matrix matrix of point values /// template AIS_EXPORT double get_weight_mean(const DC &list, size_t top = 0) { double ret = INFINITY; double sum = 0.0; double denominator = 0.0; size_t count = 0; for (auto &dv_pair : list) { if (top > 0 && count > top) break; auto [weight, value] = dv_pair; if (std::isnan(value) || std::isinf(value)) continue; sum += value * weight; denominator += weight; count++; } ret = std::abs(denominator) < 1e-6 ? INFINITY : sum / denominator; return ret; } //================================================================ // /// generate axis values from start to end, point count = grid count + 1 /// AIS_EXPORT std::vector generateAxisPoints(double start, double end, size_t pointCount); //================================================================ // /// filter sample points which include in the target area points, out of the range will be erased /// AIS_EXPORT std::vector filter_points(const std::vector &areaPoints, const std::vector &samplePoints); //================================================================ // /// filter and copy sample points which include in the target area points /// AIS_EXPORT void filter_copy_points(const std::pair &minPos, const std::pair &maxPos, const std::vector &samplePoints, std::vector &outputPoints); }