https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PointReduction.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "PointReduction.h"
11#include "MooseUtils.h"
12#include "MooseError.h"
13
14#include <algorithm>
15#include <cmath>
16
17namespace PointReduction
18{
19
20Real
21sqr(Real a)
22{
23 mooseDeprecated("use PointReduction::square() instead");
24 return a * a;
25}
26
27Real
28square(Real a)
29{
30 return a * a;
31}
32
33Real
35 const FunctionNode & begin,
36 const FunctionNode & end)
37{
38 const Real x0 = node.first;
39 const Real y0 = node.second;
40 const Real x1 = begin.first;
41 const Real y1 = begin.second;
42 const Real x2 = end.first;
43 const Real y2 = end.second;
44
45 const Real denom = std::sqrt(square(y2 - y1) + square(x2 - x1));
46 mooseAssert(MooseUtils::absoluteFuzzyGreaterThan(denom, 0.0),
47 "Line begin and end points must not be the same");
48
49 return std::abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) / denom;
50}
51
52void
54 const Real epsilon,
55 std::vector<bool> & keep,
56 std::size_t begin,
57 std::size_t end)
58{
59 // Find the point with the maximum distance from the line defined by begin and end
60 Real dmax = 0.0;
61 std::size_t index = 0;
62
63 for (std::size_t i = begin; i <= end; ++i)
64 if (keep[i])
65 {
66 const Real d = perpendicularDistance(list[i], list[begin], list[end]);
67 if (d > dmax)
68 {
69 index = i;
70 dmax = d;
71 }
72 }
73
74 // If max distance is greater than epsilon, recursively simplify
75 if (dmax > epsilon)
76 {
77 // Recursive call
78 douglasPeuckerRecurse(list, epsilon, keep, begin, index);
79 douglasPeuckerRecurse(list, epsilon, keep, index, end);
80 }
81 else
82 {
83 // remove all points between begin and end
84 for (std::size_t i = begin + 1; i < end; ++i)
85 keep[i] = false;
86 }
87}
88
90douglasPeucker(const FunctionNodeList & list, const Real epsilon)
91{
92 // set up keep list for function nodes
93 std::vector<bool> keep(list.size(), true);
94 douglasPeuckerRecurse(list, epsilon, keep, 0, list.size() - 1);
95
96 FunctionNodeList result;
97 result.reserve(std::count_if(keep.begin(), keep.end(), [](bool k) { return k; }));
98
100 for (std::size_t i = 0; i < list.size(); ++i)
101 if (keep[i])
102 result.push_back(list[i]);
103
104 return result;
105}
106
107} // namespace PointReduction
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition MooseError.h:363
std::vector< FunctionNode > FunctionNodeList
Real sqr(Real a)
libMesh::Real perpendicularDistance(const FunctionNode &point, const FunctionNode &begin, const FunctionNode &end)
compute the perpendicular distance of a point P from a line defined by begin and end points.
std::pair< libMesh::Real, libMesh::Real > FunctionNode
Real square(Real a)
FunctionNodeList douglasPeucker(const FunctionNodeList &, libMesh::Real epsilon)
Generate a pruned function node list using the Ramer-Douglas-Peucker algorithm.
void douglasPeuckerRecurse(const FunctionNodeList &list, const Real epsilon, std::vector< bool > &keep, std::size_t begin, std::size_t end)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real