24 #include "delaunator-cpp/delaunator.hpp" 38 bool in_triangle(
const std::array<std::array<double,3>,3> &points,
39 const std::array<double,8> &precomputed,
40 const Point<2> &check_point,
41 double &interpolate_value,
42 double &interpolator_s,
43 double &interpolator_t)
48 const double s_no_area = -(precomputed[0] + precomputed[1]*check_point[0] + precomputed[2]*check_point[1]);
49 const double t_no_area = -(precomputed[3] + precomputed[4]*check_point[0] + precomputed[5]*check_point[1]);
51 if (s_no_area >= -factor*std::numeric_limits<double>::epsilon() && t_no_area >= -factor*std::numeric_limits<double>::epsilon() && s_no_area+t_no_area-precomputed[6]<=precomputed[6]*factor*std::numeric_limits<double>::epsilon())
54 interpolator_s = precomputed[7]*s_no_area;
55 interpolator_t = precomputed[7]*t_no_area;
56 interpolate_value = points[0][2]*(1-interpolator_s-interpolator_t)+points[1][2]*interpolator_s+points[2][2]*interpolator_t;
70 WBAssertThrow(!values_at_points.first.empty(),
"internal error: no values in values_at_points.first.");
71 minimum = values_at_points.first[0];
72 maximum = values_at_points.first[0];
74 for (
const auto &value: values_at_points.first)
88 if (!values_at_points.second.empty())
94 delaunator::Delaunator triangulation(values_at_points.second);
97 triangles.resize(triangulation.triangles.size()/3);
98 std::vector<KDTree::Node> node_list;
99 for (std::size_t i = 0; i < triangulation.triangles.size(); i+=3)
101 delaunator::Delaunator &t = triangulation;
107 triangles[i/3][0][0] = t.coords[2 * t.triangles[i]];
108 triangles[i/3][0][1] = t.coords[2 * t.triangles[i]+1];
109 triangles[i/3][0][2] = values_at_points.first[t.triangles[i]];
110 triangles[i/3][1][0] = t.coords[2 * t.triangles[i+1]];
111 triangles[i/3][1][1] = t.coords[2 * t.triangles[i+1]+1];
112 triangles[i/3][1][2] = values_at_points.first[t.triangles[i+1]];
113 triangles[i/3][2][0] = t.coords[2 * t.triangles[i+2]];
114 triangles[i/3][2][1] = t.coords[2 * t.triangles[i+2]+1];
115 triangles[i/3][2][2] = values_at_points.first[t.triangles[i+2]];
117 node_list.emplace_back(i/3,
118 (t.coords[2*t.triangles[i]]+t.coords[2*t.triangles[i+1]]+t.coords[2*t.triangles[i+2]])/3.,
119 (t.coords[2*t.triangles[i]+1]+t.coords[2*t.triangles[i+1]+1]+t.coords[2*t.triangles[i+2]+1])/3.);
134 in_triangle_precomputed[iii][3] = triangles[iii][0][0]*triangles[iii][1][1] - triangles[iii][0][1]*triangles[iii][1][0];
137 in_triangle_precomputed[iii][6] = -(-triangles[iii][1][1]*triangles[iii][2][0] + triangles[iii][0][1]*(-triangles[iii][1][0] + triangles[iii][2][0]) + triangles[iii][0][0]*(triangles[iii][1][1] - triangles[iii][2][1]) + triangles[iii][1][0]*triangles[iii][2][1]);
160 double interpolated_value = 0;
187 for (
const auto &index_distance: index_distances.
vector)
196 for (
auto &index_distance: index_distances_other.
vector)
211 return SurfaceValueInfo {nodes.index,interpolated_value,interpolator_s,interpolator_t};
215 return SurfaceValueInfo {nodes.index,interpolated_value,interpolator_s,interpolator_t};
218 WBAssertThrow(
false,
"Internal error: The requested point was not in any triangle. " 219 <<
"This could be due to rounding errors if the difference between the check point and triangle points are small, " 220 <<
"or you are requesting a point outside the boundaries defined by the additional points. The check point was " 221 << check_point[0] <<
":" << check_point[1] <<
".");
std::vector< IndexDistance > vector
std::vector< std::array< double, 8 > > in_triangle_precomputed
Stores precomputed values.
CoordinateSystem get_coordinate_system() const
const std::vector< Node > & get_nodes() const
void create_tree(const size_t left, const size_t right, const bool x_axis)
#define WBAssertThrow(condition, message)
SurfaceValueInfo local_value(const Point< 2 > &check_point) const
std::vector< std::array< std::array< double, 3 >, 3 > > triangles
IndexDistances find_closest_points(const Point< 2 > &check_point) const