PolyDiM
C++ library for POLYtopal DIscretization Methods
Loading...
Searching...
No Matches
PlatonicSolid.hpp
Go to the documentation of this file.
1// _LICENSE_HEADER_
2//
3// Copyright (C) 2019 - 2025.
4// Terms register on the GPL-3.0 license.
5//
6// This file can be redistributed and/or modified under the license terms.
7//
8// See top level LICENSE file for more details.
9//
10// This file can be used citing references in CITATION.cff file.
11
12#ifndef __PlatonicSolid_H
13#define __PlatonicSolid_H
14
15#include "GeometryUtilities.hpp"
16#include "MeshMatricesDAO.hpp"
17#include "MeshUtilities.hpp"
18#include <numeric>
19
20namespace Gedim
21{
27{
28 const Gedim::GeometryUtilities &geometryUtilities;
29 const Gedim::MeshUtilities &meshUtilities;
30
31 public:
32 PlatonicSolid(const Gedim::GeometryUtilities &geometryUtilities, const Gedim::MeshUtilities &meshUtilities)
33 : geometryUtilities(geometryUtilities), meshUtilities(meshUtilities)
34 {
35 }
36
37 virtual ~PlatonicSolid(){};
38
40 {
41 polyhedron.Vertices.colwise().normalize();
42 }
43
45 {
46 for (unsigned int v = 0; v < mesh.Cell0DTotalNumber(); v++)
47 {
48 const auto num_neighboord = mesh.Cell0DNumberNeighbourCell2D(v);
49
50 if (num_neighboord == 6)
51 {
52 const auto coord = mesh.Cell0DCoordinates(v);
53 const auto normalized_coord = coord.normalized();
54 for (unsigned int d = 0; d < 3; d++)
55 mesh_data.Cell0DCoordinates[v * 3 + d] = normalized_coord(d);
56 }
57 }
58
59 for (unsigned int v = 0; v < mesh.Cell0DTotalNumber(); v++)
60 {
61 const auto num_neighboord = mesh.Cell0DNumberNeighbourCell2D(v);
62
63 if (num_neighboord != 6)
64 {
65 const auto neighboord_edges = mesh.Cell0DNeighbourCell1Ds(v);
66 Eigen::MatrixXd plane = Eigen::MatrixXd::Zero(3, 3);
67 for (unsigned int e = 0; e < 3; e++)
68 {
69 auto origin = mesh.Cell1DOrigin(neighboord_edges[e]);
70 if (origin == v)
71 plane.col(e) = mesh.Cell1DEndCoordinates(neighboord_edges[e]);
72 else
73 plane.col(e) = mesh.Cell1DOriginCoordinates(neighboord_edges[e]);
74 }
75
76 const Eigen::Vector3d normal_plane = geometryUtilities.PolygonNormal(plane);
77 const Eigen::Vector3d origin_plane = plane.col(0);
78
79 const Eigen::Vector3d point = mesh.Cell0DCoordinates(v);
81
82 for (unsigned int d = 0; d < 3; d++)
83 mesh_data.Cell0DCoordinates[v * 3 + d] = projected_point(d);
84 }
85 }
86 }
87
89 {
90
91 std::list<unsigned int> special_vertices;
92
93 for (unsigned int v = 0; v < mesh.Cell0DTotalNumber(); v++)
94 {
95 const auto neighboord = mesh.Cell0DNeighbourCell2Ds(v);
96 bool no_special = true;
97 for (unsigned int n = 0; n < neighboord.size(); n++)
98 {
99 if (mesh.Cell2DNumberVertices(neighboord[n]) != 6)
100 {
101 special_vertices.push_back(v);
102 no_special = false;
103 break;
104 }
105 }
106
107 if (no_special)
108 {
109 const auto coord = mesh.Cell0DCoordinates(v);
110 const auto normalized_coord = coord.normalized();
111 for (unsigned int d = 0; d < 3; d++)
112 mesh_data.Cell0DCoordinates[v * 3 + d] = normalized_coord(d);
113 }
114 }
115
116 for (unsigned int v : special_vertices)
117 {
118 const auto neighboord = mesh.Cell0DNeighbourCell2Ds(v);
119
120 for (unsigned int n : neighboord)
121 {
122 if (mesh.Cell2DNumberVertices(n) == 6)
123 {
124 const auto face_vertices = mesh.Cell2DVertices(n);
125 Eigen::MatrixXd plane = Eigen::MatrixXd::Zero(3, 3);
126 unsigned int p = 0;
127 for (unsigned int e = 0; e < face_vertices.size(); e++)
128 {
129 if (std::find(special_vertices.begin(), special_vertices.end(), face_vertices[e]) ==
130 special_vertices.end())
131 {
132 plane.col(p++) = mesh.Cell0DCoordinates(face_vertices[e]);
133
134 if (p == 3)
135 break;
136 }
137 }
138
139 const Eigen::Vector3d normal_plane = geometryUtilities.PolygonNormal(plane);
140 const Eigen::Vector3d origin_plane = plane.col(0);
141
142 const Eigen::Vector3d point = mesh.Cell0DCoordinates(v);
144
145 for (unsigned int d = 0; d < 3; d++)
146 mesh_data.Cell0DCoordinates[v * 3 + d] = projected_point(d);
147 }
148 }
149 }
150 }
151
153
155 const unsigned int &frequency,
157
159 const unsigned int &frequency,
161
163 const unsigned int &q,
164 const unsigned int &b,
165 const unsigned int &c) const
166 {
167
168 Gedim::Output::Assert(p >= 3 && q == 3);
169
171
172 switch (p)
173 {
174 case 3:
175 solid = tetrahedron();
176 break;
177 case 4:
178 solid = octahedron();
179 break;
180 case 5:
181 solid = icosahedron();
182 break;
183 default:
184 throw std::runtime_error("not valid q");
185 }
186
188
191
192 return dual;
193 }
194
196 const unsigned int &q,
197 const unsigned int &b,
198 const unsigned int &c) const
199 {
200 Gedim::Output::Assert(p == 3 && q >= 3);
201
203
204 switch (q)
205 {
206 case 3:
207 solid = tetrahedron();
208 break;
209 case 4:
210 solid = octahedron();
211 break;
212 case 5:
213 solid = icosahedron();
214 break;
215 default:
216 throw std::runtime_error("not valid q");
217 }
218
220 if ((b == 0 && c > 0) || (b > 0 && c == 0))
221 {
222 unsigned int frequency = c == 0 ? b : c;
223 Gedim::MeshMatrices mesh_data;
224 Gedim::MeshMatricesDAO mesh(mesh_data);
225
227
228 polyhedron.Vertices = mesh.Cell0DsCoordinates();
229 polyhedron.Edges = mesh.Cell1DsExtremes();
230 polyhedron.Faces = mesh.Cell2DsExtremes();
231
233 }
234 else if (b == c)
235 {
236 unsigned int frequency = c == 0 ? b : c;
237 Gedim::MeshMatrices mesh_data;
238 Gedim::MeshMatricesDAO mesh(mesh_data);
239
241
242 polyhedron.Vertices = mesh.Cell0DsCoordinates();
243 polyhedron.Edges = mesh.Cell1DsExtremes();
244 polyhedron.Faces = mesh.Cell2DsExtremes();
245
247 }
248 else
249 throw std::runtime_error("not valid configuration");
250
251 return polyhedron;
252 }
253
255 {
256 // choose coordinates on the unit sphere
257 const double a = 1.0 / 3.0;
258 const double b = sqrt(8.0 / 9.0);
259 const double c = sqrt(2.0 / 9.0);
260 const double d = sqrt(2.0 / 3.0);
261
263
264 // add the 4 vertices
265 polyhedron.Vertices.resize(3, 4);
266 polyhedron.Vertices.col(0) << 0.0, 0.0, 1.0;
267 polyhedron.Vertices.col(1) << -c, d, -a;
268 polyhedron.Vertices.col(2) << -c, -d, -a;
269 polyhedron.Vertices.col(3) << b, 0.0, -a;
270
271 // add the 6 edges
272 polyhedron.Edges.resize(2, 6);
273 polyhedron.Edges.col(0) << 0, 1; // 0
274 polyhedron.Edges.col(1) << 1, 2; // 1
275 polyhedron.Edges.col(2) << 0, 2; // 2
276 polyhedron.Edges.col(3) << 2, 3; // 3
277 polyhedron.Edges.col(4) << 0, 3; // 4
278 polyhedron.Edges.col(5) << 1, 3; // 5
279
280 // add the 4 faces
281 polyhedron.Faces.resize(4);
282 polyhedron.Faces[0].resize(2, 3);
283 polyhedron.Faces[0] << 0, 1, 2, 0, 1, 2;
284
285 polyhedron.Faces[1].resize(2, 3);
286 polyhedron.Faces[1] << 0, 2, 3, 2, 3, 4;
287
288 polyhedron.Faces[2].resize(2, 3);
289 polyhedron.Faces[2] << 0, 3, 1, 4, 5, 0;
290
291 polyhedron.Faces[3].resize(2, 3);
292 polyhedron.Faces[3] << 3, 2, 1, 3, 1, 5;
293
294 return polyhedron;
295 }
296
298 {
299
300 // choose coordinates on the unit sphere
301 const double a = 1.0 / sqrt(3.0);
302
304
305 // add the 8 vertices
306 polyhedron.Vertices.resize(3, 8);
307 polyhedron.Vertices.col(0) << -a, -a, -a;
308 polyhedron.Vertices.col(1) << a, -a, -a;
309 polyhedron.Vertices.col(2) << a, a, -a;
310 polyhedron.Vertices.col(3) << -a, a, -a;
311 polyhedron.Vertices.col(4) << -a, -a, a;
312 polyhedron.Vertices.col(5) << a, -a, a;
313 polyhedron.Vertices.col(6) << a, a, a;
314 polyhedron.Vertices.col(7) << -a, a, a;
315
316 // add the 12 edges
317 polyhedron.Edges.resize(2, 12);
318 polyhedron.Edges.col(0) << 0, 1; // 0
319 polyhedron.Edges.col(1) << 1, 2; // 1
320 polyhedron.Edges.col(2) << 2, 3; // 2
321 polyhedron.Edges.col(3) << 0, 3; // 3
322 polyhedron.Edges.col(4) << 2, 6; // 4
323 polyhedron.Edges.col(5) << 5, 6; // 5
324 polyhedron.Edges.col(6) << 1, 5; // 6
325 polyhedron.Edges.col(7) << 6, 7; // 7
326 polyhedron.Edges.col(8) << 4, 7; // 8
327 polyhedron.Edges.col(9) << 4, 5; // 9
328 polyhedron.Edges.col(10) << 0, 4; // 10
329 polyhedron.Edges.col(11) << 3, 7; // 11
330
331 // add the 6 faces
332 polyhedron.Faces.resize(6);
333 polyhedron.Faces[0].resize(2, 4);
334 polyhedron.Faces[0] << 3, 2, 1, 0, 2, 1, 0, 3;
335
336 polyhedron.Faces[1].resize(2, 4);
337 polyhedron.Faces[1] << 2, 6, 5, 1, 4, 5, 6, 1;
338
339 polyhedron.Faces[2].resize(2, 4);
340 polyhedron.Faces[2] << 5, 6, 7, 4, 5, 7, 8, 9;
341
342 polyhedron.Faces[3].resize(2, 4);
343 polyhedron.Faces[3] << 0, 4, 7, 3, 10, 8, 11, 3;
344
345 polyhedron.Faces[4].resize(2, 4);
346 polyhedron.Faces[4] << 3, 7, 6, 2, 11, 7, 4, 2;
347
348 polyhedron.Faces[5].resize(2, 4);
349 polyhedron.Faces[5] << 1, 5, 4, 0, 6, 9, 10, 0;
350
351 return polyhedron;
352 }
353
361
363 {
365
366 const double phi = (1.0 + sqrt(5.0)) * 0.5; // golden ratio
367 const double a = 1.0;
368 const double b = 1.0 / phi;
369
370 // add the 12 vertices
371 polyhedron.Vertices.resize(3, 12);
372 polyhedron.Vertices.col(0) << 0.0, b, -a;
373 polyhedron.Vertices.col(1) << b, a, 0.0;
374 polyhedron.Vertices.col(2) << -b, a, 0.0;
375 polyhedron.Vertices.col(3) << 0.0, b, a;
376 polyhedron.Vertices.col(4) << 0.0, -b, a;
377 polyhedron.Vertices.col(5) << -a, 0.0, b;
378 polyhedron.Vertices.col(6) << 0.0, -b, -a;
379 polyhedron.Vertices.col(7) << a, 0.0, -b;
380 polyhedron.Vertices.col(8) << a, 0.0, b;
381 polyhedron.Vertices.col(9) << -a, 0.0, -b;
382 polyhedron.Vertices.col(10) << b, -a, 0.0;
383 polyhedron.Vertices.col(11) << -b, -a, 0.0;
384
385 // add the 12 edges
386 polyhedron.Edges.resize(2, 30);
387 polyhedron.Edges.col(0) << 1, 2; // 0
388 polyhedron.Edges.col(1) << 0, 1; // 1
389 polyhedron.Edges.col(2) << 0, 2; // 2
390 polyhedron.Edges.col(3) << 2, 3; // 3
391 polyhedron.Edges.col(4) << 1, 3; // 4
392 polyhedron.Edges.col(5) << 4, 5; // 5
393 polyhedron.Edges.col(6) << 3, 4; // 6
394 polyhedron.Edges.col(7) << 3, 5; // 7
395 polyhedron.Edges.col(8) << 4, 8; // 8
396 polyhedron.Edges.col(9) << 3, 8; // 9
397 polyhedron.Edges.col(10) << 6, 7; // 10
398 polyhedron.Edges.col(11) << 0, 6; // 11
399 polyhedron.Edges.col(12) << 0, 7; // 12
400 polyhedron.Edges.col(13) << 6, 9; // 13
401 polyhedron.Edges.col(14) << 0, 9; // 14
402 polyhedron.Edges.col(15) << 10, 11; // 15
403 polyhedron.Edges.col(16) << 6, 11; // 16
404 polyhedron.Edges.col(17) << 6, 10; // 17
405 polyhedron.Edges.col(18) << 4, 10; // 18
406 polyhedron.Edges.col(19) << 4, 11; // 19
407 polyhedron.Edges.col(20) << 5, 9; // 20
408 polyhedron.Edges.col(21) << 2, 5; // 21
409 polyhedron.Edges.col(22) << 2, 9; // 22
410 polyhedron.Edges.col(23) << 9, 11; // 23
411 polyhedron.Edges.col(24) << 5, 11; // 24
412 polyhedron.Edges.col(25) << 7, 8; // 25
413 polyhedron.Edges.col(26) << 1, 7; // 26
414 polyhedron.Edges.col(27) << 1, 8; // 27
415 polyhedron.Edges.col(28) << 8, 10; // 28
416 polyhedron.Edges.col(29) << 7, 10; // 29
417
418 // add the 6 faces
419 polyhedron.Faces.resize(20);
420 polyhedron.Faces[0].resize(2, 3);
421 polyhedron.Faces[0] << 2, 1, 0, 0, 1, 2;
422
423 polyhedron.Faces[1].resize(2, 3);
424 polyhedron.Faces[1] << 1, 2, 3, 0, 3, 4;
425
426 polyhedron.Faces[2].resize(2, 3);
427 polyhedron.Faces[2] << 5, 4, 3, 5, 6, 7;
428
429 polyhedron.Faces[3].resize(2, 3);
430 polyhedron.Faces[3] << 4, 8, 3, 8, 9, 6;
431
432 polyhedron.Faces[4].resize(2, 3);
433 polyhedron.Faces[4] << 7, 6, 0, 10, 11, 12;
434
435 polyhedron.Faces[5].resize(2, 3);
436 polyhedron.Faces[5] << 6, 9, 0, 13, 14, 11;
437
438 polyhedron.Faces[6].resize(2, 3);
439 polyhedron.Faces[6] << 11, 10, 4, 15, 18, 19;
440
441 polyhedron.Faces[7].resize(2, 3);
442 polyhedron.Faces[7] << 10, 11, 6, 15, 16, 17;
443
444 polyhedron.Faces[8].resize(2, 3);
445 polyhedron.Faces[8] << 9, 5, 2, 20, 21, 22;
446
447 polyhedron.Faces[9].resize(2, 3);
448 polyhedron.Faces[9] << 5, 9, 11, 20, 23, 24;
449
450 polyhedron.Faces[10].resize(2, 3);
451 polyhedron.Faces[10] << 8, 7, 1, 25, 26, 27;
452
453 polyhedron.Faces[11].resize(2, 3);
454 polyhedron.Faces[11] << 7, 8, 10, 25, 28, 29;
455
456 polyhedron.Faces[12].resize(2, 3);
457 polyhedron.Faces[12] << 2, 5, 3, 21, 7, 3;
458
459 polyhedron.Faces[13].resize(2, 3);
460 polyhedron.Faces[13] << 8, 1, 3, 27, 4, 9;
461
462 polyhedron.Faces[14].resize(2, 3);
463 polyhedron.Faces[14] << 9, 2, 0, 22, 2, 14;
464
465 polyhedron.Faces[15].resize(2, 3);
466 polyhedron.Faces[15] << 1, 7, 0, 26, 12, 1;
467
468 polyhedron.Faces[16].resize(2, 3);
469 polyhedron.Faces[16] << 11, 9, 6, 23, 13, 16;
470
471 polyhedron.Faces[17].resize(2, 3);
472 polyhedron.Faces[17] << 7, 10, 6, 29, 17, 10;
473
474 polyhedron.Faces[18].resize(2, 3);
475 polyhedron.Faces[18] << 5, 11, 4, 24, 19, 5;
476
477 polyhedron.Faces[19].resize(2, 3);
478 polyhedron.Faces[19] << 10, 8, 4, 28, 8, 18;
479
481
482 return polyhedron;
483 }
484
492};
493
494} // namespace Gedim
495
496#endif // __PlatonicSolid_H
Eigen column vector.
Definition Eigen_Array.hpp:23
The GeometryUtilities class intersects 3D segments.
Definition GeometryUtilities.hpp:37
Definition IMeshDAO.hpp:1068
MeshUtilities.
Definition MeshUtilities.hpp:23
static void Assert(const bool &logicResult)
Assert for all code, generate exception if something goes wrong.
Definition IOUtilities.hpp:126
MeshUtilities.
Definition PlatonicSolid.hpp:27
GeometryUtilities::Polyhedron geodesic_polyhedron(const unsigned int &p, const unsigned int &q, const unsigned int &b, const unsigned int &c) const
Definition PlatonicSolid.hpp:195
GeometryUtilities::Polyhedron hexahedron() const
Definition PlatonicSolid.hpp:297
void second_class_geodesic_polyhedron(const Gedim::GeometryUtilities::Polyhedron &starting_polyhedron, const unsigned int &frequency, Gedim::MeshMatricesDAO &filter_mesh) const
Definition PlatonicSolid.cpp:467
GeometryUtilities::Polyhedron tetrahedron() const
Definition PlatonicSolid.hpp:254
void project_to_unit_sphere_goldberg(Gedim::MeshMatrices &mesh_data, Gedim::MeshMatricesDAO &mesh) const
Definition PlatonicSolid.hpp:88
PlatonicSolid(const Gedim::GeometryUtilities &geometryUtilities, const Gedim::MeshUtilities &meshUtilities)
Definition PlatonicSolid.hpp:32
Gedim::GeometryUtilities::Polyhedron icosahedron() const
Definition PlatonicSolid.hpp:362
Gedim::GeometryUtilities::Polyhedron octahedron() const
Definition PlatonicSolid.hpp:354
virtual ~PlatonicSolid()
Definition PlatonicSolid.hpp:37
Gedim::GeometryUtilities::Polyhedron goldberg_polyhedron(const unsigned int &p, const unsigned int &q, const unsigned int &b, const unsigned int &c) const
Definition PlatonicSolid.hpp:162
Gedim::GeometryUtilities::Polyhedron dual_polyhedron(const Gedim::GeometryUtilities::Polyhedron &polyhedron) const
MeshUtilities.
Definition PlatonicSolid.cpp:26
Gedim::GeometryUtilities::Polyhedron dodecahedron() const
Definition PlatonicSolid.hpp:485
void project_to_unit_sphere_geodesic(Gedim::MeshMatrices &mesh_data, Gedim::MeshMatricesDAO &mesh) const
Definition PlatonicSolid.hpp:44
void project_to_unit_sphere(Gedim::GeometryUtilities::Polyhedron &polyhedron) const
Definition PlatonicSolid.hpp:39
void first_class_geodesic_polyhedron(const Gedim::GeometryUtilities::Polyhedron &starting_polyhedron, const unsigned int &frequency, Gedim::MeshMatricesDAO &filter_mesh) const
Definition PlatonicSolid.cpp:104
Definition Eigen_Array.cpp:22
Definition GeometryUtilities.hpp:677
Definition MeshMatrices.hpp:21
std::vector< double > Cell0DCoordinates
Cell0D coordinates, size 3 x NumberCell0D (x,y,z)
Definition MeshMatrices.hpp:24