You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
6.9 KiB
C

1 month ago
/*------------------------------------------------------------------------------
* Copyright (c) 2023 by Bai Bing (seread@163.com)
* See COPYING file for copying and redistribution conditions.
*
* Alians IT Studio.
*----------------------------------------------------------------------------*/
#pragma once
#include <algorithm>
#include <execution>
#include <list>
#include <utility>
#include <vector>
#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 <class PT = ais::Point>
AIS_EXPORT std::vector<double> getAxisValues(const std::vector<PT> &pointList, Axis3DType axis)
{
std::vector<double> axisValues;
for (auto &p : pointList)
{
if (axis == Axis3DType::Z)
{
if constexpr (ais::all_same_v<PT, ais::PointXYZ>)
{
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 <class dt>
AIS_EXPORT std::pair<dt, dt> getMinMax(const std::vector<dt> &points)
{
const auto [minp, maxp] = std::minmax_element(std::execution::par_unseq, points.begin(), points.end());
return std::pair<dt, dt>(*minp, *maxp);
}
//================================================================
//
/// get min and max values from point matrix
/// @param matrix matrix of point values
///
template <class dt = double>
AIS_EXPORT std::pair<dt, dt> getMinMax(const ais::Matrix<dt> &matrix)
{
const auto [minp, maxp] = std::minmax_element(std::execution::par_unseq, matrix.begin(), matrix.end());
return std::pair<dt, dt>(*minp, *maxp);
}
//================================================================
//
/// get average values from list
/// @param matrix matrix of point values
///
template <typename DC>
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 <typename DC>
AIS_EXPORT double get_idw(const DC &list)
{
double ret = INFINITY;
double sum = 0.0;
double denominator = 0.0;
std::pair<double, double> 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 <typename DC>
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<double, double> 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 <typename DC>
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<double> 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<ais::PointXYZ> filter_points(const std::vector<ais::Point> &areaPoints, const std::vector<ais::PointXYZ> &samplePoints);
//================================================================
//
/// filter and copy sample points which include in the target area points
///
AIS_EXPORT void filter_copy_points(const std::pair<double, double> &minPos, const std::pair<double, double> &maxPos,
const std::vector<ais::PointXYZ> &samplePoints,
std::vector<ais::PointXYZ> &outputPoints);
}