25 : normal(0., 0., 1.), offset(0.)
31 : i1(_i1), i2(_i2), i3(_i3)
37 : volume(0.0), centroid(ignition::math::Vector3d({0, 0, 0}))
54 for (
int i = 0; i < 2; ++i)
56 for (
int j = 0; j < 2; ++j)
58 for (
int k = 0; k < 2; ++k)
61 ignition::math::Vector3d(i * x - x / 2.0,
62 j * y - y / 2.0, k * z - z / 2.0));
91 double angle_step = 2.0 * M_PI / n;
94 cylinder.
vertices[0] = ignition::math::Vector3d{0, 0, -l_2};
95 for (
int i = 1; i <= n; ++i)
97 double x = r * ::sin(angle_step * (i-1));
98 double y = r * ::cos(angle_step * (i-1));
100 cylinder.
vertices[i] = ignition::math::Vector3d{x, y, -l_2};
102 cylinder.
vertices[i+n] = ignition::math::Vector3d{x, y, l_2};
104 cylinder.
vertices[2*n+1] = ignition::math::Vector3d{0, 0, l_2};
107 for (
int i = 1; i <= n; ++i)
109 cylinder.
faces.emplace_back(
Face(0, i, (i%n)+1));
111 for (
int i = 1; i <= n; ++i)
113 cylinder.
faces.emplace_back(
Face(i+1, i, n+i));
114 cylinder.
faces.emplace_back(
Face((i%n)+n, (i%n)+n+1, (i%n)+1));
116 for (
int i = 1; i <= n; ++i)
118 cylinder.
faces.emplace_back(
Face(i+n, 2*n+1, (i%n)+n+1));
121 assert(cylinder.
vertices.size() == 2 * n + 2);
122 assert(cylinder.
faces.size() == 4 * n);
129 const ignition::math::Vector3d &v2,
const ignition::math::Vector3d &v3,
130 const ignition::math::Vector3d &p)
132 ignition::math::Vector3d a = v2 - v1;
133 ignition::math::Vector3d b = v3 - v1;
134 ignition::math::Vector3d r = p - v1;
137 output.
volume = (1/6.) * (b.Cross(a)).Dot(r);
147 for (
const auto& face : faces)
149 ignition::math::Vector3d v1 = vertices[face.i1];
150 ignition::math::Vector3d v2 = vertices[face.i2];
151 ignition::math::Vector3d v3 = vertices[face.i3];
152 output += tetrahedronVolume(v1, v2, v3);
159 const ignition::math::Vector3d &v2,
160 const ignition::math::Vector3d &v3,
double d1,
double d2,
double d3,
161 const ignition::math::Vector3d &p)
167 ignition::math::Vector3d ab = v1 + (d1/(d1 - d2))*(v2 - v1);
175 ignition::math::Vector3d bc = v2 + (d2/(d2 - d3))*(v3 - v2);
176 output += tetrahedronVolume(ab, bc, v1, p);
177 output += tetrahedronVolume(bc, v3, v1, p);
182 ignition::math::Vector3d ac = v1 + (d1/(d1 - d3))*(v3 - v1);
183 output += tetrahedronVolume(ab, ac, v1, p);
191 ignition::math::Vector3d ac = v1 + (d1/(d1 - d3))*(v3 - v1);
192 output += tetrahedronVolume(ab, v2, v3, p);
193 output += tetrahedronVolume(ab, v3, ac, p);
198 ignition::math::Vector3d bc = v2 + (d2/(d2 - d3))*(v3 - v2);
199 output += tetrahedronVolume(ab, v2, bc, p);
207 const ignition::math::Quaterniond &q,
Plane &plane)
210 auto qt = q.Inverse();
211 auto normal = qt.RotateVector(plane.
normal);
215 std::vector<double> ds(vertices.size());
216 int numSubmerged = 0;
218 for (
size_t i = 0; i < vertices.size(); ++i)
220 ds[i] = normal.Dot(vertices[i]) - offset;
221 if (ds[i] < -EPSILON)
229 if (numSubmerged == 0)
239 ignition::math::Vector3d p = vertices[sampleVert] - ds[sampleVert] * normal;
243 for (
const auto& face : faces)
245 ignition::math::Vector3d v1 = vertices[face.i1];
246 ignition::math::Vector3d v2 = vertices[face.i2];
247 ignition::math::Vector3d v3 = vertices[face.i3];
248 double d1 = ds[face.i1];
249 double d2 = ds[face.i2];
250 double d3 = ds[face.i3];
254 output += clipTriangle(v1, v2, v3, d1, d2, d3, p);
256 else if (d1 * d3 < 0)
258 output += clipTriangle(v3, v1, v2, d3, d1, d2, p);
260 else if (d2 * d3 < 0)
262 output += clipTriangle(v2, v3, v1, d2, d3, d1, p);
264 else if (d1 < 0 || d2 < 0 || d3 < 0)
266 output += tetrahedronVolume(v1, v2, v3, p);
272 if (output.
volume <= EPSILON)
ignition::math::Vector3d normal
Vector3 normal to plane.
Volume & operator+=(const Volume &rhs)
Overloads += for volume object.
float offset
Offset w.r.t. normal.
Volume ComputeFullVolume()
Compute full volume and center of buoyancy of the polyhedron.
std::vector< Face > faces
Object faces.
TFSIMD_FORCE_INLINE const tfScalar & y() const
Plane()
Initializes plane at z=0.
Submerged volume calculation using polyhedron based on: Exact Buoyancy for Polyhedra by Eric Catto...
static Polyhedron makeCube(double x, double y, double z)
Generate a cube polyhedron centered at origin.
static Polyhedron makeCylinder(double r, double l, int n)
Generate a cylinder polyhedron centered at origin.
TFSIMD_FORCE_INLINE const tfScalar & x() const
Store vertex index for a triangular face.
ignition::math::Vector3d centroid
Vector3 representing volume centroid.
static Volume clipTriangle(const ignition::math::Vector3d &v1, const ignition::math::Vector3d &v2, const ignition::math::Vector3d &v3, double d1, double d2, double d3, const ignition::math::Vector3d &p=ignition::math::Vector3d({0., 0., 0.}))
Clips a partially submerged triangle.
std::vector< ignition::math::Vector3d > vertices
Object vertices.
static Volume tetrahedronVolume(const ignition::math::Vector3d &v1, const ignition::math::Vector3d &v2, const ignition::math::Vector3d &v3, const ignition::math::Vector3d &p=ignition::math::Vector3d({0., 0., 0.}))
Computes volume and centroid of tetrahedron tetrahedron formed by triangle + arbitrary point...
Represents output volume with centroid.
Represents a plane as a normal and offset.
double volume
Submerged volume of shape.
Volume SubmergedVolume(const ignition::math::Vector3d &x, const ignition::math::Quaterniond &q, Plane &plane)
Compute submerge volume and center of buoyancy of a polyhedron.