forked from nmwsharp/geometry-central
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathbarycentric_vector.h
More file actions
115 lines (87 loc) · 4.77 KB
/
barycentric_vector.h
File metadata and controls
115 lines (87 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#pragma once
#include "geometrycentral/surface/intrinsic_geometry_interface.h"
#include "geometrycentral/surface/surface_point.h"
namespace geometrycentral {
namespace surface {
// A BarycentricVector represents a barycentric vector on the surface of a triangle mesh, which is the difference of two
// barycentric points (SurfacePoints.)
enum class BarycentricVectorType { Face = 0, Edge, Vertex };
struct BarycentricVector {
// === Constructors
BarycentricVector(); // default: yields invalid vector with null Face
BarycentricVector(Face f); // yields face-type BarycentricVector with zero vector
BarycentricVector(SurfacePoint pA, SurfacePoint pB);
BarycentricVector(Vertex v);
BarycentricVector(Edge e, Vector2 edgeCoords);
BarycentricVector(Face f, Vector3 faceCoords);
BarycentricVector(Halfedge he, Face f);
BarycentricVectorType type = BarycentricVectorType::Face;
// if face-type
Face face = Face();
Vector3 faceCoords = Vector3::undefined(); // must sum to zero
// if edge-type
Edge edge = Edge();
Vector2 edgeCoords = Vector2::undefined(); // must sum to zero
// if vertex-type
Vertex vertex = Vertex();
// === Methods
// All BarycentricVectors (vertex, edge, face) have an equivalent vector in one or many adjacent faces. This function
// returns one of the equivalent BarycentricVectors in a face (chosen arbitrarily). If this vector is a face vector,
// the output is a copy of this vector.
BarycentricVector inSomeFace() const;
// Returns the BarycentricVector as a face vector in face f. If the the BarycentricVector is not on or adjacent to the
// requested face, throws an error.
BarycentricVector inFace(Face f) const;
// Returns the BarycentricVector as an edge vector in edge e. If this vector is already an edge vector, the output is
// a copy of the vector. If the the BarycentricVector is not on the edge or one of its adjacent vertices, throws an
// error.
BarycentricVector inEdge(Edge e) const;
void validate() const;
// Shift values so the components sum to zero.
void normalizeDisplacement(); // modify in-place
BarycentricVector normalizedDisplacement() const; // return a new vector
// Compute norms; must define the geometry w.r.t. which norms are evaluated.
double norm(IntrinsicGeometryInterface& geom) const;
double norm2(IntrinsicGeometryInterface& geom) const;
// Overloaded operators
BarycentricVector operator+(const BarycentricVector& v) const;
BarycentricVector operator-(const BarycentricVector& v) const;
BarycentricVector operator*(double s) const;
BarycentricVector operator/(double s) const;
BarycentricVector& operator+=(const BarycentricVector& other);
BarycentricVector& operator-=(const BarycentricVector& other);
BarycentricVector& operator*=(const double& s);
BarycentricVector& operator/=(const double& s);
bool operator==(const BarycentricVector& other) const;
bool operator!=(const BarycentricVector& other) const;
const BarycentricVector operator-() const;
// Rotate the vector 90 degrees CCW within the face it belongs to.
// This requires the geometry, since the meaning of "90 degrees" depends on the geometry of the triangle.
BarycentricVector rotate90(IntrinsicGeometryInterface& geom) const; // return a new vector
// Rotate the vector the specified amount of radians CCW within the face it belongs to.
// This again requires the geometry.
BarycentricVector rotate(IntrinsicGeometryInterface& geom, double angle) const;
};
// Helper functions for rotations
BarycentricVector faceVectorRotate90(const BarycentricVector& v, IntrinsicGeometryInterface& geom);
BarycentricVector faceVectorRotate(const BarycentricVector& w, IntrinsicGeometryInterface& geom, double angle);
// Returns an arbitrary face shared by two vectors, if one exists; returns Face() if none.
Face sharedFace(const BarycentricVector& u, const BarycentricVector& v);
// Returns the edge shared by two vectors, if one exists; return Edge() if none.
Edge sharedEdge(const BarycentricVector& u, const BarycentricVector& v);
// Norms & inner products (require geometry)
double norm(IntrinsicGeometryInterface& geom, const BarycentricVector& v);
double norm2(IntrinsicGeometryInterface& geom, const BarycentricVector& v);
double dot(IntrinsicGeometryInterface& geom, const BarycentricVector& u, const BarycentricVector& v);
// Scalar multiplication
template <typename T>
BarycentricVector operator*(const T s, const BarycentricVector& v);
// double angle(const BarycentricVector& u, const BarycentricVector& v);
// Printing
::std::ostream& operator<<(::std::ostream& output, const BarycentricVector& v);
} // namespace surface
} // namespace geometrycentral
namespace std {
std::string to_string(geometrycentral::surface::BarycentricVector v);
}
#include "geometrycentral/surface/barycentric_vector.ipp"