Marine systems simulation
Subroutines.h
1#pragma once
2
3#include <iostream>
4#include <iomanip>
5#include <fstream>
6#include <algorithm>
7#include <vector>
8#include <valarray>
9#include <Eigen/Eigen>
10
11#include "sfh/math/math.h"
12
13namespace barge {
14
15typedef Eigen::Matrix<double,6,6> mat6;
16typedef Eigen::Matrix<double,6,1> vec6;
17typedef Eigen::Matrix<double,3,3> mat3;
18typedef Eigen::Matrix<double,2,1> vec2;
19typedef Eigen::Matrix<int,2,1> vec2i;
20typedef Eigen::Matrix<double,3,1> vec3;
21typedef Eigen::Matrix<int,3,1> vec3i;
22typedef Eigen::Matrix<double,13,1> vec13;
23typedef Eigen::Quaternion<double> quat;
24
25// Convex Hull ==================================================================
26typedef double iCoordinate; // Coordinate type
27typedef double oCoordinate; // Must be big enough to hold 2*max(|Coordinate|)^2
28// Convex Hull ==================================================================
29
30// Ray-Triangle intersection ====================================================
31int rayTri(const vec3 &V1, const vec3 &V2, const vec3 &V3, const vec3 &O, const vec3 &D, double &out);
32// Ray-Triangle intersection ====================================================
33
34// Segment-Plane intersection ===================================================
35int SegmentPlane(const vec3 &S0, const vec3 &S1, const vec3 &P0, const vec3 &PN, vec3 &SPI);
36// Segment-Plane intersection ===================================================
37
38// Convex Hull ==================================================================
39struct Point {
40 iCoordinate x, y;
41 bool operator <(const Point &p) const {
42 return x < p.x || (x == p.x && y < p.y);
43 }
44};
45
46// 2D cross product of OA and OB vectors
47inline oCoordinate Cross2D(const Point &O, const Point &A, const Point &B)
48{
49 return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
50}
51// 2D cross product of OA and OB vectors
52
53std::vector<Point> ConvexHull(std::vector<Point> P);
54// Convex Hull ==================================================================
55
56// Triangle Area 2D =============================================================
57inline double TriangleArea2D(const vec2 &V0, const vec2 &V1, const vec2 &V2)
58{
59 vec2 V01 = V1-V0;
60 vec2 V02 = V2-V0;
61
62 return 0.5*std::abs(V01(0)*V02(1)-V02(0)*V01(1));
63}
64// Triangle Area 2D =============================================================
65
66// Triangle Area 3D =============================================================
67inline double TriangleArea3D(const vec3 &V0, const vec3 &V1, const vec3 &V2)
68{
69 vec3 V01 = V1-V0;
70 vec3 V02 = V2-V0;
71
72 vec3 V012 = V01.cross(V02);
73
74 return 0.5*sqrt(V012(0)*V012(0)+V012(1)*V012(1)+V012(2)*V012(2));
75}
76// Triangle Area 3D =============================================================
77
78// Point-Point distance 3D ======================================================
79inline double PointDistance3D(const vec3 &PA, const vec3 &PB)
80{
81 return sqrt((PA(0)-PB(0))*(PA(0)-PB(0))+(PA(1)-PB(1))*(PA(1)-PB(1))+(PA(2)-PB(2))*(PA(2)-PB(2)));
82}
83// Point-Point distance 3D ======================================================
84
85// Point-Plane distance =========================================================
86inline double PointPlaneDis(const vec3 &V0, const vec3 &P0, const vec3 &PN)
87{
88 vec3 VP = V0-P0;
89 return VP.dot(PN.normalized());
90}
91// Point-Plane distance =========================================================
92
93// Polyplate structure ==========================================================
95public:
97 PolyplateSpec(int &nPolyPoints, std::vector<double> &xPoints, std::vector<double> &yPoints, double &mThickness, double &mDensity);
99
100 void setPolyplate(int &nPolyPoints, std::vector<double> &xPoints, std::vector<double> &yPoints, double &mThickness, double &mDensity);
101
102 int numPoints; // Points
103 double thickness; // Plate thickness
104 std::vector<double> xCoords; // Polygon x-coords (Right-handed in NED, counter-clockwise from bottom, clockwise from top)
105 std::vector<double> yCoords; // Polygon y-coords (Right-handed in NED, counter-clockwise from bottom, clockwise from top)
106 double density; // Density
107 double mass; // Mass
108 double volume; // Volume
109 mat6 inertiaMatrix; // Plate inertia
110 vec3 centroid;
111
112 double projectedArea;
113 double cubedGRZ;
114 double cubedGRY;
115 double cubedGRX;
116 double cubedGRXY;
117 double cubedGRYX;
118
119 double rectGRX;
120 double rectGRY;
121};
122
123mat3 GetRotation(const vec3& angle);
124mat6 ReorientInertiaTranslateRotate(const mat6& Inertia, const vec6& orientation);
125mat3 MakeDyadic(const vec3& vector);
126// Polyplate structure ==========================================================
127
128// AABB class ===================================================================
129class AABB {
130public:
131 vec3 minloc, maxloc;
132
133 AABB() {
134 minloc(0) = minloc(1) = minloc(2) = std::numeric_limits<double>::max();
135 maxloc(0) = maxloc(1) = maxloc(2) = -std::numeric_limits<double>::max();
136 }
137
138 AABB(const AABB &aabb) {
139 minloc = aabb.minloc;
140 maxloc = aabb.maxloc;
141 }
142
143 ~AABB(){}
144
145 void add(const vec3 &v) {
146 if (v(0) < minloc(0)) minloc(0) = v(0);
147 if (v(1) < minloc(1)) minloc(1) = v(1);
148 if (v(2) < minloc(2)) minloc(2) = v(2);
149 if (v(0) > maxloc(0)) maxloc(0) = v(0);
150 if (v(1) > maxloc(1)) maxloc(1) = v(1);
151 if (v(2) > maxloc(2)) maxloc(2) = v(2);
152 }
153
154 void clear() {
155 minloc(0) = minloc(1) = minloc(2) = std::numeric_limits<double>::max();
156 maxloc(0) = maxloc(1) = maxloc(2) = -std::numeric_limits<double>::max();
157 }
158
159 int overlap(const AABB &aabb)
160 {
161 if(maxloc(0) < aabb.minloc(0) || minloc(0) > aabb.maxloc(0)) return 0;
162 if(maxloc(1) < aabb.minloc(1) || minloc(1) > aabb.maxloc(1)) return 0;
163 if(maxloc(2) < aabb.minloc(2) || minloc(2) > aabb.maxloc(2)) return 0;
164
165 return 1;
166 }
167
168 double overlapvolume(const AABB &aabb, vec3 &minol, vec3 &maxol)
169 {
170 minol(0) = std::max(minloc(0),aabb.minloc(0));
171 maxol(0) = std::min(maxloc(0),aabb.maxloc(0));
172 minol(1) = std::max(minloc(1),aabb.minloc(1));
173 maxol(1) = std::min(maxloc(1),aabb.maxloc(1));
174 minol(2) = std::max(minloc(2),aabb.minloc(2));
175 maxol(2) = std::min(maxloc(2),aabb.maxloc(2));
176
177 double volume = std::abs((maxol(0)-minol(0))*(maxol(1)-minol(1))*(maxol(2)-minol(2)));
178
179 return volume;
180 }
181};
182// AABB class ===================================================================
183
184// AABB struct ==================================================================
185struct AABBSpec {
186 int numE; // Number of edges in object.
187 int numT; // Number of triangles in object.
188
189 int* indexE; // Index of edges in AABB.
190 int* indexT; // Index of triangles in AABB.
191};
192// AABB struct ==================================================================
193
194// AABB class 2D ================================================================
195class AABB2D {
196public:
197 vec2 minloc, maxloc;
198
199 AABB2D() {
200 minloc(0) = minloc(1) = std::numeric_limits<double>::max();
201 maxloc(0) = maxloc(1) = -std::numeric_limits<double>::max();
202 }
203
204 AABB2D(const AABB2D &aabb) {
205 minloc = aabb.minloc;
206 maxloc = aabb.maxloc;
207 }
208
209 ~AABB2D(){}
210
211 void add(const vec2 &v) {
212 if (v(0) < minloc(0)) minloc(0) = v(0);
213 if (v(1) < minloc(1)) minloc(1) = v(1);
214 if (v(0) > maxloc(0)) maxloc(0) = v(0);
215 if (v(1) > maxloc(1)) maxloc(1) = v(1);
216 }
217
218 void clear() {
219 minloc(0) = minloc(1) = std::numeric_limits<double>::max();
220 maxloc(0) = maxloc(1) = -std::numeric_limits<double>::max();
221 }
222
223 int overlap(const AABB2D &aabb)
224 {
225 if(maxloc(0) < aabb.minloc(0) || minloc(0) > aabb.maxloc(0)) return 0;
226 if(maxloc(1) < aabb.minloc(1) || minloc(1) > aabb.maxloc(1)) return 0;
227
228 return 1;
229 }
230
231 double overlaparea(const AABB2D &aabb, vec2 &minol, vec2 &maxol)
232 {
233 minol(0) = std::max(minloc(0),aabb.minloc(0));
234 maxol(0) = std::min(maxloc(0),aabb.maxloc(0));
235 minol(1) = std::max(minloc(1),aabb.minloc(1));
236 maxol(1) = std::min(maxloc(1),aabb.maxloc(1));
237
238 double area = std::abs((maxol(0)-minol(0))*(maxol(1)-minol(1)));
239
240 return area;
241 }
242};
243// AABB class 2D ================================================================
244
245// Object struct ================================================================
247 int numP; // Number of points in object.
248 int numT; // Number of triangles in object.
249
250 double* xyzP; // Coordinate of points in object.
251 int* indexT; // Index of triangles in object.
252 double* normT;
253};
254// Object struct ================================================================
255
256// Quaternion class =============================================================
257class QuatC {
258public:
259 quat L2G; // Quaternion transfers local coordinates to global coordinates
260 quat G2L; // Quaternion transfers global coordinates to local coordinates
261};
262// Quaternion class =============================================================
263
264// Particle class ===============================================================
265class Particle {
266public:
267 vec3 xyzCT; // Coordinate of centroid.
268 int numV; // Number of vertices in a polyhedral particle.
269 vec3* xyzV; // Coordinate of each vertex.
270 int* numE; // Number of edges that share each vertex.
271 int** indexE; // Index of edges that share each vertex.
272 int* numF; // Number of faces that share each vertex.
273 vec2i** indexF; // Index of faces that share each vertex.
274
275 Particle(){}
276
277 Particle(const Particle &P0);
278
279 ~Particle();
280
281 void newPolyplate(int &nPolyPoints);
282 void setPolyplate(int &nPolyPoints, const PolyplateSpec &iPolyplate, vec3 &iCT, quat &iQuatL2G);
283 vec2i ClosestV(const Particle &PB, double &dAB);
284 double DistancePL(const vec3 &P0, const vec3 &PN, int &numCV, std::vector<int> &indexCV);
285 double DistancePL1V(const vec3 &P0, const vec3 &PN);
286 int IntersectionPL(const vec3 &P0, const vec3 &PN, int &numInt, std::vector<vec3> &xyzInt, double &IND);
287};
288// Particle class ===============================================================
289
290// Common Plane =================================================================
292public:
293 double dBA; // Gap between two particles
294 int Cont; // 1: Real contact; 0: Potential contact; -1: Not in contact
295
296 CommonPlane(){}
297 ~CommonPlane(){}
298
299 int CalCommonPlane(Particle &PA, Particle &PB, const double &TOL, const double &TRAN, const vec3 &P0, const vec3 &PN, vec3 &CP0, vec3 &CPN);
300};
301// Common Plane =================================================================
302
303// Contact Area =================================================================
304double ContactArea(Particle &PA, Particle &PB, const vec3 &P0, const vec3 &PN, double &IND, vec3 &CONP);
305
306double ContactAreaPolyplate(Particle &PA, Particle &PB, const vec3 &P0, const vec3 &PN, double &IND, vec3 &CONP);
307// Contact Area =================================================================
308
309// Quaternion to Roll-Pitch-Yaw Angles ==========================================
310inline vec3 QuaternionToAngle(const quat &QuatL2G)
311{
312 vec3 RollPitchYaw = QuatL2G.toRotationMatrix().eulerAngles(0,1,2);
313
314 return RollPitchYaw;
315}
316// Quaternion to Roll-Pitch-Yaw Angles ==========================================
317} // namespace
Definition: Subroutines.h:195
Definition: Subroutines.h:129
Definition: Subroutines.h:291
Definition: Subroutines.h:265
Definition: Subroutines.h:257
Definition: Subroutines.h:185
Definition: Subroutines.h:246
Definition: Subroutines.h:39
Definition: Subroutines.h:94