1 #ifndef VTESTBED_GEOMETRY_TRIANGLE_HH 2 #define VTESTBED_GEOMETRY_TRIANGLE_HH 6 #include <vtestbed/geometry/math.hh> 7 #include <vtestbed/geometry/plane.hh> 8 #include <vtestbed/geometry/ray.hh> 9 #include <vtestbed/geometry/types.hh> 15 template <
class T,
int N>
22 static constexpr
const int dimensions = N;
23 using scalar_type = T;
24 using value_type =
typename base_type::value_type;
25 using pointer =
typename base_type::pointer;
26 using const_pointer =
typename base_type::const_pointer;
27 using reference =
typename base_type::reference;
28 using const_reference =
typename base_type::const_reference;
29 using iterator =
typename base_type::iterator;
30 using const_iterator =
typename base_type::const_iterator;
31 using size_type =
typename base_type::size_type;
32 using difference_type =
typename base_type::difference_type;
33 using reverse_iterator =
typename base_type::reverse_iterator;
34 using const_reverse_iterator =
typename base_type::const_reverse_iterator;
37 using base_type::base_type;
38 using base_type::operator=;
39 using base_type::operator[];
44 Triangle(const_reference p0, const_reference p1, const_reference p2):
47 inline void flip() { std::swap(this->front(), this->back()); }
48 inline void reverse() { this->flip(); }
49 inline void invert() { this->flip(); }
54 bool degenerate(scalar_type eps)
const;
61 template <
class T,
int N>
71 return dot(tr[2], cross(tr[0], tr[1])) / T{6};
86 template <
class T,
int N>
89 using vec = Vertex<T,N>;
90 vec e1{triangle[1] - triangle[0]}, e2{triangle[2] - triangle[0]};
91 vec n{cross(ray.direction(), e2)};
93 if (std::abs(det) < eps) {
97 vec tvec{ray.origin() - triangle[0]};
98 T u = dot(tvec, n) * rdet;
99 if (u < T{0} || u > T{1}) {
102 vec qvec{cross(tvec, e1)};
103 T v = dot(ray.direction(), qvec) * rdet;
104 if (v < T{0} || u+v > T{1}) {
110 template <
class T,
int N>
111 inline Vertex<Plane_position,3>
112 compare(
const Plane<T,N> plane,
const Triangle<T,N>& triangle, T eps) {
113 Vertex<Plane_position,3> order;
114 for (
int i=0; i<3; ++i) {
115 order(i) = compare(plane, triangle[i], eps);
120 template <
class T,
int N>
123 const Plane<T,N>& plane,
124 const Triangle<T,N>& triangle,
125 const Vertex<Plane_position,3>& positions,
130 template <
class T,
int N>
132 centroid(
const Triangle<T,N>& t) {
133 return (t[0]+t[1]+t[2])/T{3};
136 template <
class T,
int N>
138 area(
const Triangle<T,N>& t) {
139 Vertex<T,N> e1 = t[1] - t[0];
140 Vertex<T,N> e2 = t[2] - t[0];
146 surface_normal(
const Triangle<T,3>& t) {
147 return surface_normal(t[0],t[1],t[2]);
154 #endif // vim:filetype=cpp
A polygon composed of line segments.
bool intersect(const Ray< T, N > &ray, const Triangle< T, N > &triangle, T eps)
Check if ray intersects triangle.
TinyVector< T, 1 > cross(const TinyVector< T, 2 > &a, const TinyVector< T, 2 > &b)
Two-dimensional cross product.
T length(const blitz::TinyVector< T, N > &x)
Computes vector length without overflow.
T tetrahedron_signed_volume(const Triangle< T, 3 > &tr)
Signed volume of a tetrahedron with the origin .
Three- and two-dimensional plane.