-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRotatingPolygon.h
178 lines (146 loc) · 4.42 KB
/
RotatingPolygon.h
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
116
117
118
119
120
121
122
123
124
125
126
127
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "ElementStorage.h"
#pragma once
#include "VoronoiDiagram.h"
#include "quaternion.h"
/**
* @brief The vertices of a polygon in 3 dimensions. Represented as a 3xN matrix.
*
* @tparam N The number of vertices
*/
template <int N>
using PolygonVerts = BLA::Matrix<3, N>;
/**
* @brief Get a pyramid with a triangular base
*
* @return PolygonVerts<4>
*/
PolygonVerts<4> get_pyramid(){
PolygonVerts<4> pyramid;
pyramid.Column(0) = BLA::Matrix<3>({-0.5, -0.5, -0.5});
pyramid.Column(1) = BLA::Matrix<3>({ 0.5, -0.5, -0.5});
pyramid.Column(2) = BLA::Matrix<3>({ 0, 0.75, -0.5});
pyramid.Column(3) = BLA::Matrix<3>({ 0, 0, 0.75});
return pyramid;
};
/**
* @brief Get a cube
*
* @return PolygonVerts<4>
*/
PolygonVerts<4> get_cube(){
PolygonVerts<4> cube;
cube.Column(0) = BLA::Matrix<3>({0.5, 0.5, 0.5});
cube.Column(1) = BLA::Matrix<3>({0.5,-0.5, 0.5});
cube.Column(2) = BLA::Matrix<3>({0.5, 0.5,-0.5});
cube.Column(3) = BLA::Matrix<3>({0.5,-0.5,-0.5});
return cube;
};
/**
* @brief Get a triangle (2d)
*
* @return PolygonVerts<3>
*/
PolygonVerts<3> get_triangle(){
PolygonVerts<3> triangle;
triangle.Column(0) = BLA::Matrix<3>({0.5, -0.5, 0});
triangle.Column(1) = BLA::Matrix<3>({-0.5,-0.5, 0.75});
triangle.Column(2) = BLA::Matrix<3>({ 0, 0, 0});
return triangle;
};
/**
* @brief A class to represent a rotating polygon.
* This contains vertices, a voronoi diagram, an orientation.
*
* Dynamics of rotation need to be implemented.
*
* @tparam N The number of vertices in the polygon
*/
template <int N>
class RotatingPolygon{
public:
RotatingPolygon(PolygonVerts<N> verts) : verts_(verts), rot_verts_t_(verts) {
// voronoi_ = VoronoiDiagram<3,N>(verts_);
}
/**
* @brief Step the simulation forward by dt.
* This effectively rotates the polygon.
*
* @param dt The time step
*/
void step(float dt){
// apply dynamics
QuaternionO q = q_;
apply_dynamics(dt, q, dq_);
// apply rotation
apply_rotation(q);
}
/**
* @brief get an updated state of the polygon (q, dq). This is _const_. do_dynamics must be implemented to find ddq.
*
* @param dt The time step
* @param q The orientation quaternion
* @param dq The angular velocity
*/
virtual void apply_dynamics(float dt, QuaternionO& q, BLA::Matrix<3,1>& dq) const {
BLA::Matrix<3> ddq_stepped;
do_dynamics(q, dq, ddq_stepped);
// apply dq to q. dq is an axis_angle rotation.
QuaternionO dq_quat = QuaternionO(dq * dt);
q = dq_quat * q;
dq = dq + ddq_stepped * dt;
}
/**
* @brief get ddq given the state (q and dq). This is _const_.
*/
virtual void do_dynamics(const QuaternionO& q,
const BLA::Matrix<3>& dq, BLA::Matrix<3>& ddq) const {
ddq = {0,0,0};
}
/**
* @brief Apply a rotation to the polygon.
*
* @param q The orientation quaternion
*/
void apply_rotation(const QuaternionO& q){
q_ = q;
// update rotation matrix
rot_matrix_ = q_.getRotationMatrix();
// rotate vertices
rot_verts_t_ = rot_matrix_ * verts_;
}
/**
* @brief Get the vertex at index i
*
* @param i The index
* @return BLA::Matrix<3> The vertex
*/
BLA::Matrix<3> get_vert(int i){
return rot_verts_t_.Column(i);
}
/**
* @brief Get the index of the closest vertex to a point
*
* @param point The point
* @return int The index of the closest vertex
*/
int vert_closest_to(BLA::Matrix<3,1> point){
// We apply an inverse rotation to the point to get it in the frame of the voronoi diagram object.
// return voronoi_.get_cell_index(BLA::MatrixTranspose<BLA::Matrix<3,3>>(rot_matrix_) * point);
}
/**
* @brief Get the closest vertex to a point
*
* @param point The point
* @return BLA::Matrix<3> The closest vertex
*/
BLA::Matrix<3> get_closest_vert(BLA::Matrix<3> point){
return get_vert(vert_closest_to(point));
}
private:
// VoronoiDiagram<3,N> voronoi_;
PolygonVerts<N> verts_;
PolygonVerts<N> rot_verts_t_;
BLA::Matrix<3, 3, float> rot_matrix_ = BLA::Eye<3,3>();
QuaternionO q_; // orientation quaternion
BLA::Matrix<3> dq_ = {0,0,0}; // angular velocity
};