Newer
Older
* Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*/
#include <cstddef>
namespace MathLib
{
template <typename T, std::size_t DIM> class TemplatePoint;
using Point3d = MathLib::TemplatePoint<double, 3>;
enum TriangleTest
{
GAUSS, BARYCENTRIC
};
/**
* Checks if a point p is on the left or right side of a plane spanned by three
* points a, b, c.
* @param p point to test
* @param a first point on plane
* @param b second point on plane
* @param c third point on plane
* @return If the triangle abc is ordered counterclockwise when viewed from p,
* the method will return a negative value,
* otherwise it will return a positive value. If p is coplanar with abc, the
* function will return 0.
*/
double orientation3d(MathLib::Point3d const& p,
MathLib::Point3d const& a,
MathLib::Point3d const& b,
MathLib::Point3d const& c);
/**
* Calculates the volume of a tetrahedron.
* The formula is V=1/6*|a(b x c)| with a=x1->x2, b=x1->x3 and c=x1->x4.
*/
double calcTetrahedronVolume(MathLib::Point3d const& a,
MathLib::Point3d const& b,
MathLib::Point3d const& c,
MathLib::Point3d const& d);
/**
* Calculates the area of the triangle defined by its edge nodes a, b and c.
* The formula is \f$A= \frac{1}{2} \cdot |u \times v|\f$, i.e. half of the area of the
* parallelogram specified by the vectors\f$u=b-a\f$ and \f$v=c-a\f$.
*/
double calcTriangleArea(MathLib::Point3d const& a, MathLib::Point3d const& b,
MathLib::Point3d const& c);
/**
* Tests if the given point p is located within a tetrahedron spanned by points
* a, b, c, d.
* If the tet specified by a, b, c, d is degenerated (i.e. all points are
* coplanar) the function
* will return false because there is no meaningful concept of "inside" for such
* elements.
* @param p test point
* @param a edge node of tetrahedron
* @param b edge node of tetrahedron
* @param c edge node of tetrahedron
* @param d edge node of tetrahedron
* @param eps Accounts for numerical inaccuracies by allowing a point to be
* slightly outside of the element and still be regarded as inside.
* @return true if the test point p is not located outside of abcd (i.e. inside
* or on a plane/edge).
*/
bool isPointInTetrahedron(MathLib::Point3d const& p, MathLib::Point3d const& a,
MathLib::Point3d const& b, MathLib::Point3d const& c,
MathLib::Point3d const& d,
double eps = std::numeric_limits<double>::epsilon());
/**
* Tests if the given point p is within the triangle, defined by its edge nodes
* a, b and c.Using two eps-values it is possible to test an 'epsilon'
* neighbourhood around the triangle as well as an 'epsilon' outside the
* triangles plane.
* @param p test point
* @param a edge node of triangle
* @param b edge node of triangle
* @param c edge node of triangle
* @param eps_pnt_out_of_plane eps allowing for p to be slightly off the plane
* spanned by abc
* @param eps_pnt_out_of_tri eps allowing for p to be slightly off outside of
* abc
* @param algorithm defines the method to use
* @return true if the test point p is within the 'epsilon'-neighbourhood of the
* triangle
*/
bool isPointInTriangle(
MathLib::Point3d const& p,
MathLib::Point3d const& a,
MathLib::Point3d const& b,
MathLib::Point3d const& c,
double eps_pnt_out_of_plane = std::numeric_limits<float>::epsilon(),
double eps_pnt_out_of_tri = std::numeric_limits<float>::epsilon(),
MathLib::TriangleTest algorithm = MathLib::GAUSS);
/**
* Tests if the given point q is within the triangle, defined by its edge nodes
* a, b and c.
* Using two eps-values it is possible to test an 'epsilon' neighbourhood around
* the triangle
* as well as an 'epsilon' outside the triangles plane.
* @param a edge node of triangle
* @param b edge node of triangle
* @param c edge node of triangle
* @param eps_pnt_out_of_plane eps allowing for p to be slightly off the plane
* spanned by abc ((orthogonal distance to the plane spaned by triangle)
* @param eps_pnt_out_of_tri eps allowing for p to be slightly off outside of
* abc
* @return true if the test point p is within the 'epsilon'-neighbourhood of the
* triangle
*/
bool gaussPointInTriangle(
MathLib::Point3d const& q, MathLib::Point3d const& a,
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
MathLib::Point3d const& b, MathLib::Point3d const& c,
double eps_pnt_out_of_plane = std::numeric_limits<float>::epsilon(),
double eps_pnt_out_of_tri = std::numeric_limits<float>::epsilon());
/**
* Tests if the given point p is within the triangle, defined by its edge nodes
* a, b and c.
* Using two eps-values it is possible to test an 'epsilon' neighbourhood around
* the triangle
* as well as an 'epsilon' outside the triangles plane.
* Algorithm based on "Fundamentals of Computer Graphics" by Peter Shirley.
* @param p test point
* @param a edge node of triangle
* @param b edge node of triangle
* @param c edge node of triangle
* @param eps_pnt_out_of_plane eps allowing for p to be slightly off the plane
* spanned by abc
* @param eps_pnt_out_of_tri eps allowing for p to be slightly off outside of
* abc
* @return true if the test point p is within the 'epsilon'-neighbourhood of the
* triangle
*/
bool barycentricPointInTriangle(
MathLib::Point3d const& p, MathLib::Point3d const& a,
MathLib::Point3d const& b, MathLib::Point3d const& c,
double eps_pnt_out_of_plane = std::numeric_limits<float>::epsilon(),
double eps_pnt_out_of_tri = std::numeric_limits<float>::epsilon());
/// Checks if the point \f$p'\f$ is in the triangle defined by the points
/// \f$a', b', c'\f$, where the \f$p', a', b', c' \f$ are the orthogonal
/// projections to the \f$x\f$-\f$y\f$ plane of the points \f$p, a, b, c\f$,
/// respectively.
bool isPointInTriangleXY(MathLib::Point3d const& p, MathLib::Point3d const& a,
MathLib::Point3d const& b, MathLib::Point3d const& c);
/**
* Checks if a and b can be placed on a plane such that c and d lie on different
* sides of said plane. (In 2D space this checks if c and d are on different
* sides of a line through a and b.)
* @param a first point on plane
* @param b second point on plane
* @param c first point to test
* @param d second point to test
* @return true, if such a plane can be found, false otherwise
*/
bool dividedByPlane(const MathLib::Point3d& a, const MathLib::Point3d& b,
const MathLib::Point3d& c, const MathLib::Point3d& d);
/// Checks if the four given points are located on a plane.
bool isCoplanar(const MathLib::Point3d& a, const MathLib::Point3d& b,
const MathLib::Point3d& c, const MathLib::Point3d& d);
} // end namespace MathLib