You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
4.3 KiB
149 lines
4.3 KiB
3 months ago
|
// David Eberly, Geometric Tools, Redmond WA 98052
|
||
|
// Copyright (c) 1998-2021
|
||
|
// Distributed under the Boost Software License, Version 1.0.
|
||
|
// https://www.boost.org/LICENSE_1_0.txt
|
||
|
// https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
|
||
|
// Version: 4.0.2019.08.13
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <Mathematics/Hyperplane.h>
|
||
|
#include <Mathematics/Vector3.h>
|
||
|
|
||
|
// The tetrahedron is represented as an array of four vertices: V0, V1, V2,
|
||
|
// and V3. The vertices are ordered so that the triangular faces are
|
||
|
// counterclockwise-ordered triangles when viewed by an observer outside the
|
||
|
// tetrahedron:
|
||
|
// face 0 = <V[0],V[2],V[1]>
|
||
|
// face 1 = <V[0],V[1],V[3]>
|
||
|
// face 2 = <V[0],V[3],V[2]>
|
||
|
// face 3 = <V[1],V[2],V[3]>
|
||
|
|
||
|
namespace gte
|
||
|
{
|
||
|
template <typename Real>
|
||
|
class Tetrahedron3
|
||
|
{
|
||
|
public:
|
||
|
// Construction and destruction. The default constructor sets the
|
||
|
// vertices to (0,0,0), (1,0,0), (0,1,0), and (0,0,1).
|
||
|
Tetrahedron3()
|
||
|
:
|
||
|
v{ Vector3<Real>::Zero(), Vector3<Real>::Unit(0),
|
||
|
Vector3<Real>::Unit(1), Vector3<Real>::Unit(2) }
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Tetrahedron3(Vector3<Real> const& v0, Vector3<Real> const& v1,
|
||
|
Vector3<Real> const& v2, Vector3<Real> const& v3)
|
||
|
:
|
||
|
v{ v0, v1, v2, v3 }
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Tetrahedron3(std::array<Vector3<Real>, 4> const& inV)
|
||
|
:
|
||
|
v(inV)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
// Get the vertex indices for the specified face. The input 'face'
|
||
|
// must be in {0,1,2,3}.
|
||
|
void GetFaceIndices(int face, int index[3]) const
|
||
|
{
|
||
|
if (face == 0)
|
||
|
{
|
||
|
index[0] = 0;
|
||
|
index[1] = 2;
|
||
|
index[2] = 1;
|
||
|
}
|
||
|
else if (face == 1)
|
||
|
{
|
||
|
index[0] = 0;
|
||
|
index[1] = 1;
|
||
|
index[2] = 3;
|
||
|
}
|
||
|
else if (face == 2)
|
||
|
{
|
||
|
index[0] = 0;
|
||
|
index[1] = 3;
|
||
|
index[2] = 2;
|
||
|
}
|
||
|
else // face == 3 (no index validation is performed)
|
||
|
{
|
||
|
index[0] = 1;
|
||
|
index[1] = 2;
|
||
|
index[2] = 3;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Construct the planes of the faces. The planes have outer pointing
|
||
|
// normal vectors. The plane indexing is the same as the face
|
||
|
// indexing mentioned previously.
|
||
|
void GetPlanes(Plane3<Real> plane[4]) const
|
||
|
{
|
||
|
Vector3<Real> edge10 = v[1] - v[0];
|
||
|
Vector3<Real> edge20 = v[2] - v[0];
|
||
|
Vector3<Real> edge30 = v[3] - v[0];
|
||
|
Vector3<Real> edge21 = v[2] - v[1];
|
||
|
Vector3<Real> edge31 = v[3] - v[1];
|
||
|
|
||
|
plane[0].normal = UnitCross(edge20, edge10); // <v0,v2,v1>
|
||
|
plane[1].normal = UnitCross(edge10, edge30); // <v0,v1,v3>
|
||
|
plane[2].normal = UnitCross(edge30, edge20); // <v0,v3,v2>
|
||
|
plane[3].normal = UnitCross(edge21, edge31); // <v1,v2,v3>
|
||
|
|
||
|
Real det = Dot(edge10, plane[3].normal);
|
||
|
if (det < (Real)0)
|
||
|
{
|
||
|
// The normals are inner pointing, reverse their directions.
|
||
|
for (int i = 0; i < 4; ++i)
|
||
|
{
|
||
|
plane[i].normal = -plane[i].normal;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < 4; ++i)
|
||
|
{
|
||
|
plane[i].constant = Dot(v[i], plane[i].normal);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Public member access.
|
||
|
std::array<Vector3<Real>, 4> v;
|
||
|
|
||
|
public:
|
||
|
// Comparisons to support sorted containers.
|
||
|
bool operator==(Tetrahedron3 const& tetrahedron) const
|
||
|
{
|
||
|
return v == tetrahedron.v;
|
||
|
}
|
||
|
|
||
|
bool operator!=(Tetrahedron3 const& tetrahedron) const
|
||
|
{
|
||
|
return v != tetrahedron.v;
|
||
|
}
|
||
|
|
||
|
bool operator< (Tetrahedron3 const& tetrahedron) const
|
||
|
{
|
||
|
return v < tetrahedron.v;
|
||
|
}
|
||
|
|
||
|
bool operator<=(Tetrahedron3 const& tetrahedron) const
|
||
|
{
|
||
|
return v <= tetrahedron.v;
|
||
|
}
|
||
|
|
||
|
bool operator> (Tetrahedron3 const& tetrahedron) const
|
||
|
{
|
||
|
return v > tetrahedron.v;
|
||
|
}
|
||
|
|
||
|
bool operator>=(Tetrahedron3 const& tetrahedron) const
|
||
|
{
|
||
|
return v >= tetrahedron.v;
|
||
|
}
|
||
|
};
|
||
|
}
|