preCICE v3.1.1
Loading...
Searching...
No Matches
Triangle.cpp
Go to the documentation of this file.
1#include "Triangle.hpp"
2#include <Eigen/Core>
3#include <Eigen/Dense>
4#include <Eigen/Geometry>
5#include <algorithm>
6#include <boost/concept/assert.hpp>
7#include <boost/range/concepts.hpp>
8#include <iterator>
10#include "math/geometry.hpp"
11#include "mesh/Edge.hpp"
12#include "mesh/Vertex.hpp"
13#include "utils/EigenIO.hpp"
14#include "utils/assertion.hpp"
15
16namespace precice::mesh {
17
18BOOST_CONCEPT_ASSERT((boost::RandomAccessIteratorConcept<Triangle::iterator>) );
19BOOST_CONCEPT_ASSERT((boost::RandomAccessIteratorConcept<Triangle::const_iterator>) );
20BOOST_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<Triangle>) );
21BOOST_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<const Triangle>) );
22
24 Edge &edgeOne,
25 Edge &edgeTwo,
26 Edge &edgeThree)
27{
28 PRECICE_ASSERT(edgeOne.getDimensions() == edgeTwo.getDimensions(),
29 edgeOne.getDimensions(), edgeTwo.getDimensions());
30 PRECICE_ASSERT(edgeTwo.getDimensions() == edgeThree.getDimensions(),
31 edgeTwo.getDimensions(), edgeThree.getDimensions());
32
33 PRECICE_ASSERT(edgeOne.connectedTo(edgeTwo), "Edge one and two are not connected.");
34 PRECICE_ASSERT(edgeOne.connectedTo(edgeThree), "Edge one and three are not connected.");
35 PRECICE_ASSERT(edgeTwo.connectedTo(edgeThree), "Edge two and three are not connected.");
36
37 // Pick first 2 vertices from first edge
38 Vertex &v0 = edgeOne.vertex(0);
39 Vertex &v1 = edgeOne.vertex(1);
40
41 // Determine the third vertex using the second edge
42 Vertex *v2 = nullptr;
43 if ((v0 == edgeTwo.vertex(0)) || (v1 == edgeTwo.vertex(0))) {
44 v2 = &edgeTwo.vertex(1);
45 } else if ((v0 == edgeTwo.vertex(1)) || (v1 == edgeTwo.vertex(1))) {
46 v2 = &edgeTwo.vertex(0);
47 } else {
48 PRECICE_UNREACHABLE("Edges don't form a triangle");
49 }
50
51 _vertices = {&v0, &v1, v2};
52 std::sort(_vertices.begin(), _vertices.end(),
53 [](const Vertex *lhs, const Vertex *rhs) { return *lhs < *rhs; });
54}
55
57 Vertex &vertexOne,
58 Vertex &vertexTwo,
59 Vertex &vertexThree)
60 : _vertices({&vertexOne, &vertexTwo, &vertexThree})
61{
62 PRECICE_ASSERT(vertexOne.getDimensions() == vertexTwo.getDimensions(),
63 vertexOne.getDimensions(), vertexTwo.getDimensions());
64 PRECICE_ASSERT(vertexTwo.getDimensions() == vertexThree.getDimensions(),
65 vertexTwo.getDimensions(), vertexThree.getDimensions());
66 std::sort(_vertices.begin(), _vertices.end(),
67 [](const Vertex *lhs, const Vertex *rhs) { return *lhs < *rhs; });
68}
69
70double Triangle::getArea() const
71{
72 return math::geometry::triangleArea(vertex(0).getCoords(), vertex(1).getCoords(), vertex(2).getCoords());
73}
74
75Eigen::VectorXd Triangle::computeNormal() const
76{
77 Eigen::Vector3d vectorA = (vertex(1).getCoords() - vertex(0).getCoords()) / 2.0;
78 Eigen::Vector3d vectorB = (vertex(1).getCoords() - vertex(0).getCoords()) / 2.0;
79
80 // Compute cross-product of vector A and vector B
81 return vectorA.cross(vectorB).normalized();
82}
83
85{
86 return _vertices[0]->getDimensions();
87}
88
89const Eigen::VectorXd Triangle::getCenter() const
90{
91 return (_vertices[0]->getCoords() + _vertices[1]->getCoords() + _vertices[2]->getCoords()) / 3.0;
92}
93
95{
96 auto center = getCenter();
97 return std::max({(center - _vertices[0]->getCoords()).norm(),
98 (center - _vertices[1]->getCoords()).norm(),
99 (center - _vertices[2]->getCoords()).norm()});
100}
101
102bool Triangle::operator==(const Triangle &other) const
103{
104 return std::is_permutation(_vertices.begin(), _vertices.end(), other._vertices.begin(),
105 [](const Vertex *e1, const Vertex *e2) { return *e1 == *e2; });
106}
107
108bool Triangle::operator!=(const Triangle &other) const
109{
110 return !(*this == other);
111}
112
114{
116 return os << "POLYGON (("
117 << t.vertex(0).getCoords().transpose().format(wkt()) << ", "
118 << t.vertex(1).getCoords().transpose().format(wkt()) << ", "
119 << t.vertex(2).getCoords().transpose().format(wkt()) << ", "
120 << t.vertex(0).getCoords().transpose().format(wkt()) << "))";
121}
122
123} // namespace precice::mesh
#define PRECICE_ASSERT(...)
Definition assertion.hpp:87
#define PRECICE_UNREACHABLE(...)
Definition assertion.hpp:95
Linear edge of a mesh, defined by two Vertex objects.
Definition Edge.hpp:16
int getDimensions() const
Returns number of spatial dimensions (2 or 3) the edge is embedded to.
Definition Edge.hpp:91
Vertex & vertex(int i)
Returns the edge's vertex with index 0 or 1.
Definition Edge.hpp:77
bool connectedTo(const Edge &other) const
Checks whether both edges share a vertex.
Definition Edge.cpp:39
Triangle of a mesh, defined by three vertices.
Definition Triangle.hpp:27
double getArea() const
Returns the surface area of the triangle.
Definition Triangle.cpp:70
int getDimensions() const
Returns dimensionalty of space the triangle is embedded in.
Definition Triangle.cpp:84
std::array< Vertex *, 3 > _vertices
Vertices defining the triangle, sorted by Vertex::getID()
Definition Triangle.hpp:138
double getEnclosingRadius() const
Returns the radius of the circle enclosing the triangle.
Definition Triangle.cpp:94
Eigen::VectorXd computeNormal() const
Computes the normal of the triangle.
Definition Triangle.cpp:75
Vertex & vertex(int i)
Returns triangle vertex with index 0, 1 or 2.
Definition Triangle.hpp:143
bool operator==(const Triangle &other) const
Compares two Triangles for equality.
Definition Triangle.cpp:102
const Eigen::VectorXd getCenter() const
Returns the barycenter of the triangle.
Definition Triangle.cpp:89
bool operator!=(const Triangle &other) const
Not equal, implemented in terms of equal.
Definition Triangle.cpp:108
Triangle(Edge &edgeOne, Edge &edgeTwo, Edge &edgeThree)
Constructor based on 3 edges.
Definition Triangle.cpp:23
Vertex of a mesh.
Definition Vertex.hpp:16
Eigen::VectorXd getCoords() const
Returns the coordinates of the vertex.
Definition Vertex.hpp:116
T is_permutation(T... args)
T max(T... args)
double triangleArea(const Eigen::VectorXd &a, const Eigen::VectorXd &b, const Eigen::VectorXd &c)
Computes the signed area of a triangle in 2D.
Definition geometry.cpp:93
provides Mesh, Data and primitives.
BOOST_CONCEPT_ASSERT((boost::RandomAccessIteratorConcept< Triangle::iterator >))
std::ostream & operator<<(std::ostream &os, const BoundingBox &bb)
Eigen::IOFormat wkt()
Definition EigenIO.hpp:9
T sort(T... args)