mod_geo-tp/src/util.h

109 lines
2.4 KiB
C++

#ifndef UTIL_H
#define UTIL_H
#include "my_mesh.h"
#include <QVector3D>
#include <QtMath>
template <typename Mesh>
class HalfedgeLoopRange {
Mesh &mesh;
const typename Mesh::HalfedgeHandle &start;
public:
HalfedgeLoopRange(Mesh &mesh, const typename Mesh::HalfedgeHandle &start)
:mesh(mesh), start(start) {}
typename Mesh::HalfedgeLoopIter begin() {
return mesh.hl_begin(start);
}
typename Mesh::HalfedgeLoopIter end() {
return mesh.hl_end(start);
}
};
template <typename Mesh>
class ConstHalfedgeLoopRange {
Mesh &mesh;
const typename Mesh::HalfedgeHandle &start;
public:
ConstHalfedgeLoopRange(Mesh &mesh, const typename Mesh::HalfedgeHandle &start)
:mesh(mesh), start(start) {}
typename Mesh::HalfedgeLoopIter begin() {
return mesh.chl_begin(start);
}
typename Mesh::HalfedgeLoopIter end() {
return mesh.chl_end(start);
}
};
QDebug operator<<(QDebug dbg, const Point &p);
/* Returns the angle between the vector from p2 to p1 and the vector
* from p2 to p3. */
template <typename Point>
qreal angle_between(Point p1, Point p2, Point p3) {
Point vec_a = p1 - p2;
Point vec_b = p3 - p2;
return qAcos(vec_a.dot(vec_b) / (vec_a.norm() * vec_b.norm()));
}
template <typename Point>
qreal triangle_area(Point p1, Point p2, Point p3) {
Point vec_a = p1 - p2;
Point vec_b = p3 - p2;
return vec_a.cross(vec_b).norm() / 2.;
}
qreal cotan(const qreal x);
template <typename T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
if (v < lo) return lo;
if (v > hi) return hi;
return v;
}
template <typename ForwardIt>
constexpr typename ForwardIt::value_type average(const ForwardIt first,
const ForwardIt last) {
typedef typename ForwardIt::value_type value_type;
if (first == last) return 0;
value_type average = 0;
for (ForwardIt it = first; it != last; ++it) {
average += *it;
}
return average / (last - first);
}
template <typename ForwardIt>
constexpr typename ForwardIt::value_type
standard_deviation(const ForwardIt first,
const ForwardIt last,
typename ForwardIt::value_type average) {
typedef typename ForwardIt::value_type value_type;
if (first == last) return 0;
value_type accumulator = 0;
for (ForwardIt it = first; it != last; ++it) {
accumulator += (*it - average) * (*it - average);
}
return sqrt(accumulator / (last - first));
}
std::vector<std::vector<VertexHandle>> find_connected_components(
MyMesh &mesh);
#endif