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